From 04ee84fc20760dd2189dfa45fc1f01e4b21ea8a9 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 11 Feb 2023 17:18:45 +0100 Subject: [PATCH 01/98] update version --- docs/_pages/releases.md | 6 ++++-- docs/index.html | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/_pages/releases.md b/docs/_pages/releases.md index faca38477d..3228d54f07 100644 --- a/docs/_pages/releases.md +++ b/docs/_pages/releases.md @@ -12,10 +12,12 @@ sidebar: ### What's new ### Fixes -* Fixed hanging of `CompleteWithinAsync` when used with `WithResult` and `AssertionScope` - [#2101](https://github.com/fluentassertions/fluentassertions/pull/2101) -* `BeEquivalentTo` no longer crashes on fields hiding base-class fields - [#1990](https://github.com/fluentassertions/fluentassertions/pull/1990) +## 6.10.0 +### Fixes +* Fixed hanging of `CompleteWithinAsync` when used with `WithResult` and `AssertionScope` - [#2101](https://github.com/fluentassertions/fluentassertions/pull/2101) +* `BeEquivalentTo` no longer crashes on fields hiding base-class fields - [#1990](https://github.com/fluentassertions/fluentassertions/pull/1990) * Fixed System.Net.Http dependency declaration for net47 target framework to be a framework dependency instead of a nuget dependency - [#2122](https://github.com/fluentassertions/fluentassertions/pull/2122) ## 6.9.0 diff --git a/docs/index.html b/docs/index.html index 1c4e81bd6d..8c6b5121c7 100644 --- a/docs/index.html +++ b/docs/index.html @@ -6,8 +6,8 @@ overlay_color: "#373737" overlay_filter: "0.7" overlay_image: "/assets/images/fluent_assertions_large_horizontal.svg" - cta_label: "Hello 2023! Here's Fluent Assertions 6.9!" - cta_url: "https://fluentassertions.com/releases/#680" + cta_label: "Fluent Assertions 6.10 is out!" + cta_url: "https://fluentassertions.com/releases/#6100" caption: "Logo by [**IUserName**](https://github.com/IUsername) and icons by [**Zlatko Najdenovski**](https://www.flaticon.com/authors/zlatko-najdenovski) from [Flaticon](https://www.flaticon.com/) " excerpt: '_"There''s a life before Fluent Assertions, and there''s a life after it"_ - [Meisam Alifallahi](https://www.linkedin.com/in/meisam-alifallahi/) From 55023d5596805ba55565c01a43e82f1f008503ca Mon Sep 17 00:00:00 2001 From: IT-VBFK <49762557+IT-VBFK@users.noreply.github.com> Date: Tue, 14 Feb 2023 07:25:17 +0100 Subject: [PATCH 02/98] Add optional build parameter to generate a `binlog` file (#2127) --- .gitignore | 1 + .nuke/build.schema.json | 4 ++++ Build/Build.cs | 7 +++++++ 3 files changed, 12 insertions(+) diff --git a/.gitignore b/.gitignore index b75671262e..ee534ee6da 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ packages/** *.tmp *.tmp_proj *.log +*.binlog *.vspscc *.vssscc .builds diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json index 04602534eb..dc9c2e1388 100644 --- a/.nuke/build.schema.json +++ b/.nuke/build.schema.json @@ -10,6 +10,10 @@ "type": "boolean", "description": "Indicates to continue a previously failed build attempt" }, + "GenerateBinLog": { + "type": "boolean", + "description": "Use this parameter if you encounter build problems in any way, to generate a .binlog file which holds some useful information" + }, "Help": { "type": "boolean", "description": "Shows the help text for this build assembly" diff --git a/Build/Build.cs b/Build/Build.cs index 7d2b7631e5..809bde6c05 100644 --- a/Build/Build.cs +++ b/Build/Build.cs @@ -41,6 +41,10 @@ class Build : NukeBuild string BuildNumber => GitHubActions?.RunNumber.ToString(); string PullRequestBase => GitHubActions?.BaseRef; + [Parameter("Use this parameter if you encounter build problems in any way, " + + "to generate a .binlog file which holds some useful information.")] + readonly bool? GenerateBinLog; + [Parameter("The key to push to Nuget")] [Secret] readonly string NuGetApiKey; @@ -124,6 +128,9 @@ class Build : NukeBuild DotNetBuild(s => s .SetProjectFile(Solution) .SetConfiguration(Configuration.CI) + .When(GenerateBinLog is true, _ => _ + .SetBinaryLog(ArtifactsDirectory / $"{Solution.Core.FluentAssertions.Name}.binlog") + ) .EnableNoLogo() .EnableNoRestore() .SetAssemblyVersion(GitVersion.AssemblySemVer) From 66c33216d25bf999b78d862281c88028a6318e9e Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Fri, 17 Feb 2023 18:46:09 +0000 Subject: [PATCH 03/98] Dynamic copyright year (#2128) Remove the need to ever update the copyright year again by having MSBuild dynamically insert the current year. --- Src/FluentAssertions/FluentAssertions.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/FluentAssertions/FluentAssertions.csproj b/Src/FluentAssertions/FluentAssertions.csproj index ee4c7c1654..817254eadd 100644 --- a/Src/FluentAssertions/FluentAssertions.csproj +++ b/Src/FluentAssertions/FluentAssertions.csproj @@ -28,7 +28,7 @@ Apache-2.0 FluentAssertions.png See https://fluentassertions.com/releases/ - Copyright Dennis Doomen 2010-2023 + Copyright Dennis Doomen 2010-$([System.DateTime]::Now.ToString(yyyy)) false From d2088e592beef7f27bde4004cd90d85dbc891eb4 Mon Sep 17 00:00:00 2001 From: Dennis Doomen Date: Sat, 4 Feb 2023 14:06:32 +0100 Subject: [PATCH 04/98] Tweaked the editorconfig and Rider/R# auto-cleanup profile --- .editorconfig | 32 +++++++++++++-- FluentAssertions.sln.DotSettings | 69 +++++++++++++++++++++----------- Tests/.editorconfig | 5 ++- 3 files changed, 78 insertions(+), 28 deletions(-) diff --git a/.editorconfig b/.editorconfig index 07ba3633da..1dfa065e14 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,7 +1,7 @@ +root = true # EditorConfig is awesome: http://EditorConfig.org # top-most EditorConfig file -root = true # Global settings [*] @@ -266,12 +266,38 @@ dotnet_diagnostic.AV2305.severity = none # AV2407: Region should be removed dotnet_diagnostic.AV2407.severity = none -# ReSharper/Rider # Convert lambda expression to method group resharper_convert_closure_to_method_group_highlighting = none +# Start each element in a object or collection initializer on a new line resharper_wrap_object_and_collection_initializer_style = chop_always +# Force an empty line resharper_blank_lines_after_multiline_statements = 1 -resharper_keep_existing_initializer_arrangement = false \ No newline at end of file +# Don't remove existing line breaks +resharper_keep_existing_initializer_arrangement = true +resharper_keep_existing_arrangement = true + +# We care about that extra else after an else-if +resharper_redundant_if_else_block_highlighting = none + +# Don't remove explicit default cases in switch statements +resharper_redundant_empty_switch_section_highlighting = none + +resharper_align_multiline_binary_expressions_chain = false + +# Only use new() when the type is obvious +resharper_object_creation_when_type_not_evident = explicitly_typed +resharper_object_creation_when_type_evident = target_typed + +# Indent 4 spaces per necessary indention +resharper_continuous_indent_multiplier = 1 + +# Avoid breaking a generic definition +resharper_wrap_before_extends_colon = true + +resharper_blank_lines_before_multiline_statements = 1 + +resharper_parentheses_non_obvious_operations = arithmetic, multiplicative, equality, relational, additive +resharper_parentheses_redundancy_style = remove_if_not_clarifies_precedence diff --git a/FluentAssertions.sln.DotSettings b/FluentAssertions.sln.DotSettings index 2db6662b1c..c52d714bf8 100644 --- a/FluentAssertions.sln.DotSettings +++ b/FluentAssertions.sln.DotSettings @@ -6,62 +6,80 @@ True HINT DO_NOT_SHOW - <?xml version="1.0" encoding="utf-16"?><Profile name="Safe Cleanup"><CSArrangeThisQualifier>True</CSArrangeThisQualifier><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReformatCode>True</CSReformatCode><CSCodeStyleAttributes ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" RemoveRedundantParentheses="True" AddMissingParentheses="True" ArrangeBraces="True" ArrangeAttributes="True" ArrangeObjectCreation="True" ArrangeDefaultValue="True" ArrangeNamespaces="True" /><CSMakeAutoPropertyGetOnly>True</CSMakeAutoPropertyGetOnly><CSArrangeQualifiers>True</CSArrangeQualifiers><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><IDEA_SETTINGS>&lt;profile version="1.0"&gt; + <?xml version="1.0" encoding="utf-16"?><Profile name="Safe Cleanup"><CSArrangeThisQualifier>True</CSArrangeThisQualifier><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReformatCode>True</CSReformatCode><CSCodeStyleAttributes ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" AddMissingParentheses="True" ArrangeBraces="True" ArrangeAttributes="True" ArrangeObjectCreation="True" ArrangeDefaultValue="True" ArrangeNamespaces="True" RemoveRedundantParentheses="True" /><CSMakeAutoPropertyGetOnly>True</CSMakeAutoPropertyGetOnly><CSArrangeQualifiers>True</CSArrangeQualifiers><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><IDEA_SETTINGS>&lt;profile version="1.0"&gt; &lt;option name="myName" value="Safe Cleanup" /&gt; + &lt;inspection_tool class="ES6ShorthandObjectProperty" enabled="false" level="WARNING" enabled_by_default="false" /&gt; + &lt;inspection_tool class="JSArrowFunctionBracesCanBeRemoved" enabled="false" level="WARNING" enabled_by_default="false" /&gt; + &lt;inspection_tool class="JSPrimitiveTypeWrapperUsage" enabled="false" level="WARNING" enabled_by_default="false" /&gt; + &lt;inspection_tool class="JSRemoveUnnecessaryParentheses" enabled="false" level="WARNING" enabled_by_default="false" /&gt; + &lt;inspection_tool class="JSUnnecessarySemicolon" enabled="false" level="WARNING" enabled_by_default="false" /&gt; + &lt;inspection_tool class="TypeScriptExplicitMemberType" enabled="false" level="WARNING" enabled_by_default="false" /&gt; + &lt;inspection_tool class="UnnecessaryContinueJS" enabled="false" level="WARNING" enabled_by_default="false" /&gt; + &lt;inspection_tool class="UnnecessaryLabelJS" enabled="false" level="WARNING" enabled_by_default="false" /&gt; + &lt;inspection_tool class="UnnecessaryLabelOnBreakStatementJS" enabled="false" level="WARNING" enabled_by_default="false" /&gt; + &lt;inspection_tool class="UnnecessaryLabelOnContinueStatementJS" enabled="false" level="WARNING" enabled_by_default="false" /&gt; + &lt;inspection_tool class="UnnecessaryReturnJS" enabled="false" level="WARNING" enabled_by_default="false" /&gt; + &lt;inspection_tool class="WrongPropertyKeyValueDelimiter" enabled="false" level="WEAK WARNING" enabled_by_default="false" /&gt; &lt;/profile&gt;</IDEA_SETTINGS><RIDER_SETTINGS>&lt;profile&gt; &lt;Language id="CSS"&gt; - &lt;Reformat&gt;true&lt;/Reformat&gt; - &lt;Rearrange&gt;true&lt;/Rearrange&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; + &lt;Rearrange&gt;false&lt;/Rearrange&gt; &lt;/Language&gt; &lt;Language id="EditorConfig"&gt; - &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; &lt;/Language&gt; &lt;Language id="HTML"&gt; - &lt;OptimizeImports&gt;true&lt;/OptimizeImports&gt; - &lt;Reformat&gt;true&lt;/Reformat&gt; - &lt;Rearrange&gt;true&lt;/Rearrange&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; + &lt;Rearrange&gt;false&lt;/Rearrange&gt; + &lt;OptimizeImports&gt;false&lt;/OptimizeImports&gt; &lt;/Language&gt; &lt;Language id="HTTP Request"&gt; - &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; &lt;/Language&gt; &lt;Language id="Handlebars"&gt; - &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; &lt;/Language&gt; &lt;Language id="Ini"&gt; - &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; &lt;/Language&gt; &lt;Language id="JSON"&gt; - &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; &lt;/Language&gt; &lt;Language id="Jade"&gt; - &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; &lt;/Language&gt; &lt;Language id="JavaScript"&gt; - &lt;OptimizeImports&gt;true&lt;/OptimizeImports&gt; - &lt;Reformat&gt;true&lt;/Reformat&gt; - &lt;Rearrange&gt;true&lt;/Rearrange&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; + &lt;Rearrange&gt;false&lt;/Rearrange&gt; + &lt;OptimizeImports&gt;false&lt;/OptimizeImports&gt; &lt;/Language&gt; &lt;Language id="Markdown"&gt; - &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="PowerShell"&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; &lt;/Language&gt; &lt;Language id="Properties"&gt; - &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; &lt;/Language&gt; &lt;Language id="RELAX-NG"&gt; - &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; &lt;/Language&gt; &lt;Language id="SQL"&gt; - &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="VueExpr"&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; &lt;/Language&gt; &lt;Language id="XML"&gt; - &lt;OptimizeImports&gt;true&lt;/OptimizeImports&gt; - &lt;Reformat&gt;true&lt;/Reformat&gt; - &lt;Rearrange&gt;true&lt;/Rearrange&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; + &lt;Rearrange&gt;false&lt;/Rearrange&gt; + &lt;OptimizeImports&gt;false&lt;/OptimizeImports&gt; &lt;/Language&gt; &lt;Language id="yaml"&gt; - &lt;Reformat&gt;true&lt;/Reformat&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; &lt;/Language&gt; -&lt;/profile&gt;</RIDER_SETTINGS></Profile> +&lt;/profile&gt;</RIDER_SETTINGS><XAMLCollapseEmptyTags>False</XAMLCollapseEmptyTags></Profile> Safe Cleanup Required Required @@ -77,6 +95,9 @@ True False 130 + False + 1 + 130 False UseExplicitType UseVarWhenEvident diff --git a/Tests/.editorconfig b/Tests/.editorconfig index cf27b53ce5..7fc6546234 100644 --- a/Tests/.editorconfig +++ b/Tests/.editorconfig @@ -146,4 +146,7 @@ dotnet_diagnostic.SA1615.severity = none dotnet_diagnostic.SA1005.severity = suggestion # ReSharper/Rider -resharper_expression_is_always_null_highlighting=none +resharper_expression_is_always_null_highlighting = none + +# ReSharper properties +resharper_keep_user_linebreaks = true From 454f16b54a88e2ebb5debbf7e40fab2937dfc147 Mon Sep 17 00:00:00 2001 From: Dennis Date: Tue, 7 Feb 2023 11:35:24 +0100 Subject: [PATCH 05/98] Auto-formatted all code with some manual corrections --- .../AggregateExceptionExtractor.cs | 2 +- Src/FluentAssertions/AndWhichConstraint.cs | 3 +- Src/FluentAssertions/AssertionExtensions.cs | 27 +- Src/FluentAssertions/AssertionOptions.cs | 2 +- .../CallerStatementBuilder.cs | 12 +- .../MultiLineCommentParsingStrategy.cs | 2 + .../QuotesParsingStrategy.cs | 1 + .../SingleLineCommentParsingStrategy.cs | 1 + Src/FluentAssertions/CallerIdentifier.cs | 17 +- .../GenericCollectionAssertions.cs | 339 +++++++++++------ .../GenericDictionaryAssertions.cs | 117 ++++-- .../MaximumMatching/MaximumMatchingSolver.cs | 8 +- .../Collections/StringCollectionAssertions.cs | 46 ++- .../SubsequentOrderingAssertions.cs | 28 +- Src/FluentAssertions/Common/Configuration.cs | 2 + .../Common/DictionaryHelpers.cs | 1 + .../Common/EnumerableExtensions.cs | 8 +- .../Common/ExceptionExtensions.cs | 1 + .../Common/ExpressionExtensions.cs | 8 +- .../Common/FullFrameworkReflector.cs | 16 +- Src/FluentAssertions/Common/Guard.cs | 16 +- .../Common/ICollectionWrapper.cs | 21 +- .../Common/IntegerExtensions.cs | 2 +- Src/FluentAssertions/Common/MemberPath.cs | 10 +- .../MemberPathSegmentEqualityComparer.cs | 9 +- .../Common/MethodInfoExtensions.cs | 5 +- .../Common/ObjectExtensions.cs | 8 +- .../ReadOnlyNonGenericCollectionWrapper.cs | 18 +- .../Common/StringExtensions.cs | 10 +- .../Common/TimeOnlyExtensions.cs | 1 - Src/FluentAssertions/Common/TypeExtensions.cs | 76 ++-- .../CustomAssertionAttribute.cs | 2 +- .../Data/DataColumnAssertions.cs | 23 +- .../Data/DataEquivalencyAssertionOptions.cs | 37 +- .../Data/DataRowAssertions.cs | 34 +- .../Data/DataSetAssertions.cs | 35 +- .../Data/DataTableAssertions.cs | 41 +- .../Data/IDataEquivalencyAssertionOptions.cs | 1 - ...DataColumnCollectionAssertionExtensions.cs | 7 +- .../DataRowAssertionExtensions.cs | 2 - .../DataRowCollectionAssertionExtensions.cs | 8 +- .../DataSetAssertionExtensions.cs | 2 - .../DataTableAssertionExtensions.cs | 2 - .../DataTableCollectionAssertionExtensions.cs | 5 +- .../Equivalency/Comparands.cs | 3 +- .../EquivalencyAssertionOptions.cs | 7 +- .../Equivalency/EquivalencyStep.cs | 6 +- .../Equivalency/EquivalencyValidator.cs | 3 + ...llectionMemberAssertionOptionsDecorator.cs | 3 +- .../Execution/CyclicReferenceDetector.cs | 2 +- .../Equivalency/Execution/ObjectReference.cs | 4 +- .../IEquivalencyAssertionOptions.cs | 1 - .../IEquivalencyValidationContext.cs | 1 - Src/FluentAssertions/Equivalency/IMember.cs | 1 - .../Matching/MappedMemberMatchingRule.cs | 3 +- .../Matching/MappedPathMatchingRule.cs | 6 +- .../Matching/MustMatchByNameRule.cs | 6 +- .../Matching/TryMatchByNameRule.cs | 5 +- .../Equivalency/MemberFactory.cs | 5 +- .../MultiDimensionalArrayEquivalencyStep.cs | 5 +- Src/FluentAssertions/Equivalency/Node.cs | 2 +- .../Ordering/ByteArrayOrderingRule.cs | 4 +- .../Ordering/PathBasedOrderingRule.cs | 2 + Src/FluentAssertions/Equivalency/Property.cs | 6 +- .../ExcludeNonBrowsableMembersRule.cs | 6 +- .../IncludeMemberByPathSelectionRule.cs | 4 +- .../IncludeMemberByPredicateSelectionRule.cs | 4 +- .../SelectMemberByPathSelectionRule.cs | 3 +- ...elfReferenceEquivalencyAssertionOptions.cs | 4 +- .../Equivalency/Steps/AssertionContext.cs | 4 +- .../Steps/AssertionRuleEquivalencyStep.cs | 9 +- .../Equivalency/Steps/AutoConversionStep.cs | 12 +- .../ConstraintCollectionEquivalencyStep.cs | 11 +- .../Steps/ConstraintEquivalencyStep.cs | 15 +- .../Steps/DataColumnEquivalencyStep.cs | 12 +- .../Steps/DataRelationEquivalencyStep.cs | 8 +- .../Steps/DataRowCollectionEquivalencyStep.cs | 30 +- .../Steps/DataRowEquivalencyStep.cs | 37 +- .../Steps/DataSetEquivalencyStep.cs | 68 ++-- .../Steps/DataTableEquivalencyStep.cs | 48 ++- .../Steps/DictionaryEquivalencyStep.cs | 22 +- .../Steps/DictionaryInterfaceInfo.cs | 1 + .../Equivalency/Steps/EnumEqualityStep.cs | 13 +- .../Steps/EnumerableEquivalencyStep.cs | 7 +- .../Steps/EnumerableEquivalencyValidator.cs | 31 +- ...numerableEquivalencyValidatorExtensions.cs | 13 +- .../Steps/EqualityComparerEquivalencyStep.cs | 3 +- .../Steps/GenericDictionaryEquivalencyStep.cs | 5 +- .../Steps/GenericEnumerableEquivalencyStep.cs | 15 +- .../Steps/ReferenceEqualityEquivalencyStep.cs | 7 +- .../Steps/RunAllUserStepsEquivalencyStep.cs | 3 +- .../Steps/SimpleEqualityEquivalencyStep.cs | 3 +- .../Steps/StringEqualityEquivalencyStep.cs | 6 +- .../StructuralEqualityEquivalencyStep.cs | 20 +- .../Steps/ValueTypeEquivalencyStep.cs | 9 +- .../Steps/XAttributeEquivalencyStep.cs | 3 +- .../Steps/XDocumentEquivalencyStep.cs | 3 +- .../Steps/XElementEquivalencyStep.cs | 3 +- .../Equivalency/Tracing/Tracer.cs | 2 +- Src/FluentAssertions/EquivalencyPlan.cs | 4 +- .../EventRaisingExtensions.cs | 7 +- .../Events/EventAssertions.cs | 7 +- Src/FluentAssertions/Events/EventMonitor.cs | 2 + Src/FluentAssertions/Events/EventRecorder.cs | 3 +- .../Execution/AssertionFailedException.cs | 2 - .../Execution/AssertionScope.cs | 36 +- .../Execution/CollectingAssertionStrategy.cs | 1 - .../Execution/ContextDataItems.cs | 3 +- .../Execution/ContinuationOfGiven.cs | 5 +- .../Execution/DefaultAssertionStrategy.cs | 1 - .../Execution/GivenSelectorExtensions.cs | 22 +- .../Execution/LateBoundTestFramework.cs | 1 + .../Execution/MessageBuilder.cs | 9 +- .../Execution/NSpecFramework.cs | 1 + .../Execution/TestFrameworkProvider.cs | 7 +- .../Execution/XUnit2TestFramework.cs | 1 + .../Extensions/FluentDateTimeExtensions.cs | 6 +- .../AggregateExceptionValueFormatter.cs | 1 + .../Formatting/AttributeBasedFormatter.cs | 16 +- .../Formatting/DateOnlyValueFormatter.cs | 1 - .../DateTimeOffsetValueFormatter.cs | 10 +- .../Formatting/DefaultValueFormatter.cs | 4 +- .../Formatting/DictionaryValueFormatter.cs | 2 + .../Formatting/EnumValueFormatter.cs | 1 + .../Formatting/EnumerableExtensions.cs | 2 +- .../Formatting/EnumerableValueFormatter.cs | 1 + .../Formatting/FormattedObjectGraph.cs | 4 +- Src/FluentAssertions/Formatting/Formatter.cs | 5 +- .../Formatting/FormattingOptions.cs | 2 +- .../MultidimensionalArrayFormatter.cs | 4 +- ...PredicateLambdaExpressionValueFormatter.cs | 2 +- .../Formatting/TimeOnlyValueFormatter.cs | 1 - .../Formatting/TimeSpanValueFormatter.cs | 5 +- .../Formatting/ValueFormatterAttribute.cs | 2 +- .../Numeric/ComparableTypeAssertions.cs | 10 +- .../Numeric/DecimalAssertions.cs | 2 +- .../Numeric/NullableDecimalAssertions.cs | 2 +- .../Numeric/NumericAssertions.cs | 37 +- .../NumericAssertionsExtensions.cs | 188 +++++++--- .../ObjectAssertionsExtensions.cs | 6 +- .../Primitives/BooleanAssertions.cs | 2 +- .../Primitives/DateOnlyAssertions.cs | 7 +- .../Primitives/DateTimeAssertions.cs | 14 +- .../Primitives/DateTimeOffsetAssertions.cs | 37 +- .../DateTimeOffsetRangeAssertions.cs | 9 +- .../Primitives/DateTimeRangeAssertions.cs | 9 +- .../Primitives/EnumAssertions.cs | 19 +- .../HttpResponseMessageAssertions.cs | 3 +- .../Primitives/NegatedStringStartValidator.cs | 1 + .../Primitives/NullableDateOnlyAssertions.cs | 1 - .../Primitives/NullableTimeOnlyAssertions.cs | 1 - .../Primitives/ObjectAssertions.cs | 1 + .../Primitives/ReferenceTypeAssertions.cs | 6 +- .../Primitives/SimpleTimeSpanAssertions.cs | 8 +- .../Primitives/StringAssertions.cs | 85 +++-- .../Primitives/StringEqualityValidator.cs | 7 +- .../Primitives/StringStartValidator.cs | 1 + .../Primitives/StringValidator.cs | 6 +- .../StringWildcardMatchingValidator.cs | 9 +- .../Primitives/TimeOnlyAssertions.cs | 9 +- .../Primitives/TimeSpanPredicate.cs | 5 +- .../Specialized/AssemblyAssertions.cs | 15 +- .../Specialized/AsyncFunctionAssertions.cs | 11 +- .../Specialized/DelegateAssertions.cs | 11 +- .../Specialized/DelegateAssertionsBase.cs | 4 +- .../Specialized/ExceptionAssertions.cs | 8 +- .../Specialized/ExecutionTime.cs | 2 + .../Specialized/ExecutionTimeAssertions.cs | 46 ++- .../Specialized/FunctionAssertionHelpers.cs | 9 +- .../Specialized/FunctionAssertions.cs | 10 +- .../GenericAsyncFunctionAssertions.cs | 12 +- .../TaskCompletionSourceAssertions.cs | 4 +- .../Types/MethodBaseAssertions.cs | 3 +- .../Types/MethodInfoAssertions.cs | 38 +- .../Types/MethodInfoSelector.cs | 15 +- .../Types/MethodInfoSelectorAssertions.cs | 20 +- .../Types/PropertyInfoAssertions.cs | 85 ++--- .../Types/PropertyInfoSelector.cs | 2 +- .../Types/PropertyInfoSelectorAssertions.cs | 6 +- Src/FluentAssertions/Types/TypeAssertions.cs | 14 +- Src/FluentAssertions/Types/TypeSelector.cs | 5 +- .../Types/TypeSelectorAssertions.cs | 35 +- Src/FluentAssertions/Xml/Equivalency/Node.cs | 5 +- .../Xml/Equivalency/XmlIterator.cs | 1 + .../Xml/Equivalency/XmlReaderValidator.cs | 7 +- .../Xml/XDocumentAssertions.cs | 18 +- .../Xml/XElementAssertions.cs | 2 +- .../FluentAssertions/net47.verified.txt | 4 +- .../FluentAssertions/net6.0.verified.txt | 4 +- .../netcoreapp2.1.verified.txt | 4 +- .../netcoreapp3.0.verified.txt | 4 +- .../netstandard2.0.verified.txt | 4 +- .../netstandard2.1.verified.txt | 4 +- Tests/Benchmarks/CheckIfMemberIsBrowsable.cs | 2 +- Tests/Benchmarks/LargeDataTableEquivalency.cs | 9 +- Tests/Benchmarks/LargeObjectGraph.cs | 6 +- Tests/Benchmarks/Program.cs | 8 +- .../UsersOfGetClosedGenericInterfaces.cs | 45 ++- .../BasicSpecs.cs | 2 +- .../CollectionSpecs.cs | 175 +++++---- .../CyclicReferencesSpecs.cs | 163 ++++++-- .../DataColumnSpecs.cs | 5 +- .../DataRelationSpecs.cs | 16 +- .../DataRowSpecs.cs | 38 +- .../DataSetSpecs.cs | 92 +++-- .../DataSpecs.cs | 60 +-- .../DataTableSpecs.cs | 145 +++++--- .../DictionarySpecs.cs | 84 +++-- .../EnumSpecs.cs | 4 +- .../ExtensibilitySpecs.cs | 37 +- .../MemberConversionSpecs.cs | 2 +- .../MemberLessObjectsSpecs.cs | 4 +- .../SelectionRulesSpecs.cs | 38 +- .../TestTypes.cs | 19 +- .../TupleSpecs.cs | 4 +- .../TypedDataSetSpecs.cs | 15 +- .../TypedDataTableSpecs.cs | 20 +- .../XmlSpecs.cs | 5 +- .../AssertionExtensions.cs | 1 - .../AssertionExtensionsSpecs.cs | 5 +- .../AssertionOptionsSpecs.cs | 16 +- .../CollectionAssertionSpecs.AllSatisfy.cs | 8 +- .../CollectionAssertionSpecs.BeEmpty.cs | 2 +- ...CollectionAssertionSpecs.BeEquivalentTo.cs | 9 +- ...ectionAssertionSpecs.BeInAscendingOrder.cs | 78 ++-- ...ctionAssertionSpecs.BeInDescendingOrder.cs | 73 ++-- .../CollectionAssertionSpecs.BeSubsetOf.cs | 2 +- .../CollectionAssertionSpecs.Contain.cs | 6 +- ...ctionAssertionSpecs.ContainEquivalentOf.cs | 31 +- ...ssertionSpecs.ContainInConsecutiveOrder.cs | 14 +- ...CollectionAssertionSpecs.ContainInOrder.cs | 11 +- ...AssertionSpecs.ContainItemsAssignableTo.cs | 15 +- .../CollectionAssertionSpecs.ContainSingle.cs | 13 +- .../CollectionAssertionSpecs.EndWith.cs | 18 +- .../CollectionAssertionSpecs.Equal.cs | 20 +- .../CollectionAssertionSpecs.HaveCount.cs | 13 +- ...tionAssertionSpecs.HaveCountGreaterThan.cs | 9 +- ...tionSpecs.HaveCountGreaterThanOrEqualTo.cs | 12 +- ...lectionAssertionSpecs.HaveCountLessThan.cs | 6 +- ...sertionSpecs.HaveCountLessThanOrEqualTo.cs | 12 +- .../CollectionAssertionSpecs.HaveSameCount.cs | 3 +- ...ctionAssertionSpecs.OnlyHaveUniqueItems.cs | 3 +- .../CollectionAssertionSpecs.Satisfy.cs | 32 +- ...ctionAssertionSpecs.SatisfyRespectively.cs | 28 +- .../CollectionAssertionSpecs.StartWith.cs | 18 +- .../Collections/CollectionAssertionSpecs.cs | 14 +- .../DataColumnCollectionAssertionSpecs.cs | 9 +- .../Data/DataRowCollectionAssertionSpecs.cs | 62 ++-- .../Data/DataTableCollectionAssertionSpecs.cs | 7 +- ...ectionAssertionOfStringSpecs.AllSatisfy.cs | 4 +- ...GenericCollectionAssertionOfStringSpecs.cs | 63 ++-- .../GenericDictionaryAssertionSpecs.cs | 350 +++++++++++------- .../Common/TimeSpanExtensions.cs | 2 + .../ConfigurationSpecs.cs | 4 +- .../CulturedFactAttributeDiscoverer.cs | 6 +- .../CulturedTheoryAttribute.cs | 3 +- .../CulturedTheoryAttributeDiscoverer.cs | 20 +- .../CulturedXunitTestCase.cs | 24 +- .../CulturedXunitTheoryTestCase.cs | 22 +- .../CulturedXunitTheoryTestCaseRunner.cs | 17 +- .../Events/EventAssertionSpecs.cs | 55 +-- .../AsyncFunctionExceptionAssertionSpecs.cs | 47 ++- .../Exceptions/ExceptionAssertionSpecs.cs | 17 +- .../FunctionExceptionAssertionSpecs.cs | 30 +- .../Exceptions/InnerExceptionSpecs.cs | 32 +- .../Exceptions/MiscellaneousExceptionSpecs.cs | 4 +- .../Exceptions/NotThrowSpecs.cs | 17 +- .../Exceptions/OuterExceptionSpecs.cs | 21 +- .../AssertionScope.ChainingApiSpecs.cs | 11 +- .../AssertionScope.ContextDataSpecs.cs | 6 +- .../AssertionScope.MessageFormatingSpecs.cs | 8 +- .../Execution/AssertionScopeSpecs.cs | 5 +- .../Execution/GivenSelectorSpecs.cs | 6 +- .../Execution/TestFrameworkProviderTests.cs | 4 + .../Extensions/FluentDateTimeSpecs.cs | 12 +- .../Extensions/ObjectExtensionsSpecs.cs | 26 +- .../DateTimeOffsetValueFormatterSpecs.cs | 8 +- .../Formatting/FormatterSpecs.cs | 52 +-- .../MultidimensionalArrayFormatterSpecs.cs | 16 +- ...cateLambdaExpressionValueFormatterSpecs.cs | 3 +- .../Formatting/TimeSpanFormatterSpecs.cs | 3 +- .../Numeric/ComparableSpecs.cs | 5 +- .../Numeric/NumericAssertionSpecs.cs | 3 +- .../NumericDifferenceAssertionsSpecs.cs | 111 ++++-- .../Primitives/BooleanAssertionSpecs.cs | 3 +- .../Primitives/DateOnlyAssertionSpecs.cs | 4 +- .../Primitives/DateTimeAssertionSpecs.cs | 243 ++++++------ .../DateTimeOffsetAssertionSpecs.cs | 307 ++++++++------- .../Primitives/EnumAssertionSpecs.cs | 12 +- .../Primitives/GuidAssertionSpecs.cs | 3 +- .../NullableBooleanAssertionSpecs.cs | 6 +- .../Primitives/NullableGuidAssertionSpecs.cs | 6 +- .../NullableSimpleTimeSpanAssertionSpecs.cs | 6 +- .../Primitives/ObjectAssertionSpecs.cs | 138 ++++--- .../ReferenceTypeAssertionsSpecs.cs | 44 ++- .../SimpleTimeSpanAssertionSpecs.cs | 27 +- .../Primitives/StringAssertionSpecs.Be.cs | 3 +- .../StringAssertionSpecs.BeEquivalentTo.cs | 6 +- .../StringAssertionSpecs.BeOneOf.cs | 3 +- .../StringAssertionSpecs.Contain.cs | 48 ++- .../StringAssertionSpecs.ContainAll.cs | 24 +- .../StringAssertionSpecs.ContainAny.cs | 24 +- ...tringAssertionSpecs.ContainEquivalentOf.cs | 75 ++-- .../StringAssertionSpecs.EndWith.cs | 4 +- ...tringAssertionSpecs.EndWithEquivalentOf.cs | 7 +- .../Primitives/StringAssertionSpecs.Match.cs | 9 +- .../StringAssertionSpecs.MatchEquivalentOf.cs | 14 +- .../StringAssertionSpecs.MatchRegex.cs | 52 +-- .../StringAssertionSpecs.StartWith.cs | 7 +- ...ingAssertionSpecs.StartWithEquivalentOf.cs | 14 +- .../Primitives/StringAssertionSpecs.cs | 3 - .../Primitives/StringComparisonSpecs.cs | 8 +- .../Primitives/TimeOnlyAssertionSpecs.cs | 85 +++-- .../Specialized/AssemblyAssertionSpecs.cs | 7 +- .../ExecutionTimeAssertionsSpecs.cs | 9 +- .../Specialized/TaskAssertionSpecs.cs | 9 +- .../TaskCompletionSourceAssertionSpecs.cs | 11 +- .../Specialized/TaskOfTAssertionSpecs.cs | 13 +- .../Streams/StreamAssertionSpecs.cs | 3 +- .../TypeEnumerableExtensionsSpecs.cs | 23 +- .../Types/MethodBaseAssertionSpecs.cs | 65 ++-- .../Types/MethodInfoAssertionSpecs.cs | 99 +++-- .../Types/MethodInfoSelectorAssertionSpecs.cs | 85 +++-- .../Types/MethodInfoSelectorSpecs.cs | 35 +- .../Types/PropertyInfoAssertionSpecs.cs | 109 +++--- .../PropertyInfoSelectorAssertionSpecs.cs | 52 +-- .../Types/PropertyInfoSelectorSpecs.cs | 48 ++- .../Types/TypeAssertionSpecs.Be.cs | 11 +- .../TypeAssertionSpecs.BeAssignableTo.cs | 1 + .../TypeAssertionSpecs.BeDecoratedWith.cs | 10 +- ...AssertionSpecs.BeDecoratedWithOrInherit.cs | 10 +- .../TypeAssertionSpecs.HaveConstructor.cs | 7 +- ...peAssertionSpecs.HaveDefaultConstructor.cs | 16 +- ...ionSpecs.HaveExplicitConversionOperator.cs | 4 +- .../TypeAssertionSpecs.HaveExplicitMethod.cs | 6 +- ...TypeAssertionSpecs.HaveExplicitProperty.cs | 6 +- ...ionSpecs.HaveImplicitConversionOperator.cs | 4 +- .../Types/TypeAssertionSpecs.HaveIndexer.cs | 4 +- .../Types/TypeAssertionSpecs.HaveMethod.cs | 6 +- .../Types/TypeAssertionSpecs.HaveProperty.cs | 8 +- .../Types/TypeAssertionSpecs.cs | 80 ++-- .../Types/TypeExtensionsSpecs.cs | 50 ++- .../Types/TypeSelectorAssertionSpecs.cs | 19 +- .../Types/TypeSelectorSpecs.cs | 29 +- .../UIFactsDefinition.cs | 4 +- .../Xml/XAttributeAssertionSpecs.cs | 13 +- .../Xml/XAttributeFormatterSpecs.cs | 1 - .../Xml/XDocumentAssertionSpecs.cs | 102 +++-- .../Xml/XDocumentFormatterSpecs.cs | 1 - .../Xml/XElementAssertionSpecs.cs | 90 +++-- .../Xml/XElementFormatterSpecs.cs | 1 - .../Xml/XmlElementAssertionSpecs.cs | 35 +- .../Xml/XmlNodeAssertionSpecs.cs | 57 ++- .../Xml/XmlNodeFormatterSpecs.cs | 1 - 354 files changed, 4640 insertions(+), 2867 deletions(-) diff --git a/Src/FluentAssertions/AggregateExceptionExtractor.cs b/Src/FluentAssertions/AggregateExceptionExtractor.cs index 9777f6361c..b94e03e7fc 100644 --- a/Src/FluentAssertions/AggregateExceptionExtractor.cs +++ b/Src/FluentAssertions/AggregateExceptionExtractor.cs @@ -13,7 +13,7 @@ public IEnumerable OfType(Exception actualException) { if (typeof(T).IsSameOrInherits(typeof(AggregateException))) { - return (actualException is T exception) ? new[] { exception } : Enumerable.Empty(); + return actualException is T exception ? new[] { exception } : Enumerable.Empty(); } return GetExtractedExceptions(actualException); diff --git a/Src/FluentAssertions/AndWhichConstraint.cs b/Src/FluentAssertions/AndWhichConstraint.cs index 201e32c89d..a30126ba2f 100644 --- a/Src/FluentAssertions/AndWhichConstraint.cs +++ b/Src/FluentAssertions/AndWhichConstraint.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; - using FluentAssertions.Common; using FluentAssertions.Formatting; @@ -44,7 +43,7 @@ private static TMatchedElement SingleOrDefault( ele => "\t" + Formatter.ToString(ele))); string message = "More than one object found. FluentAssertions cannot determine which object is meant." - + $" Found objects:{Environment.NewLine}{foundObjects}"; + + $" Found objects:{Environment.NewLine}{foundObjects}"; Services.ThrowException(message); } diff --git a/Src/FluentAssertions/AssertionExtensions.cs b/Src/FluentAssertions/AssertionExtensions.cs index a4638c1cb1..d16c01d5d7 100644 --- a/Src/FluentAssertions/AssertionExtensions.cs +++ b/Src/FluentAssertions/AssertionExtensions.cs @@ -13,9 +13,6 @@ using FluentAssertions.Collections; using FluentAssertions.Common; using FluentAssertions.Data; -#if !NETSTANDARD2_0 -using FluentAssertions.Events; -#endif using FluentAssertions.Numeric; using FluentAssertions.Primitives; using FluentAssertions.Reflection; @@ -24,6 +21,9 @@ using FluentAssertions.Types; using FluentAssertions.Xml; using JetBrains.Annotations; +#if !NETSTANDARD2_0 +using FluentAssertions.Events; +#endif namespace FluentAssertions; @@ -140,7 +140,7 @@ public static ExecutionTime ExecutionTime(this Action action, StartTimer createT { createTimer ??= () => new StopwatchTimer(); - return new(action, createTimer); + return new ExecutionTime(action, createTimer); } /// @@ -154,7 +154,7 @@ public static ExecutionTime ExecutionTime(this Action action, StartTimer createT [MustUseReturnValue /* do not use Pure because this method executes the action before returning to the caller */] public static ExecutionTime ExecutionTime(this Func action) { - return new(action, () => new StopwatchTimer()); + return new ExecutionTime(action, () => new StopwatchTimer()); } /// @@ -359,7 +359,8 @@ public static StringCollectionAssertions Should(this IEnumerable @this) /// current . /// [Pure] - public static GenericDictionaryAssertions, TKey, TValue> Should(this IDictionary actualValue) + public static GenericDictionaryAssertions, TKey, TValue> Should( + this IDictionary actualValue) { return new GenericDictionaryAssertions, TKey, TValue>(actualValue); } @@ -369,7 +370,8 @@ public static GenericDictionaryAssertions, TKey, TValu /// current of . /// [Pure] - public static GenericDictionaryAssertions>, TKey, TValue> Should(this IEnumerable> actualValue) + public static GenericDictionaryAssertions>, TKey, TValue> Should( + this IEnumerable> actualValue) { return new GenericDictionaryAssertions>, TKey, TValue>(actualValue); } @@ -379,7 +381,8 @@ public static GenericDictionaryAssertions /// current . /// [Pure] - public static GenericDictionaryAssertions Should(this TCollection actualValue) + public static GenericDictionaryAssertions Should( + this TCollection actualValue) where TCollection : IEnumerable> { return new GenericDictionaryAssertions(actualValue); @@ -466,7 +469,6 @@ public static NullableDateTimeOffsetAssertions Should(this DateTimeOffset? actua } #if NET6_0_OR_GREATER - /// /// Returns an object that can be used to assert the /// current . @@ -921,7 +923,6 @@ public static IMonitor Monitor(this T eventSource, Func utcNow = #endif #if NET6_0_OR_GREATER - /// /// Returns a object that can be used to assert the /// current . @@ -981,8 +982,7 @@ public static void Should(this DateTimeOffsetAssertions [Obsolete("You are asserting the 'AndConstraint' itself. Remove the 'Should()' method directly following 'And'", error: true)] public static void Should(this DateOnlyAssertions _) @@ -1091,7 +1091,8 @@ public static void Should(this DateTimeOffsetRangeAssertions CloneDefaults() { - return new(defaults); + return new EquivalencyAssertionOptions(defaults); } internal static TOptions CloneDefaults(Func predicate) diff --git a/Src/FluentAssertions/CallerIdentification/CallerStatementBuilder.cs b/Src/FluentAssertions/CallerIdentification/CallerStatementBuilder.cs index 225b899e6c..af280faf83 100644 --- a/Src/FluentAssertions/CallerIdentification/CallerStatementBuilder.cs +++ b/Src/FluentAssertions/CallerIdentification/CallerStatementBuilder.cs @@ -13,6 +13,7 @@ internal class CallerStatementBuilder internal CallerStatementBuilder() { statement = new StringBuilder(); + priorityOrderedParsingStrategies = new List { new QuotesParsingStrategy(), @@ -28,19 +29,22 @@ internal CallerStatementBuilder() internal void Append(string symbols) { using var symbolEnumerator = symbols.GetEnumerator(); + while (symbolEnumerator.MoveNext() && parsingState != ParsingState.Done) { var hasParsingStrategyWaitingForEndContext = priorityOrderedParsingStrategies .Any(s => s.IsWaitingForContextEnd()); parsingState = ParsingState.InProgress; + foreach (var parsingStrategy in - priorityOrderedParsingStrategies - .SkipWhile(parsingStrategy => - hasParsingStrategyWaitingForEndContext - && !parsingStrategy.IsWaitingForContextEnd())) + priorityOrderedParsingStrategies + .SkipWhile(parsingStrategy => + hasParsingStrategyWaitingForEndContext + && !parsingStrategy.IsWaitingForContextEnd())) { parsingState = parsingStrategy.Parse(symbolEnumerator.Current, statement); + if (parsingState != ParsingState.InProgress) { break; diff --git a/Src/FluentAssertions/CallerIdentification/MultiLineCommentParsingStrategy.cs b/Src/FluentAssertions/CallerIdentification/MultiLineCommentParsingStrategy.cs index 6e22a04799..a614631307 100644 --- a/Src/FluentAssertions/CallerIdentification/MultiLineCommentParsingStrategy.cs +++ b/Src/FluentAssertions/CallerIdentification/MultiLineCommentParsingStrategy.cs @@ -12,6 +12,7 @@ public ParsingState Parse(char symbol, StringBuilder statement) if (isCommentContext) { var isEndOfMultilineComment = symbol is '/' && commentContextPreviousChar is '*'; + if (isEndOfMultilineComment) { isCommentContext = false; @@ -29,6 +30,7 @@ public ParsingState Parse(char symbol, StringBuilder statement) symbol is '*' && statement.Length > 0 && statement[^1] is '/'; + if (isStartOfMultilineComment) { statement.Remove(statement.Length - 1, 1); diff --git a/Src/FluentAssertions/CallerIdentification/QuotesParsingStrategy.cs b/Src/FluentAssertions/CallerIdentification/QuotesParsingStrategy.cs index 85991ead02..a988bb4c79 100644 --- a/Src/FluentAssertions/CallerIdentification/QuotesParsingStrategy.cs +++ b/Src/FluentAssertions/CallerIdentification/QuotesParsingStrategy.cs @@ -26,6 +26,7 @@ public ParsingState Parse(char symbol, StringBuilder statement) else { isQuoteContext = true; + if (IsVerbatim(statement)) { isQuoteEscapeSymbol = '"'; diff --git a/Src/FluentAssertions/CallerIdentification/SingleLineCommentParsingStrategy.cs b/Src/FluentAssertions/CallerIdentification/SingleLineCommentParsingStrategy.cs index 434e1c3b0e..9c8e86196f 100644 --- a/Src/FluentAssertions/CallerIdentification/SingleLineCommentParsingStrategy.cs +++ b/Src/FluentAssertions/CallerIdentification/SingleLineCommentParsingStrategy.cs @@ -14,6 +14,7 @@ public ParsingState Parse(char symbol, StringBuilder statement) } var doesSymbolStartComment = symbol is '/' && statement.Length > 0 && statement[^1] is '/'; + if (!doesSymbolStartComment) { return ParsingState.InProgress; diff --git a/Src/FluentAssertions/CallerIdentifier.cs b/Src/FluentAssertions/CallerIdentifier.cs index 91bceb00bc..5ef1a91728 100644 --- a/Src/FluentAssertions/CallerIdentifier.cs +++ b/Src/FluentAssertions/CallerIdentifier.cs @@ -87,13 +87,13 @@ public StackFrameReference() int firstUserCodeFrameIndex = 0; - while ((firstUserCodeFrameIndex < allStackFrames.Length) - && IsCurrentAssembly(allStackFrames[firstUserCodeFrameIndex])) + while (firstUserCodeFrameIndex < allStackFrames.Length + && IsCurrentAssembly(allStackFrames[firstUserCodeFrameIndex])) { firstUserCodeFrameIndex++; } - SkipStackFrameCount = allStackFrames.Length - firstUserCodeFrameIndex + 1; + SkipStackFrameCount = (allStackFrames.Length - firstUserCodeFrameIndex) + 1; previousReference = StartStackSearchAfterStackFrame.Value; StartStackSearchAfterStackFrame.Value = this; @@ -172,6 +172,7 @@ private static string ExtractVariableNameFrom(StackFrame frame) if (!string.IsNullOrEmpty(statement)) { Logger(statement); + if (!IsBooleanLiteral(statement) && !IsNumeric(statement) && !IsStringLiteral(statement) && !StartsWithNewKeyword(statement)) { @@ -187,7 +188,7 @@ private static string GetSourceCodeStatementFrom(StackFrame frame) string fileName = frame.GetFileName(); int expectedLineNumber = frame.GetFileLineNumber(); - if (string.IsNullOrEmpty(fileName) || (expectedLineNumber == 0)) + if (string.IsNullOrEmpty(fileName) || expectedLineNumber == 0) { return null; } @@ -204,9 +205,9 @@ private static string GetSourceCodeStatementFrom(StackFrame frame) } return currentLine == expectedLineNumber - && line != null - ? GetSourceCodeStatementFrom(frame, reader, line) - : null; + && line != null + ? GetSourceCodeStatementFrom(frame, reader, line) + : null; } catch { @@ -218,12 +219,14 @@ private static string GetSourceCodeStatementFrom(StackFrame frame) private static string GetSourceCodeStatementFrom(StackFrame frame, StreamReader reader, string line) { int column = frame.GetFileColumnNumber(); + if (column > 0) { line = line.Substring(Math.Min(column - 1, line.Length - 1)); } var sb = new CallerStatementBuilder(); + do { sb.Append(line); diff --git a/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs b/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs index 63d234c038..51c472e595 100644 --- a/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs +++ b/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs @@ -15,8 +15,7 @@ namespace FluentAssertions.Collections; [DebuggerNonUserCode] -public class GenericCollectionAssertions : - GenericCollectionAssertions, T, GenericCollectionAssertions> +public class GenericCollectionAssertions : GenericCollectionAssertions, T, GenericCollectionAssertions> { public GenericCollectionAssertions(IEnumerable actualValue) : base(actualValue) @@ -25,8 +24,8 @@ public GenericCollectionAssertions(IEnumerable actualValue) } [DebuggerNonUserCode] -public class GenericCollectionAssertions : - GenericCollectionAssertions> +public class GenericCollectionAssertions + : GenericCollectionAssertions> where TCollection : IEnumerable { public GenericCollectionAssertions(TCollection actualValue) @@ -38,13 +37,12 @@ public GenericCollectionAssertions(TCollection actualValue) #pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals [DebuggerNonUserCode] -public class GenericCollectionAssertions : - ReferenceTypeAssertions +public class GenericCollectionAssertions : ReferenceTypeAssertions where TCollection : IEnumerable where TAssertions : GenericCollectionAssertions { public GenericCollectionAssertions(TCollection actualValue) - : base(actualValue) + : base(actualValue) { } @@ -64,12 +62,14 @@ public GenericCollectionAssertions(TCollection actualValue) /// /// Zero or more objects to format using the placeholders in . /// - public AndWhichConstraint> AllBeAssignableTo(string because = "", params object[] becauseArgs) + public AndWhichConstraint> AllBeAssignableTo(string because = "", + params object[] becauseArgs) { bool success = Execute.Assertion .BecauseOf(because, becauseArgs) .ForCondition(Subject is not null) - .FailWith("Expected type to be {0}{reason}, but found {context:the collection} is .", typeof(TExpectation).FullName); + .FailWith("Expected type to be {0}{reason}, but found {context:the collection} is .", + typeof(TExpectation).FullName); IEnumerable matches = new TExpectation[0]; @@ -209,12 +209,14 @@ public AndConstraint AllBeEquivalentTo(TExpectation e /// /// Zero or more objects to format using the placeholders in . /// - public AndWhichConstraint> AllBeOfType(string because = "", params object[] becauseArgs) + public AndWhichConstraint> AllBeOfType(string because = "", + params object[] becauseArgs) { bool success = Execute.Assertion .BecauseOf(because, becauseArgs) .ForCondition(Subject is not null) - .FailWith("Expected type to be {0}{reason}, but found {context:collection} is .", typeof(TExpectation).FullName); + .FailWith("Expected type to be {0}{reason}, but found {context:collection} is .", + typeof(TExpectation).FullName); IEnumerable matches = new TExpectation[0]; @@ -355,13 +357,16 @@ public AndConstraint BeEquivalentTo(IEnumerable> options = config(AssertionOptions.CloneDefaults()).AsCollection(); + EquivalencyAssertionOptions> options = + config(AssertionOptions.CloneDefaults()).AsCollection(); - var context = new EquivalencyValidationContext(Node.From>(() => AssertionScope.Current.CallerIdentity), options) - { - Reason = new Reason(because, becauseArgs), - TraceWriter = options.TraceWriter, - }; + var context = + new EquivalencyValidationContext(Node.From>(() => AssertionScope.Current.CallerIdentity), + options) + { + Reason = new Reason(because, becauseArgs), + TraceWriter = options.TraceWriter, + }; var comparands = new Comparands { @@ -419,7 +424,9 @@ public AndConstraint> BeInAscendingOrder> BeInAscendingOrder( IComparer comparer, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), "Cannot assert collection ordering without specifying a comparer."); + Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), + "Cannot assert collection ordering without specifying a comparer."); + return BeInOrder(comparer, SortOrder.Ascending, because, becauseArgs); } @@ -445,9 +452,12 @@ public AndConstraint> BeInAscendingOrder( /// /// is . public AndConstraint> BeInAscendingOrder( - Expression> propertyExpression, IComparer comparer, string because = "", params object[] becauseArgs) + Expression> propertyExpression, IComparer comparer, string because = "", + params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), "Cannot assert collection ordering without specifying a comparer."); + Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), + "Cannot assert collection ordering without specifying a comparer."); + return BeOrderedBy(propertyExpression, comparer, SortOrder.Ascending, because, becauseArgs); } @@ -487,7 +497,8 @@ public AndConstraint> BeInAscendingOrder(string /// /// Empty and single element collections are considered to be ordered both in ascending and descending order at the same time. /// - public AndConstraint> BeInAscendingOrder(Func comparison, string because = "", params object[] becauseArgs) + public AndConstraint> BeInAscendingOrder(Func comparison, string because = "", + params object[] becauseArgs) { return BeInOrder(Comparer.Create((x, y) => comparison(x, y)), SortOrder.Ascending, because, becauseArgs); } @@ -536,7 +547,9 @@ public AndConstraint> BeInDescendingOrder> BeInDescendingOrder( IComparer comparer, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), "Cannot assert collection ordering without specifying a comparer."); + Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), + "Cannot assert collection ordering without specifying a comparer."); + return BeInOrder(comparer, SortOrder.Descending, because, becauseArgs); } @@ -562,9 +575,12 @@ public AndConstraint> BeInDescendingOrder( /// /// is . public AndConstraint> BeInDescendingOrder( - Expression> propertyExpression, IComparer comparer, string because = "", params object[] becauseArgs) + Expression> propertyExpression, IComparer comparer, string because = "", + params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), "Cannot assert collection ordering without specifying a comparer."); + Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), + "Cannot assert collection ordering without specifying a comparer."); + return BeOrderedBy(propertyExpression, comparer, SortOrder.Descending, because, becauseArgs); } @@ -604,7 +620,8 @@ public AndConstraint> BeInDescendingOrder(string /// /// Empty and single element collections are considered to be ordered both in ascending and descending order at the same time. /// - public AndConstraint> BeInDescendingOrder(Func comparison, string because = "", params object[] becauseArgs) + public AndConstraint> BeInDescendingOrder(Func comparison, string because = "", + params object[] becauseArgs) { return BeInOrder(Comparer.Create((x, y) => comparison(x, y)), SortOrder.Descending, because, becauseArgs); } @@ -647,7 +664,8 @@ public AndConstraint BeNullOrEmpty(string because = "", params obje public AndConstraint BeSubsetOf(IEnumerable expectedSuperset, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(expectedSuperset, nameof(expectedSuperset), "Cannot verify a subset against a collection."); + Guard.ThrowIfArgumentIsNull(expectedSuperset, nameof(expectedSuperset), + "Cannot verify a subset against a collection."); Execute.Assertion .BecauseOf(because, becauseArgs) @@ -688,6 +706,7 @@ public AndWhichConstraint Contain(T expected, string because = " if (success) { ICollection collection = Subject.ConvertOrCastToCollection(); + Execute.Assertion .BecauseOf(because, becauseArgs) .ForCondition(collection.Contains(expected)) @@ -711,7 +730,8 @@ public AndWhichConstraint Contain(T expected, string because = " /// Zero or more objects to format using the placeholders in . /// /// is . - public AndWhichConstraint Contain(Expression> predicate, string because = "", params object[] becauseArgs) + public AndWhichConstraint Contain(Expression> predicate, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(predicate); @@ -766,6 +786,7 @@ public AndConstraint Contain(IEnumerable expected, string becaus if (success) { IEnumerable missingItems = expectedObjects.Except(Subject); + if (missingItems.Any()) { if (expectedObjects.Count > 1) @@ -835,7 +856,8 @@ public AndWhichConstraint ContainEquivalentOf(TExp /// Zero or more objects to format using the placeholders in . /// /// is . - public AndWhichConstraint ContainEquivalentOf(TExpectation expectation, Func, + public AndWhichConstraint ContainEquivalentOf(TExpectation expectation, + Func, EquivalencyAssertionOptions> config, string because = "", params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(config); @@ -854,11 +876,13 @@ public AndWhichConstraint ContainEquivalentOf(TExp foreach (T actualItem in Subject) { - var context = new EquivalencyValidationContext(Node.From(() => AssertionScope.Current.CallerIdentity), options) - { - Reason = new Reason(because, becauseArgs), - TraceWriter = options.TraceWriter - }; + var context = + new EquivalencyValidationContext(Node.From(() => AssertionScope.Current.CallerIdentity), + options) + { + Reason = new Reason(because, becauseArgs), + TraceWriter = options.TraceWriter + }; var comparands = new Comparands { @@ -870,6 +894,7 @@ public AndWhichConstraint ContainEquivalentOf(TExp new EquivalencyValidator().AssertEquality(comparands, context); string[] failures = scope.Discard(); + if (!failures.Any()) { return new AndWhichConstraint((TAssertions)this, actualItem); @@ -1074,12 +1099,14 @@ public AndWhichConstraint ContainSingle(string because = "", par if (success) { ICollection actualItems = Subject.ConvertOrCastToCollection(); + switch (actualItems.Count) { case 0: // Fail, Collection is empty Execute.Assertion .BecauseOf(because, becauseArgs) .FailWith("Expected {context:collection} to contain a single item{reason}, but the collection is empty."); + break; case 1: // Success Condition match = actualItems.Single(); @@ -1088,6 +1115,7 @@ public AndWhichConstraint ContainSingle(string because = "", par Execute.Assertion .BecauseOf(because, becauseArgs) .FailWith("Expected {context:collection} to contain a single item{reason}, but found {0}.", Subject); + break; } } @@ -1125,6 +1153,7 @@ public AndWhichConstraint ContainSingle(Expression if (success) { ICollection actualItems = Subject.ConvertOrCastToCollection(); + Execute.Assertion .ForCondition(actualItems.Any()) .BecauseOf(because, becauseArgs) @@ -1132,20 +1161,24 @@ public AndWhichConstraint ContainSingle(Expression matches = actualItems.Where(predicate.Compile()).ToArray(); int count = matches.Length; - switch (count) + + if (count == 0) { - case 0: - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith(expectationPrefix + "but no such item was found.", predicate); - break; - case > 1: - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith(expectationPrefix + "but " + count.ToString(CultureInfo.InvariantCulture) + " such items were found.", predicate); - break; - default: - break; + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith(expectationPrefix + "but no such item was found.", predicate); + } + else if (count > 1) + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith( + expectationPrefix + "but " + count.ToString(CultureInfo.InvariantCulture) + " such items were found.", + predicate); + } + else + { + // Can never happen } } @@ -1190,7 +1223,8 @@ public AndConstraint EndWith(IEnumerable expectation, string bec /// /// is . public AndConstraint EndWith( - IEnumerable expectation, Func equalityComparison, string because = "", params object[] becauseArgs) + IEnumerable expectation, Func equalityComparison, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(expectation, nameof(expectation), "Cannot compare collection with ."); @@ -1247,7 +1281,8 @@ public AndConstraint Equal(params T[] elements) /// Zero or more objects to format using the placeholders in . /// public AndConstraint Equal( - IEnumerable expectation, Func equalityComparison, string because = "", params object[] becauseArgs) + IEnumerable expectation, Func equalityComparison, string because = "", + params object[] becauseArgs) { AssertSubjectEquality(expectation, equalityComparison, because, becauseArgs); @@ -1321,7 +1356,8 @@ public AndConstraint HaveCount(int expected, string because = "", p public AndConstraint HaveCount(Expression> countPredicate, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(countPredicate, nameof(countPredicate), "Cannot compare collection count against a predicate."); + Guard.ThrowIfArgumentIsNull(countPredicate, nameof(countPredicate), + "Cannot compare collection count against a predicate."); bool success = Execute.Assertion .BecauseOf(because, becauseArgs) @@ -1357,7 +1393,8 @@ public AndConstraint HaveCount(Expression> countPre /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint HaveCountGreaterThanOrEqualTo(int expected, string because = "", params object[] becauseArgs) + public AndConstraint HaveCountGreaterThanOrEqualTo(int expected, string because = "", + params object[] becauseArgs) { Execute.Assertion .BecauseOf(because, becauseArgs) @@ -1376,7 +1413,8 @@ public AndConstraint HaveCountGreaterThanOrEqualTo(int expected, st } [EditorBrowsable(EditorBrowsableState.Never)] - public AndConstraint HaveCountGreaterOrEqualTo(int expected, string because = "", params object[] becauseArgs) => HaveCountGreaterThanOrEqualTo(expected, because, becauseArgs); + public AndConstraint HaveCountGreaterOrEqualTo(int expected, string because = "", params object[] becauseArgs) => + HaveCountGreaterThanOrEqualTo(expected, because, becauseArgs); /// /// Asserts that the number of items in the collection is greater than the supplied amount. @@ -1437,7 +1475,8 @@ public AndConstraint HaveCountLessThanOrEqualTo(int expected, strin } [EditorBrowsable(EditorBrowsableState.Never)] - public AndConstraint HaveCountLessOrEqualTo(int expected, string because = "", params object[] becauseArgs) => HaveCountLessThanOrEqualTo(expected, because, becauseArgs); + public AndConstraint HaveCountLessOrEqualTo(int expected, string because = "", params object[] becauseArgs) => + HaveCountLessThanOrEqualTo(expected, because, becauseArgs); /// /// Asserts that the number of items in the collection is less than the supplied amount. @@ -1525,7 +1564,8 @@ public AndWhichConstraint HaveElementAt(int index, T element, st /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint HaveElementPreceding(T successor, T expectation, string because = "", params object[] becauseArgs) + public AndConstraint HaveElementPreceding(T successor, T expectation, string because = "", + params object[] becauseArgs) { Execute.Assertion .BecauseOf(because, becauseArgs) @@ -1561,7 +1601,8 @@ public AndConstraint HaveElementPreceding(T successor, T expectatio /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint HaveElementSucceeding(T predecessor, T expectation, string because = "", params object[] becauseArgs) + public AndConstraint HaveElementSucceeding(T predecessor, T expectation, string because = "", + params object[] becauseArgs) { Execute.Assertion .BecauseOf(because, becauseArgs) @@ -1633,7 +1674,8 @@ public AndConstraint HaveSameCount(IEnumerable IntersectWith(IEnumerable otherCollection, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(otherCollection, nameof(otherCollection), "Cannot verify intersection against a collection."); + Guard.ThrowIfArgumentIsNull(otherCollection, nameof(otherCollection), + "Cannot verify intersection against a collection."); bool success = Execute.Assertion .BecauseOf(because, becauseArgs) @@ -1711,7 +1753,8 @@ public AndConstraint NotBeEquivalentTo(IEnumerable NotBeInAscendingOrder( public AndConstraint NotBeInAscendingOrder( IComparer comparer, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), "Cannot assert collection ordering without specifying a comparer."); + Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), + "Cannot assert collection ordering without specifying a comparer."); + return NotBeInOrder(comparer, SortOrder.Ascending, because, becauseArgs); } @@ -1838,9 +1883,12 @@ public AndConstraint NotBeInAscendingOrder( /// /// is . public AndConstraint NotBeInAscendingOrder( - Expression> propertyExpression, IComparer comparer, string because = "", params object[] becauseArgs) + Expression> propertyExpression, IComparer comparer, string because = "", + params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), "Cannot assert collection ordering without specifying a comparer."); + Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), + "Cannot assert collection ordering without specifying a comparer."); + return NotBeOrderedBy(propertyExpression, comparer, SortOrder.Ascending, because, becauseArgs); } @@ -1879,7 +1927,8 @@ public AndConstraint NotBeInAscendingOrder(string because = "", par /// /// Empty and single element collections are considered to be ordered both in ascending and descending order at the same time. /// - public AndConstraint NotBeInAscendingOrder(Func comparison, string because = "", params object[] becauseArgs) + public AndConstraint NotBeInAscendingOrder(Func comparison, string because = "", + params object[] becauseArgs) { return NotBeInOrder(Comparer.Create((x, y) => comparison(x, y)), SortOrder.Ascending, because, becauseArgs); } @@ -1928,7 +1977,9 @@ public AndConstraint NotBeInDescendingOrder( public AndConstraint NotBeInDescendingOrder( IComparer comparer, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), "Cannot assert collection ordering without specifying a comparer."); + Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), + "Cannot assert collection ordering without specifying a comparer."); + return NotBeInOrder(comparer, SortOrder.Descending, because, becauseArgs); } @@ -1954,9 +2005,12 @@ public AndConstraint NotBeInDescendingOrder( /// /// is . public AndConstraint NotBeInDescendingOrder( - Expression> propertyExpression, IComparer comparer, string because = "", params object[] becauseArgs) + Expression> propertyExpression, IComparer comparer, string because = "", + params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), "Cannot assert collection ordering without specifying a comparer."); + Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), + "Cannot assert collection ordering without specifying a comparer."); + return NotBeOrderedBy(propertyExpression, comparer, SortOrder.Descending, because, becauseArgs); } @@ -1995,7 +2049,8 @@ public AndConstraint NotBeInDescendingOrder(string because = "", pa /// /// Empty and single element collections are considered to be ordered both in ascending and descending order at the same time. /// - public AndConstraint NotBeInDescendingOrder(Func comparison, string because = "", params object[] becauseArgs) + public AndConstraint NotBeInDescendingOrder(Func comparison, string because = "", + params object[] becauseArgs) { return NotBeInOrder(Comparer.Create((x, y) => comparison(x, y)), SortOrder.Descending, because, becauseArgs); } @@ -2041,7 +2096,8 @@ public AndConstraint NotBeSubsetOf(IEnumerable unexpectedSuperse { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Did not expect {context:collection} {0} to be a subset of {1}{reason}, but they both reference the same object.", + .FailWith( + "Did not expect {context:collection} {0} to be a subset of {1}{reason}, but they both reference the same object.", Subject, unexpectedSuperset); } @@ -2052,7 +2108,8 @@ public AndConstraint NotBeSubsetOf(IEnumerable unexpectedSuperse { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Did not expect {context:collection} {0} to be a subset of {1}{reason}.", actualItems, unexpectedSuperset); + .FailWith("Did not expect {context:collection} {0} to be a subset of {1}{reason}.", actualItems, + unexpectedSuperset); } } @@ -2082,6 +2139,7 @@ public AndWhichConstraint NotContain(T unexpected, string becaus if (success) { ICollection collection = Subject.ConvertOrCastToCollection(); + if (collection.Contains(unexpected)) { Execute.Assertion @@ -2107,7 +2165,8 @@ public AndWhichConstraint NotContain(T unexpected, string becaus /// Zero or more objects to format using the placeholders in . /// /// is . - public AndConstraint NotContain(Expression> predicate, string because = "", params object[] becauseArgs) + public AndConstraint NotContain(Expression> predicate, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(predicate); @@ -2150,7 +2209,9 @@ public AndConstraint NotContain(IEnumerable unexpected, string b Guard.ThrowIfArgumentIsNull(unexpected, nameof(unexpected), "Cannot verify non-containment against a collection"); ICollection unexpectedObjects = unexpected.ConvertOrCastToCollection(); - Guard.ThrowIfArgumentIsEmpty(unexpectedObjects, nameof(unexpected), "Cannot verify non-containment against an empty collection"); + + Guard.ThrowIfArgumentIsEmpty(unexpectedObjects, nameof(unexpected), + "Cannot verify non-containment against an empty collection"); bool success = Execute.Assertion .BecauseOf(because, becauseArgs) @@ -2160,6 +2221,7 @@ public AndConstraint NotContain(IEnumerable unexpected, string b if (success) { IEnumerable foundItems = unexpectedObjects.Intersect(Subject); + if (foundItems.Any()) { if (unexpectedObjects.Count > 1) @@ -2229,31 +2291,37 @@ public AndConstraint NotContainEquivalentOf(TExpectat /// Zero or more objects to format using the placeholders in . /// /// is . - public AndConstraint NotContainEquivalentOf(TExpectation unexpected, Func, - EquivalencyAssertionOptions> config, string because = "", params object[] becauseArgs) + public AndConstraint NotContainEquivalentOf(TExpectation unexpected, + Func, + EquivalencyAssertionOptions> config, string because = "", params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(config); bool success = Execute.Assertion .BecauseOf(because, becauseArgs) .ForCondition(Subject is not null) - .FailWith("Expected {context:collection} not to contain equivalent of {0}{reason}, but collection is .", unexpected); + .FailWith("Expected {context:collection} not to contain equivalent of {0}{reason}, but collection is .", + unexpected); if (success) { EquivalencyAssertionOptions options = config(AssertionOptions.CloneDefaults()); var foundIndices = new List(); + using (var scope = new AssertionScope()) { int index = 0; + foreach (T actualItem in Subject) { - var context = new EquivalencyValidationContext(Node.From(() => AssertionScope.Current.CallerIdentity), options) - { - Reason = new Reason(because, becauseArgs), - TraceWriter = options.TraceWriter - }; + var context = + new EquivalencyValidationContext(Node.From(() => AssertionScope.Current.CallerIdentity), + options) + { + Reason = new Reason(because, becauseArgs), + TraceWriter = options.TraceWriter + }; var comparands = new Comparands { @@ -2281,7 +2349,8 @@ public AndConstraint NotContainEquivalentOf(TExpectat { Execute.Assertion .BecauseOf(because, becauseArgs) - .WithExpectation("Expected {context:collection} {0} not to contain equivalent of {1}{reason}, ", Subject, unexpected) + .WithExpectation("Expected {context:collection} {0} not to contain equivalent of {1}{reason}, ", Subject, + unexpected) .AddReportable("configuration", () => options.ToString()); if (foundIndices.Count == 1) @@ -2332,7 +2401,8 @@ public AndConstraint NotContainInOrder(params T[] unexpected) public AndConstraint NotContainInOrder(IEnumerable unexpected, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(unexpected, nameof(unexpected), "Cannot verify absence of ordered containment against a collection."); + Guard.ThrowIfArgumentIsNull(unexpected, nameof(unexpected), + "Cannot verify absence of ordered containment against a collection."); if (Subject is null) { @@ -2344,6 +2414,7 @@ public AndConstraint NotContainInOrder(IEnumerable unexpected, s } IList unexpectedItems = unexpected.ConvertOrCastToList(); + if (unexpectedItems.Any()) { IList actualItems = Subject.ConvertOrCastToList(); @@ -2401,7 +2472,8 @@ public AndConstraint NotContainInConsecutiveOrder(params T[] unexpe public AndConstraint NotContainInConsecutiveOrder(IEnumerable unexpected, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(unexpected, nameof(unexpected), "Cannot verify absence of ordered containment against a collection."); + Guard.ThrowIfArgumentIsNull(unexpected, nameof(unexpected), + "Cannot verify absence of ordered containment against a collection."); if (Subject is null) { @@ -2413,6 +2485,7 @@ public AndConstraint NotContainInConsecutiveOrder(IEnumerable un } IList unexpectedItems = unexpected.ConvertOrCastToList(); + if (unexpectedItems.Any()) { IList actualItems = Subject.ConvertOrCastToList(); @@ -2439,7 +2512,7 @@ public AndConstraint NotContainInConsecutiveOrder(IEnumerable un .FailWith( "Expected {context:collection} {0} to not contain items {1} in consecutive order{reason}, " + "but items appeared in order ending at index {2}.", - Subject, unexpectedItems, subjectIndex + consecutiveItems - 2); + Subject, unexpectedItems, (subjectIndex + consecutiveItems) - 2); } subjectIndex++; @@ -2462,7 +2535,8 @@ public AndConstraint NotContainInConsecutiveOrder(IEnumerable un /// Zero or more objects to format using the placeholders in . /// /// is . - public AndConstraint NotContainNulls(Expression> predicate, string because = "", params object[] becauseArgs) + public AndConstraint NotContainNulls(Expression> predicate, string because = "", + params object[] becauseArgs) where TKey : class { Guard.ThrowIfArgumentIsNull(predicate); @@ -2521,13 +2595,16 @@ public AndConstraint NotContainNulls(string because = "", params ob { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:collection} not to contain s{reason}, but found several at indices {0}.", indices); + .FailWith( + "Expected {context:collection} not to contain s{reason}, but found several at indices {0}.", + indices); } else { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:collection} not to contain s{reason}, but found one at index {0}.", indices[0]); + .FailWith("Expected {context:collection} not to contain s{reason}, but found one at index {0}.", + indices[0]); } } } @@ -2612,7 +2689,8 @@ public AndConstraint NotHaveCount(int unexpected, string because = /// Zero or more objects to format using the placeholders in . /// /// is . - public AndConstraint NotHaveSameCount(IEnumerable otherCollection, string because = "", + public AndConstraint NotHaveSameCount(IEnumerable otherCollection, + string because = "", params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(otherCollection, nameof(otherCollection), "Cannot verify count against a collection."); @@ -2654,7 +2732,8 @@ public AndConstraint NotHaveSameCount(IEnumerable NotIntersectWith(IEnumerable otherCollection, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(otherCollection, nameof(otherCollection), "Cannot verify intersection against a collection."); + Guard.ThrowIfArgumentIsNull(otherCollection, nameof(otherCollection), + "Cannot verify intersection against a collection."); Execute.Assertion .BecauseOf(because, becauseArgs) @@ -2729,7 +2808,8 @@ public AndConstraint OnlyContain( /// Zero or more objects to format using the placeholders in . /// /// is . - public AndConstraint OnlyHaveUniqueItems(Expression> predicate, string because = "", params object[] becauseArgs) + public AndConstraint OnlyHaveUniqueItems(Expression> predicate, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(predicate); @@ -2753,7 +2833,8 @@ public AndConstraint OnlyHaveUniqueItems(Expression g)); } @@ -2761,7 +2842,8 @@ public AndConstraint OnlyHaveUniqueItems(Expression OnlyHaveUniqueItems(string because = "", param { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:collection} to only have unique items{reason}, but items {0} are not unique.", + .FailWith( + "Expected {context:collection} to only have unique items{reason}, but items {0} are not unique.", groupWithMultipleItems); } else @@ -2909,12 +2992,15 @@ public AndConstraint SatisfyRespectively(params Action[] element /// /// is . /// is empty. - public AndConstraint SatisfyRespectively(IEnumerable> expected, string because = "", params object[] becauseArgs) + public AndConstraint SatisfyRespectively(IEnumerable> expected, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(expected, nameof(expected), "Cannot verify against a collection of inspectors"); ICollection> elementInspectors = expected.ConvertOrCastToCollection(); - Guard.ThrowIfArgumentIsEmpty(elementInspectors, nameof(expected), "Cannot verify against an empty collection of inspectors"); + + Guard.ThrowIfArgumentIsEmpty(elementInspectors, nameof(expected), + "Cannot verify against an empty collection of inspectors"); bool success = Execute.Assertion .BecauseOf(because, becauseArgs) @@ -2950,7 +3036,8 @@ public AndConstraint SatisfyRespectively(IEnumerable> exp Execute.Assertion .BecauseOf(because, becauseArgs) - .WithExpectation("Expected {context:collection} to satisfy all inspectors{reason}, but some inspectors are not satisfied:") + .WithExpectation( + "Expected {context:collection} to satisfy all inspectors{reason}, but some inspectors are not satisfied:") .FailWithPreFormatted(failureMessage) .Then .ClearExpectation(); @@ -2995,12 +3082,15 @@ public AndConstraint Satisfy(params Expression>[] pre /// /// is . /// is empty. - public AndConstraint Satisfy(IEnumerable>> predicates, string because = "", params object[] becauseArgs) + public AndConstraint Satisfy(IEnumerable>> predicates, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(predicates, nameof(predicates), "Cannot verify against a collection of predicates"); IList>> predicatesList = predicates.ConvertOrCastToList(); - Guard.ThrowIfArgumentIsEmpty(predicatesList, nameof(predicates), "Cannot verify against an empty collection of predicates"); + + Guard.ThrowIfArgumentIsEmpty(predicatesList, nameof(predicates), + "Cannot verify against an empty collection of predicates"); bool success = Execute.Assertion .BecauseOf(because, becauseArgs) @@ -3021,21 +3111,25 @@ public AndConstraint Satisfy(IEnumerable>> var doubleNewLine = Environment.NewLine + Environment.NewLine; List> unmatchedPredicates = maximumMatchingSolution.GetUnmatchedPredicates(); + if (unmatchedPredicates.Any()) { message += doubleNewLine + "The following predicates did not have matching elements:"; + message += doubleNewLine + string.Join(Environment.NewLine, unmatchedPredicates.Select(predicate => Formatter.ToString(predicate.Expression))); } List> unmatchedElements = maximumMatchingSolution.GetUnmatchedElements(); + if (unmatchedElements.Any()) { message += doubleNewLine + "The following elements did not match any predicate:"; IEnumerable elementDescriptions = unmatchedElements .Select(element => $"Index: {element.Index}, Element: {Formatter.ToString(element.Value)}"); + message += doubleNewLine + string.Join(doubleNewLine, elementDescriptions); } @@ -3088,7 +3182,8 @@ public AndConstraint StartWith(IEnumerable expectation, string b /// /// is . public AndConstraint StartWith( - IEnumerable expectation, Func equalityComparison, string because = "", params object[] becauseArgs) + IEnumerable expectation, Func equalityComparison, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(expectation, nameof(expectation), "Cannot compare collection with ."); @@ -3154,7 +3249,7 @@ internal virtual IOrderedEnumerable GetOrderedEnumerable( { Func keySelector = propertyExpression.Compile(); - IOrderedEnumerable expectation = (direction == SortOrder.Ascending) + IOrderedEnumerable expectation = direction == SortOrder.Ascending ? unordered.OrderBy(keySelector, comparer) : unordered.OrderByDescending(keySelector, comparer); @@ -3171,7 +3266,9 @@ protected static IEnumerable RepeatAsManyAs(TExpecta return RepeatAsManyAsIterator(value, enumerable); } - protected void AssertCollectionEndsWith(IEnumerable actual, ICollection expected, Func equalityComparison, string because = "", params object[] becauseArgs) + protected void AssertCollectionEndsWith(IEnumerable actual, + ICollection expected, Func equalityComparison, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(equalityComparison); @@ -3193,7 +3290,9 @@ protected void AssertCollectionEndsWith(IEnumerable(IEnumerable actualItems, ICollection expected, Func equalityComparison, string because = "", params object[] becauseArgs) + protected void AssertCollectionStartsWith(IEnumerable actualItems, + ICollection expected, Func equalityComparison, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(equalityComparison); @@ -3210,13 +3309,14 @@ protected void AssertCollectionStartsWith(IEnumerable(IEnumerable expectation, Func equalityComparison, - string because = "", params object[] becauseArgs) + protected void AssertSubjectEquality(IEnumerable expectation, + Func equalityComparison, string because = "", params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(equalityComparison); bool subjectIsNull = Subject is null; bool expectationIsNull = expectation is null; + if (subjectIsNull && expectationIsNull) { return; @@ -3227,6 +3327,7 @@ protected void AssertSubjectEquality(IEnumerable exp ICollection expectedItems = expectation.ConvertOrCastToCollection(); AssertionScope assertion = Execute.Assertion.BecauseOf(because, becauseArgs); + if (subjectIsNull) { assertion.FailWith("Expected {context:collection} to be equal to {0}{reason}, but found .", expectedItems); @@ -3270,12 +3371,13 @@ private static T PredecessorOf(T successor, TCollection subject) { IList collection = subject.ConvertOrCastToList(); int index = collection.IndexOf(successor); - return (index > 0) ? collection[index - 1] : default; + return index > 0 ? collection[index - 1] : default; } private static IEnumerable RepeatAsManyAsIterator(TExpectation value, IEnumerable enumerable) { using IEnumerator enumerator = enumerable.GetEnumerator(); + while (enumerator.MoveNext()) { yield return value; @@ -3286,18 +3388,22 @@ private static T SuccessorOf(T predecessor, TCollection subject) { IList collection = subject.ConvertOrCastToList(); int index = collection.IndexOf(predecessor); - return (index < (collection.Count - 1)) ? collection[index + 1] : default; + return index < (collection.Count - 1) ? collection[index + 1] : default; } private string[] CollectFailuresFromInspectors(IEnumerable> elementInspectors) { string[] collectionFailures; + using (var collectionScope = new AssertionScope()) { int index = 0; - foreach ((T element, Action inspector) in Subject.Zip(elementInspectors, (element, inspector) => (element, inspector))) + + foreach ((T element, Action inspector) in Subject.Zip(elementInspectors, + (element, inspector) => (element, inspector))) { string[] inspectorFailures; + using (var itemScope = new AssertionScope()) { inspector(element); @@ -3307,7 +3413,9 @@ private string[] CollectFailuresFromInspectors(IEnumerable> elementIns if (inspectorFailures.Length > 0) { // Adding one tab and removing trailing dot to allow nested SatisfyRespectively - string failures = string.Join(Environment.NewLine, inspectorFailures.Select(x => x.IndentLines().TrimEnd('.'))); + string failures = string.Join(Environment.NewLine, + inspectorFailures.Select(x => x.IndentLines().TrimEnd('.'))); + collectionScope.AddPreFormattedFailure($"At index {index}:{Environment.NewLine}{failures}"); } @@ -3320,7 +3428,8 @@ private string[] CollectFailuresFromInspectors(IEnumerable> elementIns return collectionFailures; } - private bool IsValidProperty(Expression> propertyExpression, string because, object[] becauseArgs) + private bool IsValidProperty(Expression> propertyExpression, string because, + object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(propertyExpression, nameof(propertyExpression), "Cannot assert collection ordering without specifying a property."); @@ -3368,7 +3477,7 @@ private AndConstraint NotBeOrderedBy( private AndConstraint> BeInOrder( IComparer comparer, SortOrder expectedOrder, string because = "", params object[] becauseArgs) { - string sortOrder = (expectedOrder == SortOrder.Ascending) ? "ascending" : "descending"; + string sortOrder = expectedOrder == SortOrder.Ascending ? "ascending" : "descending"; bool success = Execute.Assertion .BecauseOf(because, becauseArgs) @@ -3381,7 +3490,7 @@ private AndConstraint> BeInOrder( { IList actualItems = Subject.ConvertOrCastToList(); - ordering = (expectedOrder == SortOrder.Ascending) + ordering = expectedOrder == SortOrder.Ascending ? actualItems.OrderBy(item => item, comparer) : actualItems.OrderByDescending(item => item, comparer); @@ -3395,7 +3504,7 @@ private AndConstraint> BeInOrder( Execute.Assertion .BecauseOf(because, becauseArgs) .FailWith("Expected {context:collection} to be in " + sortOrder + - " order{reason}, but found {0} where item at index {1} is in wrong order.", + " order{reason}, but found {0} where item at index {1} is in wrong order.", actualItems, index); return new AndConstraint>( @@ -3411,9 +3520,10 @@ private AndConstraint> BeInOrder( /// Asserts the current collection does not have all elements in ascending order. Elements are compared /// using their implementation. /// - private AndConstraint NotBeInOrder(IComparer comparer, SortOrder order, string because = "", params object[] becauseArgs) + private AndConstraint NotBeInOrder(IComparer comparer, SortOrder order, string because = "", + params object[] becauseArgs) { - string sortOrder = (order == SortOrder.Ascending) ? "ascending" : "descending"; + string sortOrder = order == SortOrder.Ascending ? "ascending" : "descending"; bool success = Execute.Assertion .BecauseOf(because, becauseArgs) @@ -3424,11 +3534,12 @@ private AndConstraint NotBeInOrder(IComparer comparer, SortOrder { IList actualItems = Subject.ConvertOrCastToList(); - T[] orderedItems = (order == SortOrder.Ascending) + T[] orderedItems = order == SortOrder.Ascending ? actualItems.OrderBy(item => item, comparer).ToArray() : actualItems.OrderByDescending(item => item, comparer).ToArray(); Func areSameOrEqual = ObjectExtensions.GetComparer(); + bool itemsAreUnordered = actualItems .Where((actualItem, index) => !areSameOrEqual(actualItem, orderedItems[index])) .Any(); @@ -3446,11 +3557,13 @@ private AndConstraint NotBeInOrder(IComparer comparer, SortOrder /// public override bool Equals(object obj) => - throw new NotSupportedException("Equals is not part of Fluent Assertions. Did you mean BeSameAs(), Equal(), or BeEquivalentTo() instead?"); + throw new NotSupportedException( + "Equals is not part of Fluent Assertions. Did you mean BeSameAs(), Equal(), or BeEquivalentTo() instead?"); private static int IndexOf(IList items, T item, int startIndex) { Func comparer = ObjectExtensions.GetComparer(); + for (; startIndex < items.Count; startIndex++) { if (comparer(items[startIndex], item)) @@ -3482,5 +3595,5 @@ private static int ConsecutiveItemCount(IList actualItems, IList expectedI } private protected static IComparer GetComparer() => - typeof(TItem) == typeof(string) ? (IComparer)(object)StringComparer.Ordinal : Comparer.Default; + typeof(TItem) == typeof(string) ? (IComparer)StringComparer.Ordinal : Comparer.Default; } diff --git a/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs b/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs index 3f07c6a51a..132a2b5517 100644 --- a/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs +++ b/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs @@ -12,8 +12,8 @@ namespace FluentAssertions.Collections; /// Contains a number of methods to assert that a is in the expected state. /// [DebuggerNonUserCode] -public class GenericDictionaryAssertions : - GenericDictionaryAssertions> +public class GenericDictionaryAssertions + : GenericDictionaryAssertions> where TCollection : IEnumerable> { public GenericDictionaryAssertions(TCollection keyValuePairs) @@ -26,8 +26,8 @@ public GenericDictionaryAssertions(TCollection keyValuePairs) /// Contains a number of methods to assert that a is in the expected state. /// [DebuggerNonUserCode] -public class GenericDictionaryAssertions : - GenericCollectionAssertions, TAssertions> +public class GenericDictionaryAssertions + : GenericCollectionAssertions, TAssertions> where TCollection : IEnumerable> where TAssertions : GenericDictionaryAssertions { @@ -87,13 +87,14 @@ public AndConstraint Equal(T expected, } Func areSameOrEqual = ObjectExtensions.GetComparer(); + foreach (var key in expectedKeys) { Execute.Assertion .ForCondition(areSameOrEqual(GetValue(Subject, key), GetValue(expected, key))) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:dictionary} to be equal to {0}{reason}, but {1} differs at key {2}.", - expected, Subject, key); + expected, Subject, key); } return new AndConstraint((TAssertions)this); @@ -139,6 +140,7 @@ public AndConstraint NotEqual(T unexpected, IEnumerable additionalKeys = subjectKeys.Except(unexpectedKeys); Func areSameOrEqual = ObjectExtensions.GetComparer(); + bool foundDifference = missingKeys.Any() || additionalKeys.Any() || subjectKeys.Any(key => !areSameOrEqual(GetValue(Subject, key), GetValue(unexpected, key))); @@ -214,11 +216,12 @@ public AndConstraint BeEquivalentTo(TExpectation expe EquivalencyAssertionOptions options = config(AssertionOptions.CloneDefaults()); - var context = new EquivalencyValidationContext(Node.From(() => AssertionScope.Current.CallerIdentity), options) - { - Reason = new Reason(because, becauseArgs), - TraceWriter = options.TraceWriter - }; + var context = + new EquivalencyValidationContext(Node.From(() => AssertionScope.Current.CallerIdentity), options) + { + Reason = new Reason(because, becauseArgs), + TraceWriter = options.TraceWriter + }; var comparands = new Comparands { @@ -283,7 +286,8 @@ public AndConstraint ContainKeys(params TKey[] expected) public AndConstraint ContainKeys(IEnumerable expected, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(expected, nameof(expected), "Cannot verify key containment against a collection of keys"); + Guard.ThrowIfArgumentIsNull(expected, nameof(expected), + "Cannot verify key containment against a collection of keys"); ICollection expectedKeys = expected.ConvertOrCastToCollection(); Guard.ThrowIfArgumentIsEmpty(expectedKeys, nameof(expected), "Cannot verify key containment against an empty sequence"); @@ -348,7 +352,8 @@ public AndConstraint NotContainKey(TKey unexpected, { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} {0} not to contain key {1}{reason}, but found it anyhow.", Subject, unexpected); + .FailWith("Expected {context:dictionary} {0} not to contain key {1}{reason}, but found it anyhow.", Subject, + unexpected); } return new AndConstraint((TAssertions)this); @@ -381,10 +386,13 @@ public AndConstraint NotContainKeys(params TKey[] unexpected) public AndConstraint NotContainKeys(IEnumerable unexpected, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(unexpected, nameof(unexpected), "Cannot verify key containment against a collection of keys"); + Guard.ThrowIfArgumentIsNull(unexpected, nameof(unexpected), + "Cannot verify key containment against a collection of keys"); ICollection unexpectedKeys = unexpected.ConvertOrCastToCollection(); - Guard.ThrowIfArgumentIsEmpty(unexpectedKeys, nameof(unexpected), "Cannot verify key containment against an empty sequence"); + + Guard.ThrowIfArgumentIsEmpty(unexpectedKeys, nameof(unexpected), + "Cannot verify key containment against an empty sequence"); if (Subject is null) { @@ -436,7 +444,7 @@ public AndWhichConstraint ContainValue(TValue expected, string because = "", params object[] becauseArgs) { AndWhichConstraint> innerConstraint = - ContainValuesAndWhich(new[] { expected }, because, becauseArgs); + ContainValuesAndWhich(new[] { expected }, because, becauseArgs); return new AndWhichConstraint( @@ -470,15 +478,20 @@ public AndConstraint ContainValues(params TValue[] expected) public AndConstraint ContainValues(IEnumerable expected, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(expected, nameof(expected), "Cannot verify value containment against a collection of values"); + Guard.ThrowIfArgumentIsNull(expected, nameof(expected), + "Cannot verify value containment against a collection of values"); + return ContainValuesAndWhich(expected, because, becauseArgs); } - private AndWhichConstraint> ContainValuesAndWhich(IEnumerable expected, string because = "", + private AndWhichConstraint> ContainValuesAndWhich(IEnumerable expected, + string because = "", params object[] becauseArgs) { ICollection expectedValues = expected.ConvertOrCastToCollection(); - Guard.ThrowIfArgumentIsEmpty(expectedValues, nameof(expected), "Cannot verify value containment against an empty sequence"); + + Guard.ThrowIfArgumentIsEmpty(expectedValues, nameof(expected), + "Cannot verify value containment against an empty sequence"); if (Subject is null) { @@ -510,8 +523,8 @@ private AndWhichConstraint> ContainValuesAndWhi return new AndWhichConstraint>((TAssertions)this, - RepetitionPreservingIntersect(subjectValues, expectedValues)); + IEnumerable>((TAssertions)this, + RepetitionPreservingIntersect(subjectValues, expectedValues)); } /// @@ -555,7 +568,8 @@ public AndConstraint NotContainValue(TValue unexpected, { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} {0} not to contain value {1}{reason}, but found it anyhow.", Subject, unexpected); + .FailWith("Expected {context:dictionary} {0} not to contain value {1}{reason}, but found it anyhow.", Subject, + unexpected); } return new AndConstraint((TAssertions)this); @@ -588,11 +602,13 @@ public AndConstraint NotContainValues(params TValue[] unexpected) public AndConstraint NotContainValues(IEnumerable unexpected, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(unexpected, nameof(unexpected), "Cannot verify value containment against a collection of values"); + Guard.ThrowIfArgumentIsNull(unexpected, nameof(unexpected), + "Cannot verify value containment against a collection of values"); ICollection unexpectedValues = unexpected.ConvertOrCastToCollection(); - Guard.ThrowIfArgumentIsEmpty(unexpectedValues, nameof(unexpected), "Cannot verify value containment with an empty sequence"); + Guard.ThrowIfArgumentIsEmpty(unexpectedValues, nameof(unexpected), + "Cannot verify value containment with an empty sequence"); if (Subject is null) { @@ -660,13 +676,16 @@ public AndConstraint Contain(params KeyValuePair[] ex Guard.ThrowIfArgumentIsNull(expected, nameof(expected), "Cannot compare dictionary with ."); ICollection> expectedKeyValuePairs = expected.ConvertOrCastToCollection(); - Guard.ThrowIfArgumentIsEmpty(expectedKeyValuePairs, nameof(expected), "Cannot verify key containment against an empty collection of key/value pairs"); + + Guard.ThrowIfArgumentIsEmpty(expectedKeyValuePairs, nameof(expected), + "Cannot verify key containment against an empty collection of key/value pairs"); if (Subject is null) { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to contain key/value pairs {0}{reason}, but dictionary is {1}.", expected, Subject); + .FailWith("Expected {context:dictionary} to contain key/value pairs {0}{reason}, but dictionary is {1}.", + expected, Subject); } TKey[] expectedKeys = expectedKeyValuePairs.Select(keyValuePair => keyValuePair.Key).ToArray(); @@ -678,7 +697,8 @@ public AndConstraint Contain(params KeyValuePair[] ex { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} {0} to contain key(s) {1}{reason}, but could not find keys {2}.", Subject, + .FailWith("Expected {context:dictionary} {0} to contain key(s) {1}{reason}, but could not find keys {2}.", + Subject, expectedKeys, missingKeys); } else @@ -691,7 +711,9 @@ public AndConstraint Contain(params KeyValuePair[] ex } Func areSameOrEqual = ObjectExtensions.GetComparer(); - KeyValuePair[] keyValuePairsNotSameOrEqualInSubject = expectedKeyValuePairs.Where(keyValuePair => !areSameOrEqual(GetValue(Subject, keyValuePair.Key), keyValuePair.Value)).ToArray(); + + KeyValuePair[] keyValuePairsNotSameOrEqualInSubject = expectedKeyValuePairs + .Where(keyValuePair => !areSameOrEqual(GetValue(Subject, keyValuePair.Key), keyValuePair.Value)).ToArray(); if (keyValuePairsNotSameOrEqualInSubject.Any()) { @@ -699,7 +721,8 @@ public AndConstraint Contain(params KeyValuePair[] ex { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to contain {0}{reason}, but {context:dictionary} differs at keys {1}.", + .FailWith( + "Expected {context:dictionary} to contain {0}{reason}, but {context:dictionary} differs at keys {1}.", expectedKeyValuePairs, keyValuePairsNotSameOrEqualInSubject.Select(keyValuePair => keyValuePair.Key)); } else @@ -709,7 +732,8 @@ public AndConstraint Contain(params KeyValuePair[] ex Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to contain value {0} at key {1}{reason}, but found {2}.", expectedKeyValuePair.Value, expectedKeyValuePair.Key, actual); + .FailWith("Expected {context:dictionary} to contain value {0} at key {1}{reason}, but found {2}.", + expectedKeyValuePair.Value, expectedKeyValuePair.Key, actual); } } @@ -757,23 +781,27 @@ public AndConstraint Contain(TKey key, TValue value, { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to contain value {0} at key {1}{reason}, but dictionary is {2}.", value, key, + .FailWith("Expected {context:dictionary} to contain value {0} at key {1}{reason}, but dictionary is {2}.", value, + key, Subject); } if (TryGetValue(Subject, key, out TValue actual)) { Func areSameOrEqual = ObjectExtensions.GetComparer(); + Execute.Assertion .ForCondition(areSameOrEqual(actual, value)) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to contain value {0} at key {1}{reason}, but found {2}.", value, key, actual); + .FailWith("Expected {context:dictionary} to contain value {0} at key {1}{reason}, but found {2}.", value, key, + actual); } else { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to contain value {0} at key {1}{reason}, but the key was not found.", value, + .FailWith("Expected {context:dictionary} to contain value {0} at key {1}{reason}, but the key was not found.", + value, key); } @@ -816,20 +844,25 @@ public AndConstraint NotContain(params KeyValuePair[] Guard.ThrowIfArgumentIsNull(items, nameof(items), "Cannot compare dictionary with ."); ICollection> keyValuePairs = items.ConvertOrCastToCollection(); - Guard.ThrowIfArgumentIsEmpty(keyValuePairs, nameof(items), "Cannot verify key containment against an empty collection of key/value pairs"); + + Guard.ThrowIfArgumentIsEmpty(keyValuePairs, nameof(items), + "Cannot verify key containment against an empty collection of key/value pairs"); if (Subject is null) { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to not contain key/value pairs {0}{reason}, but dictionary is {1}.", items, Subject); + .FailWith("Expected {context:dictionary} to not contain key/value pairs {0}{reason}, but dictionary is {1}.", + items, Subject); } - KeyValuePair[] keyValuePairsFound = keyValuePairs.Where(keyValuePair => ContainsKey(Subject, keyValuePair.Key)).ToArray(); + KeyValuePair[] keyValuePairsFound = + keyValuePairs.Where(keyValuePair => ContainsKey(Subject, keyValuePair.Key)).ToArray(); if (keyValuePairsFound.Any()) { Func areSameOrEqual = ObjectExtensions.GetComparer(); + KeyValuePair[] keyValuePairsSameOrEqualInSubject = keyValuePairsFound .Where(keyValuePair => areSameOrEqual(GetValue(Subject, keyValuePair.Key), keyValuePair.Value)).ToArray(); @@ -839,7 +872,9 @@ public AndConstraint NotContain(params KeyValuePair[] { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to not contain key/value pairs {0}{reason}, but found them anyhow.", keyValuePairs); + .FailWith( + "Expected {context:dictionary} to not contain key/value pairs {0}{reason}, but found them anyhow.", + keyValuePairs); } else { @@ -847,7 +882,9 @@ public AndConstraint NotContain(params KeyValuePair[] Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to not contain value {0} at key {1}{reason}, but found it anyhow.", keyValuePair.Value, keyValuePair.Key); + .FailWith( + "Expected {context:dictionary} to not contain value {0} at key {1}{reason}, but found it anyhow.", + keyValuePair.Value, keyValuePair.Key); } } } @@ -896,7 +933,8 @@ public AndConstraint NotContain(TKey key, TValue value, { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} not to contain value {0} at key {1}{reason}, but dictionary is {2}.", value, + .FailWith("Expected {context:dictionary} not to contain value {0} at key {1}{reason}, but dictionary is {2}.", + value, key, Subject); } @@ -905,7 +943,8 @@ public AndConstraint NotContain(TKey key, TValue value, Execute.Assertion .ForCondition(!ObjectExtensions.GetComparer()(actual, value)) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} not to contain value {0} at key {1}{reason}, but found it anyhow.", value, key); + .FailWith("Expected {context:dictionary} not to contain value {0} at key {1}{reason}, but found it anyhow.", + value, key); } return new AndConstraint((TAssertions)this); diff --git a/Src/FluentAssertions/Collections/MaximumMatching/MaximumMatchingSolver.cs b/Src/FluentAssertions/Collections/MaximumMatching/MaximumMatchingSolver.cs index 4fdf160df1..dd64434b33 100644 --- a/Src/FluentAssertions/Collections/MaximumMatching/MaximumMatchingSolver.cs +++ b/Src/FluentAssertions/Collections/MaximumMatching/MaximumMatchingSolver.cs @@ -57,7 +57,8 @@ private IEnumerable FindMatchForPredicate(Predicate predicate, Ma while (breadthFirstSearchTracker.TryDequeueUnMatchedPredicate(out var unmatchedPredicate)) { - var notVisitedMatchingElements = GetMatchingElements(unmatchedPredicate).Where(element => !visitedElements.Contains(element)); + var notVisitedMatchingElements = + GetMatchingElements(unmatchedPredicate).Where(element => !visitedElements.Contains(element)); foreach (var element in notVisitedMatchingElements) { @@ -148,7 +149,10 @@ public bool TryDequeueUnMatchedPredicate(out Predicate unmatchedPredicat public void ReassignElement(Element element, Predicate newMatchedPredicate) { var previouslyMatchedPredicate = originalMatches.GetMatchedPredicate(element); - previousMatchByPredicate.Add(previouslyMatchedPredicate, new Match { Predicate = newMatchedPredicate, Element = element }); + + previousMatchByPredicate.Add(previouslyMatchedPredicate, + new Match { Predicate = newMatchedPredicate, Element = element }); + unmatchedPredicatesQueue.Enqueue(previouslyMatchedPredicate); } diff --git a/Src/FluentAssertions/Collections/StringCollectionAssertions.cs b/Src/FluentAssertions/Collections/StringCollectionAssertions.cs index a7a460f3ee..a73e8ce273 100644 --- a/Src/FluentAssertions/Collections/StringCollectionAssertions.cs +++ b/Src/FluentAssertions/Collections/StringCollectionAssertions.cs @@ -7,8 +7,7 @@ namespace FluentAssertions.Collections; -public class StringCollectionAssertions : - StringCollectionAssertions> +public class StringCollectionAssertions : StringCollectionAssertions> { /// /// Initializes a new instance of the class. @@ -19,8 +18,8 @@ public StringCollectionAssertions(IEnumerable actualValue) } } -public class StringCollectionAssertions : - StringCollectionAssertions> +public class StringCollectionAssertions + : StringCollectionAssertions> where TCollection : IEnumerable { /// @@ -32,8 +31,7 @@ public StringCollectionAssertions(TCollection actualValue) } } -public class StringCollectionAssertions : - GenericCollectionAssertions +public class StringCollectionAssertions : GenericCollectionAssertions where TCollection : IEnumerable where TAssertions : StringCollectionAssertions { @@ -94,7 +92,8 @@ public AndConstraint BeEquivalentTo(params string[] expectation) /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint BeEquivalentTo(IEnumerable expectation, string because = "", params object[] becauseArgs) + public AndConstraint BeEquivalentTo(IEnumerable expectation, string because = "", + params object[] becauseArgs) { return BeEquivalentTo(expectation, config => config, because, becauseArgs); } @@ -127,13 +126,15 @@ public AndConstraint BeEquivalentTo(IEnumerable expectation { Guard.ThrowIfArgumentIsNull(config); - EquivalencyAssertionOptions> options = config(AssertionOptions.CloneDefaults()).AsCollection(); + EquivalencyAssertionOptions> + options = config(AssertionOptions.CloneDefaults()).AsCollection(); - var context = new EquivalencyValidationContext(Node.From>(() => AssertionScope.Current.CallerIdentity), options) - { - Reason = new Reason(because, becauseArgs), - TraceWriter = options.TraceWriter - }; + var context = + new EquivalencyValidationContext(Node.From>(() => AssertionScope.Current.CallerIdentity), options) + { + Reason = new Reason(because, becauseArgs), + TraceWriter = options.TraceWriter + }; var comparands = new Comparands { @@ -241,8 +242,11 @@ public AndConstraint AllBe(string expectation, public AndWhichConstraint ContainMatch(string wildcardPattern, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(wildcardPattern, nameof(wildcardPattern), "Cannot match strings in collection against . Provide a wildcard pattern or use the Contain method."); - Guard.ThrowIfArgumentIsEmpty(wildcardPattern, nameof(wildcardPattern), "Cannot match strings in collection against an empty string. Provide a wildcard pattern or use the Contain method."); + Guard.ThrowIfArgumentIsNull(wildcardPattern, nameof(wildcardPattern), + "Cannot match strings in collection against . Provide a wildcard pattern or use the Contain method."); + + Guard.ThrowIfArgumentIsEmpty(wildcardPattern, nameof(wildcardPattern), + "Cannot match strings in collection against an empty string. Provide a wildcard pattern or use the Contain method."); bool success = Execute.Assertion .BecauseOf(because, becauseArgs) @@ -267,6 +271,7 @@ public AndWhichConstraint ContainMatch(string wildcardPatte private bool ContainsMatch(string wildcardPattern) { using var scope = new AssertionScope(); + return Subject.Any(item => { item.Should().Match(wildcardPattern); @@ -322,13 +327,17 @@ private IEnumerable AllThatMatch(string wildcardPattern) public AndConstraint NotContainMatch(string wildcardPattern, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(wildcardPattern, nameof(wildcardPattern), "Cannot match strings in collection against . Provide a wildcard pattern or use the NotContain method."); - Guard.ThrowIfArgumentIsEmpty(wildcardPattern, nameof(wildcardPattern), "Cannot match strings in collection against an empty string. Provide a wildcard pattern or use the NotContain method."); + Guard.ThrowIfArgumentIsNull(wildcardPattern, nameof(wildcardPattern), + "Cannot match strings in collection against . Provide a wildcard pattern or use the NotContain method."); + + Guard.ThrowIfArgumentIsEmpty(wildcardPattern, nameof(wildcardPattern), + "Cannot match strings in collection against an empty string. Provide a wildcard pattern or use the NotContain method."); bool success = Execute.Assertion .BecauseOf(because, becauseArgs) .ForCondition(Subject is not null) - .FailWith("Did not expect {context:collection} to contain a match of {0}{reason}, but found .", wildcardPattern); + .FailWith("Did not expect {context:collection} to contain a match of {0}{reason}, but found .", + wildcardPattern); if (success) { @@ -344,6 +353,7 @@ public AndConstraint NotContainMatch(string wildcardPattern, string private bool NotContainsMatch(string wildcardPattern) { using var scope = new AssertionScope(); + return Subject.All(item => { item.Should().NotMatch(wildcardPattern); diff --git a/Src/FluentAssertions/Collections/SubsequentOrderingAssertions.cs b/Src/FluentAssertions/Collections/SubsequentOrderingAssertions.cs index ebfdb8294d..77d8e29531 100644 --- a/Src/FluentAssertions/Collections/SubsequentOrderingAssertions.cs +++ b/Src/FluentAssertions/Collections/SubsequentOrderingAssertions.cs @@ -8,8 +8,8 @@ namespace FluentAssertions.Collections; [DebuggerNonUserCode] -public class SubsequentOrderingAssertions : - SubsequentOrderingGenericCollectionAssertions, T, SubsequentOrderingAssertions> +public class SubsequentOrderingAssertions + : SubsequentOrderingGenericCollectionAssertions, T, SubsequentOrderingAssertions> { public SubsequentOrderingAssertions(IEnumerable actualValue, IOrderedEnumerable previousOrderedEnumerable) : base(actualValue, previousOrderedEnumerable) @@ -18,8 +18,8 @@ public SubsequentOrderingAssertions(IEnumerable actualValue, IOrderedEnumerab } [DebuggerNonUserCode] -public class SubsequentOrderingGenericCollectionAssertions : - SubsequentOrderingGenericCollectionAssertions> +public class SubsequentOrderingGenericCollectionAssertions + : SubsequentOrderingGenericCollectionAssertions> where TCollection : IEnumerable { public SubsequentOrderingGenericCollectionAssertions(TCollection actualValue, IOrderedEnumerable previousOrderedEnumerable) @@ -29,8 +29,8 @@ public SubsequentOrderingGenericCollectionAssertions(TCollection actualValue, IO } [DebuggerNonUserCode] -public class SubsequentOrderingGenericCollectionAssertions : - GenericCollectionAssertions +public class SubsequentOrderingGenericCollectionAssertions + : GenericCollectionAssertions where TCollection : IEnumerable where TAssertions : SubsequentOrderingGenericCollectionAssertions { @@ -88,9 +88,12 @@ public AndConstraint> ThenBeInAscendingOrder /// is . public AndConstraint> ThenBeInAscendingOrder( - Expression> propertyExpression, IComparer comparer, string because = "", params object[] becauseArgs) + Expression> propertyExpression, IComparer comparer, string because = "", + params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), "Cannot assert collection ordering without specifying a comparer."); + Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), + "Cannot assert collection ordering without specifying a comparer."); + return ThenBeOrderedBy(propertyExpression, comparer, SortOrder.Ascending, because, becauseArgs); } @@ -139,9 +142,12 @@ public AndConstraint> ThenBeInDescendingOrder /// is . public AndConstraint> ThenBeInDescendingOrder( - Expression> propertyExpression, IComparer comparer, string because = "", params object[] becauseArgs) + Expression> propertyExpression, IComparer comparer, string because = "", + params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), "Cannot assert collection ordering without specifying a comparer."); + Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), + "Cannot assert collection ordering without specifying a comparer."); + return ThenBeOrderedBy(propertyExpression, comparer, SortOrder.Descending, because, becauseArgs); } @@ -166,7 +172,7 @@ internal sealed override IOrderedEnumerable GetOrderedEnumerable( { Func keySelector = propertyExpression.Compile(); - IOrderedEnumerable expectation = (direction == SortOrder.Ascending) + IOrderedEnumerable expectation = direction == SortOrder.Ascending ? previousOrderedEnumerable.ThenBy(keySelector, comparer) : previousOrderedEnumerable.ThenByDescending(keySelector, comparer); diff --git a/Src/FluentAssertions/Common/Configuration.cs b/Src/FluentAssertions/Common/Configuration.cs index 793f770cc5..adf233d20b 100644 --- a/Src/FluentAssertions/Common/Configuration.cs +++ b/Src/FluentAssertions/Common/Configuration.cs @@ -63,6 +63,7 @@ private ValueFormatterDetectionMode DetermineFormatterDetectionMode() } string setting = store.GetSetting("valueFormatters"); + if (!string.IsNullOrEmpty(setting)) { try @@ -90,6 +91,7 @@ public string ValueFormatterAssembly if (valueFormatterAssembly is null) { string assemblyName = store.GetSetting("valueFormattersAssembly"); + if (!string.IsNullOrEmpty(assemblyName)) { valueFormatterAssembly = assemblyName; diff --git a/Src/FluentAssertions/Common/DictionaryHelpers.cs b/Src/FluentAssertions/Common/DictionaryHelpers.cs index cc72fd807f..9570577726 100644 --- a/Src/FluentAssertions/Common/DictionaryHelpers.cs +++ b/Src/FluentAssertions/Common/DictionaryHelpers.cs @@ -58,6 +58,7 @@ public static bool TryGetValue(this TCollection colle static bool TryGetValue(TCollection collection, TKey key, out TValue value) { Func areSameOrEqual = ObjectExtensions.GetComparer(); + foreach (var kvp in collection) { if (areSameOrEqual(kvp.Key, key)) diff --git a/Src/FluentAssertions/Common/EnumerableExtensions.cs b/Src/FluentAssertions/Common/EnumerableExtensions.cs index 333cff3a3e..8c9c1063f7 100644 --- a/Src/FluentAssertions/Common/EnumerableExtensions.cs +++ b/Src/FluentAssertions/Common/EnumerableExtensions.cs @@ -8,12 +8,12 @@ internal static class EnumerableExtensions { public static ICollection ConvertOrCastToCollection(this IEnumerable source) { - return (source as ICollection) ?? source.ToList(); + return source as ICollection ?? source.ToList(); } public static IList ConvertOrCastToList(this IEnumerable source) { - return (source as IList) ?? source.ToList(); + return source as IList ?? source.ToList(); } /// @@ -25,11 +25,13 @@ public static IList ConvertOrCastToList(this IEnumerable source) /// The second sequence to compare. /// Method that is used to compare 2 elements with the same index. /// Index at which two sequences have elements that are not equal, or -1 if enumerables are equal - public static int IndexOfFirstDifferenceWith(this IEnumerable first, IEnumerable second, Func equalityComparison) + public static int IndexOfFirstDifferenceWith(this IEnumerable first, IEnumerable second, + Func equalityComparison) { using IEnumerator firstEnumerator = first.GetEnumerator(); using IEnumerator secondEnumerator = second.GetEnumerator(); int index = 0; + while (true) { bool isFirstCompleted = !firstEnumerator.MoveNext(); diff --git a/Src/FluentAssertions/Common/ExceptionExtensions.cs b/Src/FluentAssertions/Common/ExceptionExtensions.cs index 79ae7c75dc..1e3bbd3fe5 100644 --- a/Src/FluentAssertions/Common/ExceptionExtensions.cs +++ b/Src/FluentAssertions/Common/ExceptionExtensions.cs @@ -9,6 +9,7 @@ internal static class ExceptionExtensions public static ExceptionDispatchInfo Unwrap(this TargetInvocationException exception) { Exception result = exception; + while (result is TargetInvocationException) { result = result.InnerException; diff --git a/Src/FluentAssertions/Common/ExpressionExtensions.cs b/Src/FluentAssertions/Common/ExpressionExtensions.cs index d66d9d3fea..72e62c405e 100644 --- a/Src/FluentAssertions/Common/ExpressionExtensions.cs +++ b/Src/FluentAssertions/Common/ExpressionExtensions.cs @@ -84,7 +84,9 @@ public static MemberPath GetMemberPath( case ExpressionType.Call: var methodCallExpression = (MethodCallExpression)node; - if (methodCallExpression.Method.Name != "get_Item" || methodCallExpression.Arguments.Count != 1 || methodCallExpression.Arguments[0] is not ConstantExpression) + + if (methodCallExpression.Method.Name != "get_Item" || methodCallExpression.Arguments.Count != 1 || + methodCallExpression.Arguments[0] is not ConstantExpression) { throw new ArgumentException(GetUnsupportedExpressionMessage(expression.Body), nameof(expression)); } @@ -153,7 +155,9 @@ public static void ValidateMemberPath( case ExpressionType.Call: var methodCallExpression = (MethodCallExpression)node; - if (methodCallExpression.Method.Name != "get_Item" || methodCallExpression.Arguments.Count != 1 || methodCallExpression.Arguments[0] is not ConstantExpression) + + if (methodCallExpression.Method.Name != "get_Item" || methodCallExpression.Arguments.Count != 1 || + methodCallExpression.Arguments[0] is not ConstantExpression) { throw new ArgumentException(GetUnsupportedExpressionMessage(expression.Body), nameof(expression)); } diff --git a/Src/FluentAssertions/Common/FullFrameworkReflector.cs b/Src/FluentAssertions/Common/FullFrameworkReflector.cs index d4d43d1877..6f4f5d58d5 100644 --- a/Src/FluentAssertions/Common/FullFrameworkReflector.cs +++ b/Src/FluentAssertions/Common/FullFrameworkReflector.cs @@ -20,17 +20,19 @@ private static bool IsRelevant(Assembly ass) { string assemblyName = ass.GetName().Name; - return !assemblyName.StartsWith("microsoft.", StringComparison.OrdinalIgnoreCase) && - !assemblyName.StartsWith("xunit", StringComparison.OrdinalIgnoreCase) && - !assemblyName.StartsWith("jetbrains.", StringComparison.OrdinalIgnoreCase) && - !assemblyName.StartsWith("system", StringComparison.OrdinalIgnoreCase) && - !assemblyName.StartsWith("mscorlib", StringComparison.OrdinalIgnoreCase) && - !assemblyName.StartsWith("newtonsoft", StringComparison.OrdinalIgnoreCase); + return + !assemblyName.StartsWith("microsoft.", StringComparison.OrdinalIgnoreCase) && + !assemblyName.StartsWith("xunit", StringComparison.OrdinalIgnoreCase) && + !assemblyName.StartsWith("jetbrains.", StringComparison.OrdinalIgnoreCase) && + !assemblyName.StartsWith("system", StringComparison.OrdinalIgnoreCase) && + !assemblyName.StartsWith("mscorlib", StringComparison.OrdinalIgnoreCase) && + !assemblyName.StartsWith("newtonsoft", StringComparison.OrdinalIgnoreCase); } private static bool IsDynamic(Assembly assembly) { - return assembly.GetType().FullName is "System.Reflection.Emit.AssemblyBuilder" or "System.Reflection.Emit.InternalAssemblyBuilder"; + return assembly.GetType().FullName is "System.Reflection.Emit.AssemblyBuilder" + or "System.Reflection.Emit.InternalAssemblyBuilder"; } private static IEnumerable GetExportedTypes(Assembly assembly) diff --git a/Src/FluentAssertions/Common/Guard.cs b/Src/FluentAssertions/Common/Guard.cs index 6404db1ad0..43b5a23c8f 100644 --- a/Src/FluentAssertions/Common/Guard.cs +++ b/Src/FluentAssertions/Common/Guard.cs @@ -7,7 +7,9 @@ namespace FluentAssertions.Common; internal static class Guard { - public static void ThrowIfArgumentIsNull([ValidatedNotNull] T obj, [CallerArgumentExpression(nameof(obj))] string paramName = "") + public static void ThrowIfArgumentIsNull([ValidatedNotNull] T obj, + [CallerArgumentExpression(nameof(obj))] + string paramName = "") { if (obj is null) { @@ -23,7 +25,9 @@ public static void ThrowIfArgumentIsNull([ValidatedNotNull] T obj, string par } } - public static void ThrowIfArgumentIsNullOrEmpty([ValidatedNotNull] string str, [CallerArgumentExpression(nameof(str))] string paramName = "") + public static void ThrowIfArgumentIsNullOrEmpty([ValidatedNotNull] string str, + [CallerArgumentExpression(nameof(str))] + string paramName = "") { if (string.IsNullOrEmpty(str)) { @@ -50,7 +54,9 @@ public static void ThrowIfArgumentIsOutOfRange(T value, [CallerArgumentExpres } } - public static void ThrowIfArgumentContainsNull(IEnumerable values, [CallerArgumentExpression(nameof(values))] string paramName = "") + public static void ThrowIfArgumentContainsNull(IEnumerable values, + [CallerArgumentExpression(nameof(values))] + string paramName = "") { if (values.Any(t => t is null)) { @@ -74,7 +80,9 @@ public static void ThrowIfArgumentIsEmpty(string str, string paramName, string m } } - public static void ThrowIfArgumentIsNegative(TimeSpan timeSpan, [CallerArgumentExpression(nameof(timeSpan))] string paramName = "") + public static void ThrowIfArgumentIsNegative(TimeSpan timeSpan, + [CallerArgumentExpression(nameof(timeSpan))] + string paramName = "") { if (timeSpan < TimeSpan.Zero) { diff --git a/Src/FluentAssertions/Common/ICollectionWrapper.cs b/Src/FluentAssertions/Common/ICollectionWrapper.cs index 85cd492cc0..a4027e9746 100644 --- a/Src/FluentAssertions/Common/ICollectionWrapper.cs +++ b/Src/FluentAssertions/Common/ICollectionWrapper.cs @@ -1,15 +1,14 @@ using System.Collections; -namespace FluentAssertions.Common +namespace FluentAssertions.Common; + +/// +/// Used to provide access to the underlying for an object that wraps an underlying +/// collection. +/// +/// Collection type. +public interface ICollectionWrapper + where TCollection : ICollection { - /// - /// Used to provide access to the underlying for an object that wraps an underlying - /// collection. - /// - /// Collection type. - public interface ICollectionWrapper - where TCollection : ICollection - { - TCollection UnderlyingCollection { get; } - } + TCollection UnderlyingCollection { get; } } diff --git a/Src/FluentAssertions/Common/IntegerExtensions.cs b/Src/FluentAssertions/Common/IntegerExtensions.cs index 65cd1e47c5..3e742bfeba 100644 --- a/Src/FluentAssertions/Common/IntegerExtensions.cs +++ b/Src/FluentAssertions/Common/IntegerExtensions.cs @@ -4,5 +4,5 @@ internal static class IntegerExtensions { public static string Times(this int count) => count == 1 ? "1 time" : $"{count} times"; - internal static bool IsConsecutiveTo(this int startNumber, int endNumber) => endNumber == startNumber + 1; + internal static bool IsConsecutiveTo(this int startNumber, int endNumber) => endNumber == (startNumber + 1); } diff --git a/Src/FluentAssertions/Common/MemberPath.cs b/Src/FluentAssertions/Common/MemberPath.cs index 19542bb153..ada5073437 100644 --- a/Src/FluentAssertions/Common/MemberPath.cs +++ b/Src/FluentAssertions/Common/MemberPath.cs @@ -59,7 +59,7 @@ public bool IsParentOrChildOf(MemberPath candidate) public bool IsSameAs(MemberPath candidate) { - if ((declaringType == candidate.declaringType) || declaringType?.IsAssignableFrom(candidate.reflectedType) == true) + if (declaringType == candidate.declaringType || declaringType?.IsAssignableFrom(candidate.reflectedType) == true) { string[] candidateSegments = candidate.Segments; @@ -74,7 +74,7 @@ private bool IsParentOf(MemberPath candidate) string[] candidateSegments = candidate.Segments; return candidateSegments.Length > Segments.Length && - candidateSegments.Take(Segments.Length).SequenceEqual(Segments, MemberPathSegmentEqualityComparer); + candidateSegments.Take(Segments.Length).SequenceEqual(Segments, MemberPathSegmentEqualityComparer); } private bool IsChildOf(MemberPath candidate) @@ -82,8 +82,8 @@ private bool IsChildOf(MemberPath candidate) string[] candidateSegments = candidate.Segments; return candidateSegments.Length < Segments.Length - && candidateSegments.SequenceEqual(Segments.Take(candidateSegments.Length), - MemberPathSegmentEqualityComparer); + && candidateSegments.SequenceEqual(Segments.Take(candidateSegments.Length), + MemberPathSegmentEqualityComparer); } public MemberPath AsParentCollectionOf(MemberPath nextPath) @@ -103,7 +103,7 @@ public bool IsEquivalentTo(string path) public bool HasSameParentAs(MemberPath path) { return Segments.Length == path.Segments.Length - && GetParentSegments().SequenceEqual(path.GetParentSegments(), MemberPathSegmentEqualityComparer); + && GetParentSegments().SequenceEqual(path.GetParentSegments(), MemberPathSegmentEqualityComparer); } private IEnumerable GetParentSegments() => Segments.Take(Segments.Length - 1); diff --git a/Src/FluentAssertions/Common/MemberPathSegmentEqualityComparer.cs b/Src/FluentAssertions/Common/MemberPathSegmentEqualityComparer.cs index 677c55b76e..ec2b75d05e 100644 --- a/Src/FluentAssertions/Common/MemberPathSegmentEqualityComparer.cs +++ b/Src/FluentAssertions/Common/MemberPathSegmentEqualityComparer.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Text.RegularExpressions; namespace FluentAssertions.Common; @@ -34,13 +35,13 @@ public bool Equals(string x, string y) return x == y; } - private static bool IsIndexQualifier(string segment) - => segment == AnyIndexQualifier || IndexQualifierRegex.IsMatch(segment); + private static bool IsIndexQualifier(string segment) => + segment == AnyIndexQualifier || IndexQualifierRegex.IsMatch(segment); public int GetHashCode(string obj) { #if NETCOREAPP2_1_OR_GREATER - return obj.GetHashCode(System.StringComparison.Ordinal); + return obj.GetHashCode(StringComparison.Ordinal); #else return obj.GetHashCode(); #endif diff --git a/Src/FluentAssertions/Common/MethodInfoExtensions.cs b/Src/FluentAssertions/Common/MethodInfoExtensions.cs index 8066c65027..1c2fb67eac 100644 --- a/Src/FluentAssertions/Common/MethodInfoExtensions.cs +++ b/Src/FluentAssertions/Common/MethodInfoExtensions.cs @@ -14,14 +14,15 @@ internal static class MethodInfoExtensions /// They are a subset of which can be checked on a type and therefore this mask has to be applied to check only for options. /// private static readonly Lazy ImplementationOptionsMask = - new Lazy(() => Enum.GetValues(typeof(MethodImplOptions)).Cast().Sum(x => x)); + new(() => Enum.GetValues(typeof(MethodImplOptions)).Cast().Sum(x => x)); internal static bool IsAsync(this MethodInfo methodInfo) { return methodInfo.IsDecoratedWith(); } - internal static IEnumerable GetMatchingAttributes(this MemberInfo memberInfo, Expression> isMatchingAttributePredicate) + internal static IEnumerable GetMatchingAttributes(this MemberInfo memberInfo, + Expression> isMatchingAttributePredicate) where TAttribute : Attribute { var customAttributes = memberInfo.GetCustomAttributes(inherit: false).ToList(); diff --git a/Src/FluentAssertions/Common/ObjectExtensions.cs b/Src/FluentAssertions/Common/ObjectExtensions.cs index 760c0a8a35..7ba5e3bdcc 100644 --- a/Src/FluentAssertions/Common/ObjectExtensions.cs +++ b/Src/FluentAssertions/Common/ObjectExtensions.cs @@ -23,9 +23,9 @@ public static Func GetComparer() } return (actual, expected) => actual is null - ? expected is null - : expected is not null - && (EqualityComparer.Default.Equals(actual, expected) || CompareNumerics(actual, expected)); + ? expected is null + : expected is not null + && (EqualityComparer.Default.Equals(actual, expected) || CompareNumerics(actual, expected)); } private static bool CompareNumerics(object actual, object expected) @@ -47,7 +47,7 @@ private static bool CanConvert(object source, object target, Type sourceType, Ty var converted = source.ConvertTo(targetType); return source.Equals(converted.ConvertTo(sourceType)) - && converted.Equals(target); + && converted.Equals(target); } catch { diff --git a/Src/FluentAssertions/Common/ReadOnlyNonGenericCollectionWrapper.cs b/Src/FluentAssertions/Common/ReadOnlyNonGenericCollectionWrapper.cs index c7b76cd2af..878eacda7f 100644 --- a/Src/FluentAssertions/Common/ReadOnlyNonGenericCollectionWrapper.cs +++ b/Src/FluentAssertions/Common/ReadOnlyNonGenericCollectionWrapper.cs @@ -11,25 +11,25 @@ internal static class ReadOnlyNonGenericCollectionWrapper public static ReadOnlyNonGenericCollectionWrapper Create(DataTableCollection collection) { return - (collection != null) - ? new ReadOnlyNonGenericCollectionWrapper(collection) - : null; + collection != null + ? new ReadOnlyNonGenericCollectionWrapper(collection) + : null; } public static ReadOnlyNonGenericCollectionWrapper Create(DataColumnCollection collection) { return - (collection != null) - ? new ReadOnlyNonGenericCollectionWrapper(collection) - : null; + collection != null + ? new ReadOnlyNonGenericCollectionWrapper(collection) + : null; } public static ReadOnlyNonGenericCollectionWrapper Create(DataRowCollection collection) { return - (collection != null) - ? new ReadOnlyNonGenericCollectionWrapper(collection) - : null; + collection != null + ? new ReadOnlyNonGenericCollectionWrapper(collection) + : null; } } diff --git a/Src/FluentAssertions/Common/StringExtensions.cs b/Src/FluentAssertions/Common/StringExtensions.cs index 89e4fc23eb..162a093c91 100644 --- a/Src/FluentAssertions/Common/StringExtensions.cs +++ b/Src/FluentAssertions/Common/StringExtensions.cs @@ -17,7 +17,7 @@ public static int IndexOfFirstMismatch(this string value, string expected, Strin for (int index = 0; index < value.Length; index++) { - if ((index >= expected.Length) || !comparer(value[index], expected[index])) + if (index >= expected.Length || !comparer(value[index], expected[index])) { return index; } @@ -28,7 +28,7 @@ public static int IndexOfFirstMismatch(this string value, string expected, Strin private static Func GetCharComparer(StringComparison stringComparison) => stringComparison == StringComparison.Ordinal - ? ((x, y) => x == y) + ? (x, y) => x == y : (x, y) => char.ToUpperInvariant(x) == char.ToUpperInvariant(y); /// @@ -80,7 +80,7 @@ public static string Combine(this string @this, string other, string separator = { if (@this.Length == 0) { - return (other.Length != 0) ? other : string.Empty; + return other.Length != 0 ? other : string.Empty; } if (other.Length == 0) @@ -124,8 +124,8 @@ public static string IndentLines(this string @this) public static string RemoveNewLines(this string @this) { return @this.Replace("\n", string.Empty, StringComparison.Ordinal) - .Replace("\r", string.Empty, StringComparison.Ordinal) - .Replace("\\r\\n", string.Empty, StringComparison.Ordinal); + .Replace("\r", string.Empty, StringComparison.Ordinal) + .Replace("\\r\\n", string.Empty, StringComparison.Ordinal); } /// diff --git a/Src/FluentAssertions/Common/TimeOnlyExtensions.cs b/Src/FluentAssertions/Common/TimeOnlyExtensions.cs index ca57f963bd..bbb77fc057 100644 --- a/Src/FluentAssertions/Common/TimeOnlyExtensions.cs +++ b/Src/FluentAssertions/Common/TimeOnlyExtensions.cs @@ -1,5 +1,4 @@ #if NET6_0_OR_GREATER - using System; namespace FluentAssertions.Common; diff --git a/Src/FluentAssertions/Common/TypeExtensions.cs b/Src/FluentAssertions/Common/TypeExtensions.cs index dd3d5fa29e..3da8b976b0 100644 --- a/Src/FluentAssertions/Common/TypeExtensions.cs +++ b/Src/FluentAssertions/Common/TypeExtensions.cs @@ -23,8 +23,12 @@ internal static class TypeExtensions private static readonly ConcurrentDictionary HasValueSemanticsCache = new(); private static readonly ConcurrentDictionary TypeIsRecordCache = new(); - private static readonly ConcurrentDictionary<(Type Type, MemberVisibility Visibility), IEnumerable> NonPrivatePropertiesCache = new(); - private static readonly ConcurrentDictionary<(Type Type, MemberVisibility Visibility), IEnumerable> NonPrivateFieldsCache = new(); + + private static readonly ConcurrentDictionary<(Type Type, MemberVisibility Visibility), IEnumerable> + NonPrivatePropertiesCache = new(); + + private static readonly ConcurrentDictionary<(Type Type, MemberVisibility Visibility), IEnumerable> + NonPrivateFieldsCache = new(); public static bool IsDecoratedWith(this Type type) where TAttribute : Attribute @@ -142,7 +146,7 @@ public static bool IsEquivalentTo(this IMember property, IMember otherProperty) { return (property.DeclaringType.IsSameOrInherits(otherProperty.DeclaringType) || otherProperty.DeclaringType.IsSameOrInherits(property.DeclaringType)) && - property.Name == otherProperty.Name; + property.Name == otherProperty.Name; } /// @@ -157,6 +161,7 @@ public static Type[] GetClosedGenericInterfaces(this Type type, Type openGeneric } Type[] interfaces = type.GetInterfaces(); + return interfaces .Where(t => t.IsGenericType && t.GetGenericTypeDefinition() == openGenericType) @@ -169,7 +174,7 @@ public static bool OverridesEquals(this Type type) .GetMethod("Equals", new[] { typeof(object) }); return method is not null - && method.GetBaseDefinition().DeclaringType != method.DeclaringType; + && method.GetBaseDefinition().DeclaringType != method.DeclaringType; } /// @@ -245,7 +250,7 @@ private static IEnumerable GetPropertiesFromHierarchy(Type typeToR return type .GetProperties(AllInstanceMembersFlag | BindingFlags.DeclaredOnly) .Where(property => property.GetMethod?.IsPrivate == false) - .Where(property => includeInternals || (property.GetMethod is { IsAssembly: false, IsFamilyOrAssembly: false })) + .Where(property => includeInternals || property.GetMethod is { IsAssembly: false, IsFamilyOrAssembly: false }) .ToArray(); }); } @@ -293,7 +298,8 @@ private static IEnumerable GetMembersFromHierarchy( } } - private static List GetInterfaceMembers(Type typeToReflect, Func> getMembers) + private static List GetInterfaceMembers(Type typeToReflect, + Func> getMembers) where TMemberInfo : MemberInfo { List members = new(); @@ -306,6 +312,7 @@ private static List GetInterfaceMembers(Type typeToRef while (queue.Count > 0) { Type subType = queue.Dequeue(); + foreach (Type subInterface in subType.GetInterfaces()) { if (considered.Contains(subInterface)) @@ -327,7 +334,8 @@ private static List GetInterfaceMembers(Type typeToRef return members; } - private static List GetClassMembers(Type typeToReflect, Func> getMembers) + private static List GetClassMembers(Type typeToReflect, + Func> getMembers) where TMemberInfo : MemberInfo { List members = new(); @@ -411,6 +419,7 @@ public static PropertyInfo FindPropertyByName(this Type type, string propertyNam public static bool HasExplicitlyImplementedProperty(this Type type, Type interfaceType, string propertyName) { bool hasGetter = type.HasParameterlessMethod($"{interfaceType.FullName}.get_{propertyName}"); + bool hasSetter = type.GetMethods(AllStaticAndInstanceMembersFlag) .SingleOrDefault(m => m.Name == $"{interfaceType.FullName}.set_{propertyName}" && @@ -494,8 +503,8 @@ public static bool IsDerivedFromOpenGeneric(this Type type, Type definition) // check subject and its base types against definition for (Type baseType = type; - baseType is not null; - baseType = baseType.BaseType) + baseType is not null; + baseType = baseType.BaseType) { if (baseType.IsGenericType && baseType.GetGenericTypeDefinition() == definition) { @@ -509,8 +518,8 @@ public static bool IsDerivedFromOpenGeneric(this Type type, Type definition) public static bool IsUnderNamespace(this Type type, string @namespace) { return IsGlobalNamespace() - || IsExactNamespace() - || IsParentNamespace(); + || IsExactNamespace() + || IsParentNamespace(); bool IsGlobalNamespace() => @namespace is null; bool IsExactNamespace() => IsNamespacePrefix() && type.Namespace.Length == @namespace.Length; @@ -521,7 +530,7 @@ public static bool IsUnderNamespace(this Type type, string @namespace) public static bool IsSameOrInherits(this Type actualType, Type expectedType) { return actualType == expectedType || - expectedType.IsAssignableFrom(actualType); + expectedType.IsAssignableFrom(actualType); } public static MethodInfo GetExplicitConversionOperator(this Type type, Type sourceType, Type targetType) @@ -558,22 +567,23 @@ private static bool IsTuple(this Type type) return typeof(ITuple).IsAssignableFrom(type); #else Type openType = type.GetGenericTypeDefinition(); + return openType == typeof(ValueTuple<>) - || openType == typeof(ValueTuple<,>) - || openType == typeof(ValueTuple<,,>) - || openType == typeof(ValueTuple<,,,>) - || openType == typeof(ValueTuple<,,,,>) - || openType == typeof(ValueTuple<,,,,,>) - || openType == typeof(ValueTuple<,,,,,,>) - || (openType == typeof(ValueTuple<,,,,,,,>) && IsTuple(type.GetGenericArguments()[7])) - || openType == typeof(Tuple<>) - || openType == typeof(Tuple<,>) - || openType == typeof(Tuple<,,>) - || openType == typeof(Tuple<,,,>) - || openType == typeof(Tuple<,,,,>) - || openType == typeof(Tuple<,,,,,>) - || openType == typeof(Tuple<,,,,,,>) - || (openType == typeof(Tuple<,,,,,,,>) && IsTuple(type.GetGenericArguments()[7])); + || openType == typeof(ValueTuple<,>) + || openType == typeof(ValueTuple<,,>) + || openType == typeof(ValueTuple<,,,>) + || openType == typeof(ValueTuple<,,,,>) + || openType == typeof(ValueTuple<,,,,,>) + || openType == typeof(ValueTuple<,,,,,,>) + || (openType == typeof(ValueTuple<,,,,,,,>) && IsTuple(type.GetGenericArguments()[7])) + || openType == typeof(Tuple<>) + || openType == typeof(Tuple<,>) + || openType == typeof(Tuple<,,>) + || openType == typeof(Tuple<,,,>) + || openType == typeof(Tuple<,,,,>) + || openType == typeof(Tuple<,,,,,>) + || openType == typeof(Tuple<,,,,,,>) + || (openType == typeof(Tuple<,,,,,,,>) && IsTuple(type.GetGenericArguments()[7])); #endif } @@ -600,8 +610,8 @@ public static bool IsRecord(this Type type) private static bool IsRecordClass(this Type type) { return type.GetMethod("$", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) is { } && - type.GetProperty("EqualityContract", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)? - .GetMethod?.IsDecoratedWith() == true; + type.GetProperty("EqualityContract", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)? + .GetMethod?.IsDecoratedWith() == true; } private static bool IsRecordStruct(this Type type) @@ -610,9 +620,11 @@ private static bool IsRecordStruct(this Type type) // recognizing record structs from metadata is an open point. The following check is based on common sense // and heuristic testing, apparently giving good results but not supported by official documentation. return type.BaseType == typeof(ValueType) && - type.GetMethod("PrintMembers", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, new[] { typeof(StringBuilder) }, null) is { } && - type.GetMethod("op_Equality", BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly, null, new[] { type, type }, null)? - .IsDecoratedWith() == true; + type.GetMethod("PrintMembers", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, + new[] { typeof(StringBuilder) }, null) is { } && + type.GetMethod("op_Equality", BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly, null, + new[] { type, type }, null)? + .IsDecoratedWith() == true; } private static bool IsKeyValuePair(Type type) diff --git a/Src/FluentAssertions/CustomAssertionAttribute.cs b/Src/FluentAssertions/CustomAssertionAttribute.cs index 6030e5d8b5..028e151bcb 100644 --- a/Src/FluentAssertions/CustomAssertionAttribute.cs +++ b/Src/FluentAssertions/CustomAssertionAttribute.cs @@ -6,7 +6,7 @@ namespace FluentAssertions; /// Marks a method as an extension to Fluent Assertions that either uses the built-in assertions /// internally, or directly uses the Execute.Assertion. /// -[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Method)] public class CustomAssertionAttribute : Attribute { } diff --git a/Src/FluentAssertions/Data/DataColumnAssertions.cs b/Src/FluentAssertions/Data/DataColumnAssertions.cs index e28b433e50..1a2cbfe22a 100644 --- a/Src/FluentAssertions/Data/DataColumnAssertions.cs +++ b/Src/FluentAssertions/Data/DataColumnAssertions.cs @@ -1,7 +1,6 @@ using System; using System.Data; using System.Diagnostics; - using FluentAssertions.Common; using FluentAssertions.Equivalency; using FluentAssertions.Execution; @@ -54,7 +53,8 @@ public DataColumnAssertions(DataColumn dataColumn) /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint BeEquivalentTo(DataColumn expectation, string because = "", params object[] becauseArgs) + public AndConstraint BeEquivalentTo(DataColumn expectation, string because = "", + params object[] becauseArgs) { return BeEquivalentTo( expectation, @@ -110,17 +110,22 @@ public AndConstraint BeEquivalentTo(DataColumn expectation /// Zero or more objects to format using the placeholders in . /// /// is . - public AndConstraint BeEquivalentTo(DataColumn expectation, Func, IDataEquivalencyAssertionOptions> config, string because = "", params object[] becauseArgs) + public AndConstraint BeEquivalentTo(DataColumn expectation, + Func, IDataEquivalencyAssertionOptions> config, + string because = "", params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(config); - IDataEquivalencyAssertionOptions options = config(AssertionOptions.CloneDefaults>(e => new(e))); + IDataEquivalencyAssertionOptions options = + config(AssertionOptions.CloneDefaults>(e => + new DataEquivalencyAssertionOptions(e))); - var context = new EquivalencyValidationContext(Node.From(() => AssertionScope.Current.CallerIdentity), options) - { - Reason = new Reason(because, becauseArgs), - TraceWriter = options.TraceWriter - }; + var context = + new EquivalencyValidationContext(Node.From(() => AssertionScope.Current.CallerIdentity), options) + { + Reason = new Reason(because, becauseArgs), + TraceWriter = options.TraceWriter + }; var comparands = new Comparands { diff --git a/Src/FluentAssertions/Data/DataEquivalencyAssertionOptions.cs b/Src/FluentAssertions/Data/DataEquivalencyAssertionOptions.cs index 4e03245194..b49c7d75ec 100644 --- a/Src/FluentAssertions/Data/DataEquivalencyAssertionOptions.cs +++ b/Src/FluentAssertions/Data/DataEquivalencyAssertionOptions.cs @@ -3,7 +3,6 @@ using System.Data; using System.Linq.Expressions; using System.Reflection; - using FluentAssertions.Equivalency; namespace FluentAssertions.Data; @@ -14,18 +13,13 @@ internal class DataEquivalencyAssertionOptions : EquivalencyAssertionOptions< private readonly HashSet excludeColumnNames = new(); private readonly Dictionary> excludeColumnNamesByTableName = new(); - private bool allowMismatchedTypes; - private bool ignoreUnmatchedColumns; - private RowMatchMode rowMatchMode; - private bool excludeOriginalData; - - public bool AllowMismatchedTypes => allowMismatchedTypes; + public bool AllowMismatchedTypes { get; private set; } - public bool IgnoreUnmatchedColumns => ignoreUnmatchedColumns; + public bool IgnoreUnmatchedColumns { get; private set; } - public bool ExcludeOriginalData => excludeOriginalData; + public bool ExcludeOriginalData { get; private set; } - public RowMatchMode RowMatchMode => rowMatchMode; + public RowMatchMode RowMatchMode { get; private set; } public ISet ExcludeTableNames => excludeTableNames; @@ -38,25 +32,25 @@ public DataEquivalencyAssertionOptions(EquivalencyAssertionOptions defaults) public IDataEquivalencyAssertionOptions AllowingMismatchedTypes() { - allowMismatchedTypes = true; + AllowMismatchedTypes = true; return this; } public IDataEquivalencyAssertionOptions IgnoringUnmatchedColumns() { - ignoreUnmatchedColumns = true; + IgnoreUnmatchedColumns = true; return this; } public IDataEquivalencyAssertionOptions UsingRowMatchMode(RowMatchMode rowMatchMode) { - this.rowMatchMode = rowMatchMode; + RowMatchMode = rowMatchMode; return this; } public IDataEquivalencyAssertionOptions ExcludingOriginalData() { - excludeOriginalData = true; + ExcludeOriginalData = true; return this; } @@ -109,7 +103,8 @@ public IDataEquivalencyAssertionOptions ExcludingRelated(Expression(Expression> expression) + private void ExcludeMemberOfRelatedTypeByGeneratedPredicate( + Expression> expression) { Expression> predicate = BuildMemberSelectionPredicate( typeof(TDeclaringType), @@ -118,7 +113,8 @@ private void ExcludeMemberOfRelatedTypeByGeneratedPredicate(Expression> expression) + private void ExcludeMemberOfSubtypeOfRelatedTypeByGeneratedPredicate( + Expression> expression) where TInheritingType : TDeclaringType { Expression> predicate = BuildMemberSelectionPredicate( @@ -130,8 +126,8 @@ private void ExcludeMemberOfSubtypeOfRelatedTypeByGeneratedPredicate> BuildMemberSelectionPredicate(Type relatedSubjectType, MemberInfo referencedMember) + private static Expression> BuildMemberSelectionPredicate(Type relatedSubjectType, + MemberInfo referencedMember) { ParameterExpression predicateMemberInfoArgument = Expression.Parameter(typeof(IMemberInfo)); @@ -260,7 +257,7 @@ public bool ShouldExcludeColumn(DataColumn column) } if (excludeColumnNamesByTableName.TryGetValue(column.Table.TableName, out HashSet excludeColumnsForTable) - && excludeColumnsForTable.Contains(column.ColumnName)) + && excludeColumnsForTable.Contains(column.ColumnName)) { return true; } diff --git a/Src/FluentAssertions/Data/DataRowAssertions.cs b/Src/FluentAssertions/Data/DataRowAssertions.cs index 87e4490f0e..167a4d533a 100644 --- a/Src/FluentAssertions/Data/DataRowAssertions.cs +++ b/Src/FluentAssertions/Data/DataRowAssertions.cs @@ -3,7 +3,6 @@ using System.Data; using System.Diagnostics; using System.Linq; - using FluentAssertions.Common; using FluentAssertions.Equivalency; using FluentAssertions.Execution; @@ -35,7 +34,8 @@ public DataRowAssertions(TDataRow dataRow) /// /// Zero or more objects to format using the placeholders in . /// - public AndWhichConstraint, DataColumn> HaveColumn(string expectedColumnName, string because = "", params object[] becauseArgs) + public AndWhichConstraint, DataColumn> HaveColumn(string expectedColumnName, string because = "", + params object[] becauseArgs) { var subjectColumn = default(DataColumn); @@ -43,13 +43,15 @@ public AndWhichConstraint, DataColumn> HaveColumn(st { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:DataRow} to contain a column named {0}{reason}, but found .", expectedColumnName); + .FailWith("Expected {context:DataRow} to contain a column named {0}{reason}, but found .", + expectedColumnName); } else if (!Subject.Table.Columns.Contains(expectedColumnName)) { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:DataRow} to contain a column named {0}{reason}, but it does not.", expectedColumnName); + .FailWith("Expected {context:DataRow} to contain a column named {0}{reason}, but it does not.", + expectedColumnName); } else { @@ -79,13 +81,16 @@ public AndConstraint> HaveColumns(params string[] ex /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint> HaveColumns(IEnumerable expectedColumnNames, string because = "", params object[] becauseArgs) + public AndConstraint> HaveColumns(IEnumerable expectedColumnNames, string because = "", + params object[] becauseArgs) { if (Subject is null) { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:DataRow} to be in a table containing {0} column(s) with specific names{reason}, but found .", expectedColumnNames.Count()); + .FailWith( + "Expected {context:DataRow} to be in a table containing {0} column(s) with specific names{reason}, but found .", + expectedColumnNames.Count()); } foreach (var expectedColumnName in expectedColumnNames) @@ -93,7 +98,8 @@ public AndConstraint> HaveColumns(IEnumerable>(this); @@ -114,8 +120,7 @@ public AndConstraint> HaveColumns(IEnumerable objects must be of the same type; if two objects /// are equivalent in all ways, except that one is part of a typed and is of a subclass /// of , then by default, they will not be considered equivalent. This can be overridden - /// with the - /// overload. + /// by using the overload that takes . /// /// A with the expected configuration. /// @@ -125,7 +130,8 @@ public AndConstraint> HaveColumns(IEnumerable /// Zero or more objects to format using the placeholders in . /// - public AndConstraint> BeEquivalentTo(DataRow expectation, string because = "", params object[] becauseArgs) + public AndConstraint> BeEquivalentTo(DataRow expectation, string because = "", + params object[] becauseArgs) { return BeEquivalentTo( expectation, @@ -175,11 +181,15 @@ public AndConstraint> BeEquivalentTo(DataRow expecta /// Zero or more objects to format using the placeholders in . /// /// is . - public AndConstraint> BeEquivalentTo(DataRow expectation, Func, IDataEquivalencyAssertionOptions> config, string because = "", params object[] becauseArgs) + public AndConstraint> BeEquivalentTo(DataRow expectation, + Func, IDataEquivalencyAssertionOptions> config, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(config); - IDataEquivalencyAssertionOptions options = config(AssertionOptions.CloneDefaults>(e => new(e))); + IDataEquivalencyAssertionOptions options = + config(AssertionOptions.CloneDefaults>(e => + new DataEquivalencyAssertionOptions(e))); var context = new EquivalencyValidationContext(Node.From(() => AssertionScope.Current.CallerIdentity), options) { diff --git a/Src/FluentAssertions/Data/DataSetAssertions.cs b/Src/FluentAssertions/Data/DataSetAssertions.cs index 86884f6b4b..c2e2466458 100644 --- a/Src/FluentAssertions/Data/DataSetAssertions.cs +++ b/Src/FluentAssertions/Data/DataSetAssertions.cs @@ -3,7 +3,6 @@ using System.Data; using System.Diagnostics; using System.Linq; - using FluentAssertions.Common; using FluentAssertions.Equivalency; using FluentAssertions.Execution; @@ -35,7 +34,8 @@ public DataSetAssertions(TDataSet dataSet) /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint> HaveTableCount(int expected, string because = "", params object[] becauseArgs) + public AndConstraint> HaveTableCount(int expected, string because = "", + params object[] becauseArgs) { if (Subject is null) { @@ -49,7 +49,8 @@ public AndConstraint> HaveTableCount(int expected, s Execute.Assertion .ForCondition(actualCount == expected) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:DataSet} to contain exactly {0} table(s){reason}, but found {1}.", expected, actualCount); + .FailWith("Expected {context:DataSet} to contain exactly {0} table(s){reason}, but found {1}.", expected, + actualCount); return new AndConstraint>(this); } @@ -65,7 +66,8 @@ public AndConstraint> HaveTableCount(int expected, s /// /// Zero or more objects to format using the placeholders in . /// - public AndWhichConstraint, DataTable> HaveTable(string expectedTableName, string because = "", params object[] becauseArgs) + public AndWhichConstraint, DataTable> HaveTable(string expectedTableName, string because = "", + params object[] becauseArgs) { var subjectTable = default(DataTable); @@ -73,7 +75,8 @@ public AndWhichConstraint, DataTable> HaveTable(stri { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:DataSet} to contain a table named {0}{reason}, but found .", expectedTableName); + .FailWith("Expected {context:DataSet} to contain a table named {0}{reason}, but found .", + expectedTableName); } else if (!Subject.Tables.Contains(expectedTableName)) { @@ -109,13 +112,15 @@ public AndConstraint> HaveTables(params string[] exp /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint> HaveTables(IEnumerable expectedTableNames, string because = "", params object[] becauseArgs) + public AndConstraint> HaveTables(IEnumerable expectedTableNames, string because = "", + params object[] becauseArgs) { if (Subject is null) { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:DataSet} to contain {0} table(s) with specific names{reason}, but found .", expectedTableNames.Count()); + .FailWith("Expected {context:DataSet} to contain {0} table(s) with specific names{reason}, but found .", + expectedTableNames.Count()); } foreach (var expectedTableName in expectedTableNames) @@ -151,9 +156,8 @@ public AndConstraint> HaveTables(IEnumerable /// The objects must be of the same type; if two objects /// are equivalent in all ways, except that one is a custom subclass of (e.g. to provide /// typed accessors for values contained by the ), then by default, - /// they will not be considered equivalent. This can be overridden with the - /// - /// overload. + /// they will not be considered equivalent. This can be overridden by using the overload that takes + /// . /// /// A with the expected configuration. /// @@ -163,7 +167,8 @@ public AndConstraint> HaveTables(IEnumerable /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint> BeEquivalentTo(DataSet expectation, string because = "", params object[] becauseArgs) + public AndConstraint> BeEquivalentTo(DataSet expectation, string because = "", + params object[] becauseArgs) { return BeEquivalentTo( expectation, @@ -227,11 +232,15 @@ public AndConstraint> BeEquivalentTo(DataSet expecta /// Zero or more objects to format using the placeholders in . /// /// is . - public AndConstraint> BeEquivalentTo(DataSet expectation, Func, IDataEquivalencyAssertionOptions> config, string because = "", params object[] becauseArgs) + public AndConstraint> BeEquivalentTo(DataSet expectation, + Func, IDataEquivalencyAssertionOptions> config, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(config); - IDataEquivalencyAssertionOptions options = config(AssertionOptions.CloneDefaults>(e => new(e))); + IDataEquivalencyAssertionOptions options = + config(AssertionOptions.CloneDefaults>(e => + new DataEquivalencyAssertionOptions(e))); var comparands = new Comparands { diff --git a/Src/FluentAssertions/Data/DataTableAssertions.cs b/Src/FluentAssertions/Data/DataTableAssertions.cs index 10e942e2ce..2c1916b230 100644 --- a/Src/FluentAssertions/Data/DataTableAssertions.cs +++ b/Src/FluentAssertions/Data/DataTableAssertions.cs @@ -3,7 +3,6 @@ using System.Data; using System.Diagnostics; using System.Linq; - using FluentAssertions.Common; using FluentAssertions.Equivalency; using FluentAssertions.Execution; @@ -35,7 +34,8 @@ public DataTableAssertions(TDataTable dataTable) /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint> HaveRowCount(int expected, string because = "", params object[] becauseArgs) + public AndConstraint> HaveRowCount(int expected, string because = "", + params object[] becauseArgs) { if (Subject is null) { @@ -49,7 +49,8 @@ public AndConstraint> HaveRowCount(int expected, Execute.Assertion .ForCondition(actualCount == expected) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:DataTable} to contain exactly {0} row(s){reason}, but found {1}.", expected, actualCount); + .FailWith("Expected {context:DataTable} to contain exactly {0} row(s){reason}, but found {1}.", expected, + actualCount); return new AndConstraint>(this); } @@ -65,7 +66,8 @@ public AndConstraint> HaveRowCount(int expected, /// /// Zero or more objects to format using the placeholders in . /// - public AndWhichConstraint, DataColumn> HaveColumn(string expectedColumnName, string because = "", params object[] becauseArgs) + public AndWhichConstraint, DataColumn> HaveColumn(string expectedColumnName, + string because = "", params object[] becauseArgs) { var subjectColumn = default(DataColumn); @@ -73,13 +75,15 @@ public AndWhichConstraint, DataColumn> HaveColum { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:DataTable} to contain a column named {0}{reason}, but found .", expectedColumnName); + .FailWith("Expected {context:DataTable} to contain a column named {0}{reason}, but found .", + expectedColumnName); } else if (!Subject.Columns.Contains(expectedColumnName)) { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:DataTable} to contain a column named {0}{reason}, but it does not.", expectedColumnName); + .FailWith("Expected {context:DataTable} to contain a column named {0}{reason}, but it does not.", + expectedColumnName); } else { @@ -109,13 +113,15 @@ public AndConstraint> HaveColumns(params string[ /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint> HaveColumns(IEnumerable expectedColumnNames, string because = "", params object[] becauseArgs) + public AndConstraint> HaveColumns(IEnumerable expectedColumnNames, + string because = "", params object[] becauseArgs) { if (Subject is null) { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:DataTable} to contain {0} column(s) with specific names{reason}, but found .", expectedColumnNames.Count()); + .FailWith("Expected {context:DataTable} to contain {0} column(s) with specific names{reason}, but found .", + expectedColumnNames.Count()); } foreach (var expectedColumnName in expectedColumnNames) @@ -123,7 +129,8 @@ public AndConstraint> HaveColumns(IEnumerable>(this); @@ -160,9 +167,8 @@ public AndConstraint> HaveColumns(IEnumerable objects must be of the same type; if two objects /// are equivalent in all ways, except that one is a typed that is a subclass - /// of , then by default, they will not be considered equivalent. This can be overridden - /// with the - /// overload. + /// of , then by default, they will not be considered equivalent. This can be overridden by + /// using the overload that takes . /// /// A with the expected configuration. /// @@ -172,7 +178,8 @@ public AndConstraint> HaveColumns(IEnumerable /// Zero or more objects to format using the placeholders in . /// - public AndConstraint> BeEquivalentTo(DataTable expectation, string because = "", params object[] becauseArgs) + public AndConstraint> BeEquivalentTo(DataTable expectation, string because = "", + params object[] becauseArgs) { return BeEquivalentTo( expectation, @@ -240,11 +247,15 @@ public AndConstraint> BeEquivalentTo(DataTable e /// Zero or more objects to format using the placeholders in . /// /// is . - public AndConstraint> BeEquivalentTo(DataTable expectation, Func, IDataEquivalencyAssertionOptions> config, string because = "", params object[] becauseArgs) + public AndConstraint> BeEquivalentTo(DataTable expectation, + Func, IDataEquivalencyAssertionOptions> config, + string because = "", params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(config); - IDataEquivalencyAssertionOptions options = config(AssertionOptions.CloneDefaults>(e => new(e))); + IDataEquivalencyAssertionOptions options = + config(AssertionOptions.CloneDefaults>(e => + new DataEquivalencyAssertionOptions(e))); var context = new EquivalencyValidationContext(Node.From(() => AssertionScope.Current.CallerIdentity), options) { diff --git a/Src/FluentAssertions/Data/IDataEquivalencyAssertionOptions.cs b/Src/FluentAssertions/Data/IDataEquivalencyAssertionOptions.cs index c04a6087db..41ebb4625d 100644 --- a/Src/FluentAssertions/Data/IDataEquivalencyAssertionOptions.cs +++ b/Src/FluentAssertions/Data/IDataEquivalencyAssertionOptions.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Data; using System.Linq.Expressions; - using FluentAssertions.Equivalency; namespace FluentAssertions.Data; diff --git a/Src/FluentAssertions/DataColumnCollectionAssertionExtensions.cs b/Src/FluentAssertions/DataColumnCollectionAssertionExtensions.cs index 72e2e9bfe7..0524cc371e 100644 --- a/Src/FluentAssertions/DataColumnCollectionAssertionExtensions.cs +++ b/Src/FluentAssertions/DataColumnCollectionAssertionExtensions.cs @@ -1,9 +1,6 @@ using System; -using System.Collections.Generic; using System.Data; -using System.Globalization; using System.Linq; - using FluentAssertions.Collections; using FluentAssertions.Common; using FluentAssertions.Execution; @@ -124,7 +121,7 @@ public static AndConstraint> HaveSameCou .ForCondition(subject => subject is not null) .FailWith("the same count as {0}{reason}, but found .", otherCollection) .Then - .Given((subject) => (actual: subject.Count(), expected: otherCollection.Count)) + .Given(subject => (actual: subject.Count(), expected: otherCollection.Count)) .ForCondition(count => count.actual == count.expected) .FailWith("{0} column(s){reason}, but found {1}.", count => count.expected, count => count.actual) .Then @@ -161,7 +158,7 @@ public static AndConstraint> NotHaveSame .ForCondition(subject => subject is not null) .FailWith("the same count as {0}{reason}, but found .", otherCollection) .Then - .Given((subject) => (actual: subject.Count(), expected: otherCollection.Count)) + .Given(subject => (actual: subject.Count(), expected: otherCollection.Count)) .ForCondition(count => count.actual != count.expected) .FailWith("{0} column(s){reason}, but found {1}.", count => count.expected, count => count.actual) .Then diff --git a/Src/FluentAssertions/DataRowAssertionExtensions.cs b/Src/FluentAssertions/DataRowAssertionExtensions.cs index 2b9e389ec5..b48db92509 100644 --- a/Src/FluentAssertions/DataRowAssertionExtensions.cs +++ b/Src/FluentAssertions/DataRowAssertionExtensions.cs @@ -1,8 +1,6 @@ using System.Data; using System.Diagnostics; - using FluentAssertions.Data; - using JetBrains.Annotations; namespace FluentAssertions; diff --git a/Src/FluentAssertions/DataRowCollectionAssertionExtensions.cs b/Src/FluentAssertions/DataRowCollectionAssertionExtensions.cs index b694c4959c..3e5f04df8e 100644 --- a/Src/FluentAssertions/DataRowCollectionAssertionExtensions.cs +++ b/Src/FluentAssertions/DataRowCollectionAssertionExtensions.cs @@ -1,12 +1,8 @@ using System; -using System.Collections.Generic; using System.Data; using System.Linq; - using FluentAssertions.Collections; using FluentAssertions.Common; -using FluentAssertions.Data; -using FluentAssertions.Equivalency; using FluentAssertions.Execution; namespace FluentAssertions; @@ -118,7 +114,7 @@ public static AndConstraint> HaveSameCount( .ForCondition(subject => subject is not null) .FailWith("the same count as {0}{reason}, but found .", otherCollection) .Then - .Given((subject) => (actual: subject.Count(), expected: otherCollection.Count)) + .Given(subject => (actual: subject.Count(), expected: otherCollection.Count)) .ForCondition(count => count.actual == count.expected) .FailWith("{0} row(s){reason}, but found {1}.", count => count.expected, count => count.actual) .Then @@ -154,7 +150,7 @@ public static AndConstraint> NotHaveSameCou .ForCondition(subject => subject is not null) .FailWith("the same count as {0}{reason}, but found .", otherCollection) .Then - .Given((subject) => (actual: subject.Count(), expected: otherCollection.Count)) + .Given(subject => (actual: subject.Count(), expected: otherCollection.Count)) .ForCondition(count => count.actual != count.expected) .FailWith("{0} row(s){reason}, but found {1}.", count => count.expected, count => count.actual) .Then diff --git a/Src/FluentAssertions/DataSetAssertionExtensions.cs b/Src/FluentAssertions/DataSetAssertionExtensions.cs index b2155cdcba..e993ddf88b 100644 --- a/Src/FluentAssertions/DataSetAssertionExtensions.cs +++ b/Src/FluentAssertions/DataSetAssertionExtensions.cs @@ -1,8 +1,6 @@ using System.Data; using System.Diagnostics; - using FluentAssertions.Data; - using JetBrains.Annotations; namespace FluentAssertions; diff --git a/Src/FluentAssertions/DataTableAssertionExtensions.cs b/Src/FluentAssertions/DataTableAssertionExtensions.cs index fd022fc7fb..ee7ea0e191 100644 --- a/Src/FluentAssertions/DataTableAssertionExtensions.cs +++ b/Src/FluentAssertions/DataTableAssertionExtensions.cs @@ -1,8 +1,6 @@ using System.Data; using System.Diagnostics; - using FluentAssertions.Data; - using JetBrains.Annotations; namespace FluentAssertions; diff --git a/Src/FluentAssertions/DataTableCollectionAssertionExtensions.cs b/Src/FluentAssertions/DataTableCollectionAssertionExtensions.cs index 8e508dfbc8..f9c0f7c1b2 100644 --- a/Src/FluentAssertions/DataTableCollectionAssertionExtensions.cs +++ b/Src/FluentAssertions/DataTableCollectionAssertionExtensions.cs @@ -1,7 +1,6 @@ using System; using System.Data; using System.Linq; - using FluentAssertions.Collections; using FluentAssertions.Common; using FluentAssertions.Execution; @@ -153,7 +152,7 @@ public static AndConstraint> HaveSameCoun .ForCondition(subject => subject is not null) .FailWith("the same count as {0}{reason}, but found .", otherCollection) .Then - .Given((subject) => (actual: subject.Count(), expected: otherCollection.Count)) + .Given(subject => (actual: subject.Count(), expected: otherCollection.Count)) .ForCondition(count => count.actual == count.expected) .FailWith("{0} table(s){reason}, but found {1}.", count => count.expected, count => count.actual) .Then @@ -189,7 +188,7 @@ public static AndConstraint> NotHaveSameC .ForCondition(subject => subject is not null) .FailWith("the same count as {0}{reason}, but found .", otherCollection) .Then - .Given((subject) => (actual: subject.Count(), expected: otherCollection.Count)) + .Given(subject => (actual: subject.Count(), expected: otherCollection.Count)) .ForCondition(count => count.actual != count.expected) .FailWith("{0} table(s){reason}, but found {1}.", count => count.expected, count => count.actual) .Then diff --git a/Src/FluentAssertions/Equivalency/Comparands.cs b/Src/FluentAssertions/Equivalency/Comparands.cs index 3d858da082..62c09762c3 100644 --- a/Src/FluentAssertions/Equivalency/Comparands.cs +++ b/Src/FluentAssertions/Equivalency/Comparands.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using FluentAssertions.Common; using static System.FormattableString; @@ -34,7 +33,7 @@ public Type CompileTimeType { get { - return ((compileTimeType != typeof(object)) || Expectation is null) ? compileTimeType : RuntimeType; + return compileTimeType != typeof(object) || Expectation is null ? compileTimeType : RuntimeType; } // SMELL: Do we really need this? Can we replace it by making Comparands generic or take a constructor parameter? diff --git a/Src/FluentAssertions/Equivalency/EquivalencyAssertionOptions.cs b/Src/FluentAssertions/Equivalency/EquivalencyAssertionOptions.cs index b33ed15545..90790e2673 100644 --- a/Src/FluentAssertions/Equivalency/EquivalencyAssertionOptions.cs +++ b/Src/FluentAssertions/Equivalency/EquivalencyAssertionOptions.cs @@ -18,8 +18,8 @@ namespace FluentAssertions.Equivalency; /// /// Represents the run-time type-specific behavior of a structural equivalency assertion. /// -public class EquivalencyAssertionOptions : - SelfReferenceEquivalencyAssertionOptions> +public class EquivalencyAssertionOptions + : SelfReferenceEquivalencyAssertionOptions> { public EquivalencyAssertionOptions() { @@ -43,7 +43,8 @@ public EquivalencyAssertionOptions Excluding(Expression. /// - public NestedExclusionOptionBuilder For(Expression>> expression) + public NestedExclusionOptionBuilder For( + Expression>> expression) { var selectionRule = new ExcludeMemberByPathSelectionRule(expression.GetMemberPath()); AddSelectionRule(selectionRule); diff --git a/Src/FluentAssertions/Equivalency/EquivalencyStep.cs b/Src/FluentAssertions/Equivalency/EquivalencyStep.cs index 9a2aedf89b..ddbbc2f68e 100644 --- a/Src/FluentAssertions/Equivalency/EquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/EquivalencyStep.cs @@ -5,7 +5,8 @@ /// public abstract class EquivalencyStep : IEquivalencyStep { - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { if (!typeof(T).IsAssignableFrom(comparands.GetExpectedType(context.Options))) { @@ -18,5 +19,6 @@ public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationCon /// /// Implements , but only gets called when the expected type matches . /// - protected abstract EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator); + protected abstract EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator); } diff --git a/Src/FluentAssertions/Equivalency/EquivalencyValidator.cs b/Src/FluentAssertions/Equivalency/EquivalencyValidator.cs index d9dbe59023..cc8cf0f89f 100644 --- a/Src/FluentAssertions/Equivalency/EquivalencyValidator.cs +++ b/Src/FluentAssertions/Equivalency/EquivalencyValidator.cs @@ -46,6 +46,7 @@ private static bool ShouldCompareNodesThisDeep(INode currentNode, IEquivalencyAs AssertionScope assertionScope) { bool shouldRecurse = options.AllowInfiniteRecursion || currentNode.Depth < MaxDepth; + if (!shouldRecurse) { assertionScope.FailWith("The maximum recursion depth was reached. "); @@ -66,9 +67,11 @@ private void RunStepsUntilEquivalencyIsProven(Comparands comparands, IEquivalenc using var _ = context.Tracer.WriteBlock(node => node.Description); Func getMessage = step => _ => $"Equivalency was proven by {step.GetType().Name}"; + foreach (IEquivalencyStep step in AssertionOptions.EquivalencyPlan) { var result = step.Handle(comparands, context, this); + if (result == EquivalencyResult.AssertionCompleted) { context.Tracer.WriteLine(getMessage(step)); diff --git a/Src/FluentAssertions/Equivalency/Execution/CollectionMemberAssertionOptionsDecorator.cs b/Src/FluentAssertions/Equivalency/Execution/CollectionMemberAssertionOptionsDecorator.cs index 157f0394b1..93917bb3aa 100644 --- a/Src/FluentAssertions/Equivalency/Execution/CollectionMemberAssertionOptionsDecorator.cs +++ b/Src/FluentAssertions/Equivalency/Execution/CollectionMemberAssertionOptionsDecorator.cs @@ -36,7 +36,8 @@ public OrderingRuleCollection OrderingRules { get { - return new OrderingRuleCollection(inner.OrderingRules.Select(rule => new CollectionMemberOrderingRuleDecorator(rule))); + return new OrderingRuleCollection(inner.OrderingRules.Select(rule => + new CollectionMemberOrderingRuleDecorator(rule))); } } diff --git a/Src/FluentAssertions/Equivalency/Execution/CyclicReferenceDetector.cs b/Src/FluentAssertions/Equivalency/Execution/CyclicReferenceDetector.cs index 210696356f..736ba716bd 100644 --- a/Src/FluentAssertions/Equivalency/Execution/CyclicReferenceDetector.cs +++ b/Src/FluentAssertions/Equivalency/Execution/CyclicReferenceDetector.cs @@ -30,7 +30,7 @@ public bool IsCyclicReference(ObjectReference reference, CyclicReferenceHandling { isCyclic = !observedReferences.Add(reference); - if (isCyclic && (handling == CyclicReferenceHandling.ThrowException)) + if (isCyclic && handling == CyclicReferenceHandling.ThrowException) { AssertionScope.Current .BecauseOf(reason) diff --git a/Src/FluentAssertions/Equivalency/Execution/ObjectReference.cs b/Src/FluentAssertions/Equivalency/Execution/ObjectReference.cs index bca5cb9768..b2a5f94b2a 100644 --- a/Src/FluentAssertions/Equivalency/Execution/ObjectReference.cs +++ b/Src/FluentAssertions/Equivalency/Execution/ObjectReference.cs @@ -39,7 +39,7 @@ public override bool Equals(object obj) private string[] GetPathElements() => pathElements ??= path.ToUpperInvariant().Replace("][", "].[", StringComparison.Ordinal) - .Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); + .Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); private bool IsParentOrChildOf(ObjectReference other) { @@ -49,7 +49,7 @@ private bool IsParentOrChildOf(ObjectReference other) int commonElements = Math.Min(path.Length, otherPath.Length); int longerPathAdditionalElements = Math.Max(path.Length, otherPath.Length) - commonElements; - return (longerPathAdditionalElements > 0) && otherPath.Take(commonElements).SequenceEqual(path.Take(commonElements)); + return longerPathAdditionalElements > 0 && otherPath.Take(commonElements).SequenceEqual(path.Take(commonElements)); } /// diff --git a/Src/FluentAssertions/Equivalency/IEquivalencyAssertionOptions.cs b/Src/FluentAssertions/Equivalency/IEquivalencyAssertionOptions.cs index e37b525c65..b9f49c945e 100644 --- a/Src/FluentAssertions/Equivalency/IEquivalencyAssertionOptions.cs +++ b/Src/FluentAssertions/Equivalency/IEquivalencyAssertionOptions.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.ComponentModel; - using FluentAssertions.Equivalency.Tracing; namespace FluentAssertions.Equivalency; diff --git a/Src/FluentAssertions/Equivalency/IEquivalencyValidationContext.cs b/Src/FluentAssertions/Equivalency/IEquivalencyValidationContext.cs index b9d27efabc..62b4522706 100644 --- a/Src/FluentAssertions/Equivalency/IEquivalencyValidationContext.cs +++ b/Src/FluentAssertions/Equivalency/IEquivalencyValidationContext.cs @@ -1,4 +1,3 @@ -using System; using FluentAssertions.Equivalency.Tracing; using FluentAssertions.Execution; diff --git a/Src/FluentAssertions/Equivalency/IMember.cs b/Src/FluentAssertions/Equivalency/IMember.cs index e02ccaf5b9..3d1cc4e40c 100644 --- a/Src/FluentAssertions/Equivalency/IMember.cs +++ b/Src/FluentAssertions/Equivalency/IMember.cs @@ -1,6 +1,5 @@ using System; using System.ComponentModel; - using FluentAssertions.Common; namespace FluentAssertions.Equivalency; diff --git a/Src/FluentAssertions/Equivalency/Matching/MappedMemberMatchingRule.cs b/Src/FluentAssertions/Equivalency/Matching/MappedMemberMatchingRule.cs index a0eef4fda0..0ea3b698ed 100644 --- a/Src/FluentAssertions/Equivalency/Matching/MappedMemberMatchingRule.cs +++ b/Src/FluentAssertions/Equivalency/Matching/MappedMemberMatchingRule.cs @@ -20,7 +20,7 @@ public MappedMemberMatchingRule(string expectationMemberName, string subjectMemb throw new ArgumentException("The expectation's member name cannot be a nested path"); } - if (Regex.IsMatch(subjectMemberName, $@"[\.\[\]]")) + if (Regex.IsMatch(subjectMemberName, @"[\.\[\]]")) { throw new ArgumentException("The subject's member name cannot be a nested path"); } @@ -36,6 +36,7 @@ public IMember Match(IMember expectedMember, object subject, INode parent, IEqui if (expectedMember.Name == expectationMemberName) { var member = MemberFactory.Find(subject, subjectMemberName, parent); + if (member is null) { throw new ArgumentException( diff --git a/Src/FluentAssertions/Equivalency/Matching/MappedPathMatchingRule.cs b/Src/FluentAssertions/Equivalency/Matching/MappedPathMatchingRule.cs index 08dd6cedaa..9559c48f41 100644 --- a/Src/FluentAssertions/Equivalency/Matching/MappedPathMatchingRule.cs +++ b/Src/FluentAssertions/Equivalency/Matching/MappedPathMatchingRule.cs @@ -23,6 +23,7 @@ public MappedPathMatchingRule(string expectationMemberPath, string subjectMember { Guard.ThrowIfArgumentIsNullOrEmpty(expectationMemberPath, nameof(expectationMemberPath), "A member path cannot be null"); + Guard.ThrowIfArgumentIsNullOrEmpty(subjectMemberPath, nameof(subjectMemberPath), "A member path cannot be null"); @@ -31,7 +32,8 @@ public MappedPathMatchingRule(string expectationMemberPath, string subjectMember if (expectationPath.GetContainsSpecificCollectionIndex() || subjectPath.GetContainsSpecificCollectionIndex()) { - throw new ArgumentException("Mapping properties containing a collection index must use the [] format without specific index."); + throw new ArgumentException( + "Mapping properties containing a collection index must use the [] format without specific index."); } if (!expectationPath.HasSameParentAs(subjectPath)) @@ -43,6 +45,7 @@ public MappedPathMatchingRule(string expectationMemberPath, string subjectMember public IMember Match(IMember expectedMember, object subject, INode parent, IEquivalencyAssertionOptions options) { MemberPath path = expectationPath; + if (expectedMember.RootIsCollection) { path = path.WithCollectionAsRoot(); @@ -51,6 +54,7 @@ public IMember Match(IMember expectedMember, object subject, INode parent, IEqui if (path.IsEquivalentTo(expectedMember.PathAndName)) { var member = MemberFactory.Find(subject, subjectPath.MemberName, parent); + if (member is null) { throw new ArgumentException( diff --git a/Src/FluentAssertions/Equivalency/Matching/MustMatchByNameRule.cs b/Src/FluentAssertions/Equivalency/Matching/MustMatchByNameRule.cs index 272545cc40..87a530358f 100644 --- a/Src/FluentAssertions/Equivalency/Matching/MustMatchByNameRule.cs +++ b/Src/FluentAssertions/Equivalency/Matching/MustMatchByNameRule.cs @@ -16,13 +16,13 @@ public IMember Match(IMember expectedMember, object subject, INode parent, IEqui if (config.IncludedProperties != MemberVisibility.None) { PropertyInfo propertyInfo = subject.GetType().FindProperty(expectedMember.Name); - subjectMember = (propertyInfo is not null) && !propertyInfo.IsIndexer() ? new Property(propertyInfo, parent) : null; + subjectMember = propertyInfo is not null && !propertyInfo.IsIndexer() ? new Property(propertyInfo, parent) : null; } - if ((subjectMember is null) && config.IncludedFields != MemberVisibility.None) + if (subjectMember is null && config.IncludedFields != MemberVisibility.None) { FieldInfo fieldInfo = subject.GetType().FindField(expectedMember.Name); - subjectMember = (fieldInfo is not null) ? new Field(fieldInfo, parent) : null; + subjectMember = fieldInfo is not null ? new Field(fieldInfo, parent) : null; } if ((subjectMember is null || !config.UseRuntimeTyping) && ExpectationImplementsMemberExplicitly(subject, expectedMember)) diff --git a/Src/FluentAssertions/Equivalency/Matching/TryMatchByNameRule.cs b/Src/FluentAssertions/Equivalency/Matching/TryMatchByNameRule.cs index ff3c71e392..6a20dc10bd 100644 --- a/Src/FluentAssertions/Equivalency/Matching/TryMatchByNameRule.cs +++ b/Src/FluentAssertions/Equivalency/Matching/TryMatchByNameRule.cs @@ -11,13 +11,14 @@ internal class TryMatchByNameRule : IMemberMatchingRule public IMember Match(IMember expectedMember, object subject, INode parent, IEquivalencyAssertionOptions config) { PropertyInfo property = subject.GetType().FindProperty(expectedMember.Name); - if ((property is not null) && !property.IsIndexer()) + + if (property is not null && !property.IsIndexer()) { return new Property(property, parent); } FieldInfo field = subject.GetType().FindField(expectedMember.Name); - return (field is not null) ? new Field(field, parent) : null; + return field is not null ? new Field(field, parent) : null; } /// diff --git a/Src/FluentAssertions/Equivalency/MemberFactory.cs b/Src/FluentAssertions/Equivalency/MemberFactory.cs index 28c7ff1608..672e20de3f 100644 --- a/Src/FluentAssertions/Equivalency/MemberFactory.cs +++ b/Src/FluentAssertions/Equivalency/MemberFactory.cs @@ -24,12 +24,13 @@ public static IMember Create(MemberInfo memberInfo, INode parent) internal static IMember Find(object target, string memberName, INode parent) { PropertyInfo property = target.GetType().FindProperty(memberName); - if ((property is not null) && !property.IsIndexer()) + + if (property is not null && !property.IsIndexer()) { return new Property(property, parent); } FieldInfo field = target.GetType().FindField(memberName); - return (field is not null) ? new Field(field, parent) : null; + return field is not null ? new Field(field, parent) : null; } } diff --git a/Src/FluentAssertions/Equivalency/MultiDimensionalArrayEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/MultiDimensionalArrayEquivalencyStep.cs index 67068ac0ba..b7fcd7acb6 100644 --- a/Src/FluentAssertions/Equivalency/MultiDimensionalArrayEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/MultiDimensionalArrayEquivalencyStep.cs @@ -11,7 +11,8 @@ namespace FluentAssertions.Equivalency; /// internal class MultiDimensionalArrayEquivalencyStep : IEquivalencyStep { - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { if (comparands.Expectation is not Array expectationAsArray || expectationAsArray.Rank == 1) { @@ -116,6 +117,7 @@ public int[] GetIndices() var indices = new List(); Digit digit = this; + while (digit is not null) { indices.Add(digit.index); @@ -128,6 +130,7 @@ public int[] GetIndices() public bool Increment() { bool success = nextDigit?.Increment() == true; + if (!success) { if (index < (length - 1)) diff --git a/Src/FluentAssertions/Equivalency/Node.cs b/Src/FluentAssertions/Equivalency/Node.cs index 90d94a3042..c9bb11334d 100644 --- a/Src/FluentAssertions/Equivalency/Node.cs +++ b/Src/FluentAssertions/Equivalency/Node.cs @@ -123,7 +123,7 @@ public override bool Equals(object obj) return true; } - if (obj.GetType() != this.GetType()) + if (obj.GetType() != GetType()) { return false; } diff --git a/Src/FluentAssertions/Equivalency/Ordering/ByteArrayOrderingRule.cs b/Src/FluentAssertions/Equivalency/Ordering/ByteArrayOrderingRule.cs index a0f3e0f130..756ee4b0ba 100644 --- a/Src/FluentAssertions/Equivalency/Ordering/ByteArrayOrderingRule.cs +++ b/Src/FluentAssertions/Equivalency/Ordering/ByteArrayOrderingRule.cs @@ -11,7 +11,9 @@ internal class ByteArrayOrderingRule : IOrderingRule { public OrderStrictness Evaluate(IObjectInfo memberInfo) { - return memberInfo.CompileTimeType.IsSameOrInherits(typeof(IEnumerable)) ? OrderStrictness.Strict : OrderStrictness.Irrelevant; + return memberInfo.CompileTimeType.IsSameOrInherits(typeof(IEnumerable)) + ? OrderStrictness.Strict + : OrderStrictness.Irrelevant; } public override string ToString() diff --git a/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs b/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs index 397fa3f964..a9ffc123df 100644 --- a/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs +++ b/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs @@ -22,6 +22,7 @@ public PathBasedOrderingRule(string path) public OrderStrictness Evaluate(IObjectInfo objectInfo) { string currentPropertyPath = objectInfo.Path; + if (!ContainsIndexingQualifiers(path)) { currentPropertyPath = RemoveInitialIndexQualifier(currentPropertyPath); @@ -49,6 +50,7 @@ private string RemoveInitialIndexQualifier(string sourcePath) if (!indexQualifierRegex.IsMatch(path)) { Match match = indexQualifierRegex.Match(sourcePath); + if (match.Success) { sourcePath = sourcePath.Substring(match.Length); diff --git a/Src/FluentAssertions/Equivalency/Property.cs b/Src/FluentAssertions/Equivalency/Property.cs index 4ef87c21b9..fe43d16e1a 100644 --- a/Src/FluentAssertions/Equivalency/Property.cs +++ b/Src/FluentAssertions/Equivalency/Property.cs @@ -51,10 +51,8 @@ public bool IsBrowsable { get { - if (isBrowsable == null) - { - isBrowsable = propertyInfo.GetCustomAttribute() is not { State: EditorBrowsableState.Never }; - } + isBrowsable ??= + propertyInfo.GetCustomAttribute() is not { State: EditorBrowsableState.Never }; return isBrowsable.Value; } diff --git a/Src/FluentAssertions/Equivalency/Selection/ExcludeNonBrowsableMembersRule.cs b/Src/FluentAssertions/Equivalency/Selection/ExcludeNonBrowsableMembersRule.cs index d7d452e6cf..79ffb0df6c 100644 --- a/Src/FluentAssertions/Equivalency/Selection/ExcludeNonBrowsableMembersRule.cs +++ b/Src/FluentAssertions/Equivalency/Selection/ExcludeNonBrowsableMembersRule.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; namespace FluentAssertions.Equivalency.Selection; @@ -8,7 +7,8 @@ internal class ExcludeNonBrowsableMembersRule : IMemberSelectionRule { public bool IncludesMembers => false; - public IEnumerable SelectMembers(INode currentNode, IEnumerable selectedMembers, MemberSelectionContext context) + public IEnumerable SelectMembers(INode currentNode, IEnumerable selectedMembers, + MemberSelectionContext context) { return selectedMembers.Where(member => member.IsBrowsable).ToList(); } diff --git a/Src/FluentAssertions/Equivalency/Selection/IncludeMemberByPathSelectionRule.cs b/Src/FluentAssertions/Equivalency/Selection/IncludeMemberByPathSelectionRule.cs index ea9f260b81..5a4990623f 100644 --- a/Src/FluentAssertions/Equivalency/Selection/IncludeMemberByPathSelectionRule.cs +++ b/Src/FluentAssertions/Equivalency/Selection/IncludeMemberByPathSelectionRule.cs @@ -19,11 +19,13 @@ public IncludeMemberByPathSelectionRule(MemberPath pathToInclude) public override bool IncludesMembers => true; - protected override void AddOrRemoveMembersFrom(List selectedMembers, INode parent, string parentPath, MemberSelectionContext context) + protected override void AddOrRemoveMembersFrom(List selectedMembers, INode parent, string parentPath, + MemberSelectionContext context) { foreach (MemberInfo memberInfo in context.Type.GetNonPrivateMembers(MemberVisibility.Public | MemberVisibility.Internal)) { var memberPath = new MemberPath(context.Type, memberInfo.DeclaringType, parentPath.Combine(memberInfo.Name)); + if (memberToInclude.IsSameAs(memberPath) || memberToInclude.IsParentOrChildOf(memberPath)) { selectedMembers.Add(MemberFactory.Create(memberInfo, parent)); diff --git a/Src/FluentAssertions/Equivalency/Selection/IncludeMemberByPredicateSelectionRule.cs b/Src/FluentAssertions/Equivalency/Selection/IncludeMemberByPredicateSelectionRule.cs index cec6e18b22..4a10a48ff5 100644 --- a/Src/FluentAssertions/Equivalency/Selection/IncludeMemberByPredicateSelectionRule.cs +++ b/Src/FluentAssertions/Equivalency/Selection/IncludeMemberByPredicateSelectionRule.cs @@ -28,9 +28,11 @@ public IEnumerable SelectMembers(INode currentNode, IEnumerable(selectedMembers); - foreach (MemberInfo memberInfo in currentNode.Type.GetNonPrivateMembers(MemberVisibility.Public | MemberVisibility.Internal)) + foreach (MemberInfo memberInfo in currentNode.Type.GetNonPrivateMembers(MemberVisibility.Public | + MemberVisibility.Internal)) { IMember member = MemberFactory.Create(memberInfo, currentNode); + if (predicate(new MemberToMemberInfoAdapter(member))) { if (!members.Any(p => p.IsEquivalentTo(member))) diff --git a/Src/FluentAssertions/Equivalency/Selection/SelectMemberByPathSelectionRule.cs b/Src/FluentAssertions/Equivalency/Selection/SelectMemberByPathSelectionRule.cs index 8e198b3ae0..ea91c68669 100644 --- a/Src/FluentAssertions/Equivalency/Selection/SelectMemberByPathSelectionRule.cs +++ b/Src/FluentAssertions/Equivalency/Selection/SelectMemberByPathSelectionRule.cs @@ -18,7 +18,7 @@ protected SelectMemberByPathSelectionRule(string selectedPath) protected void SetSelectedPath(string path) { - this.selectedPath = path; + selectedPath = path; } public IEnumerable SelectMembers(INode currentNode, IEnumerable selectedMembers, @@ -51,6 +51,7 @@ private static bool ContainsIndexingQualifiers(string path) private static string RemoveIndexQualifiers(string path) { Match match = new Regex(@"^\[\d+]").Match(path); + if (match.Success) { path = path.Substring(match.Length); diff --git a/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs b/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs index c5a3d540d2..ff627159e4 100644 --- a/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs +++ b/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs @@ -759,8 +759,8 @@ public override string ToString() builder.AppendLine("- Ignoring cyclic references"); } - builder.AppendLine($"- Compare tuples by their properties"); - builder.AppendLine($"- Compare anonymous types by their properties"); + builder.AppendLine("- Compare tuples by their properties"); + builder.AppendLine("- Compare anonymous types by their properties"); if (compareRecordsByValue is true) { diff --git a/Src/FluentAssertions/Equivalency/Steps/AssertionContext.cs b/Src/FluentAssertions/Equivalency/Steps/AssertionContext.cs index 23f7018b38..022255804f 100644 --- a/Src/FluentAssertions/Equivalency/Steps/AssertionContext.cs +++ b/Src/FluentAssertions/Equivalency/Steps/AssertionContext.cs @@ -3,7 +3,7 @@ namespace FluentAssertions.Equivalency.Steps; internal class AssertionContext : IAssertionContext { private AssertionContext(INode currentNode, TSubject subject, TSubject expectation, string because, - object[] becauseArgs) + object[] becauseArgs) { SelectedNode = currentNode; Subject = subject; @@ -24,7 +24,7 @@ private AssertionContext(INode currentNode, TSubject subject, TSubject expectati internal static AssertionContext CreateFrom(Comparands comparands, IEquivalencyValidationContext context) { - return new( + return new AssertionContext( context.CurrentNode, (TSubject)comparands.Subject, (TSubject)comparands.Expectation, diff --git a/Src/FluentAssertions/Equivalency/Steps/AssertionRuleEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/AssertionRuleEquivalencyStep.cs index f2ca8b7f20..4c3609bccd 100644 --- a/Src/FluentAssertions/Equivalency/Steps/AssertionRuleEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/AssertionRuleEquivalencyStep.cs @@ -22,9 +22,11 @@ public AssertionRuleEquivalencyStep( description = predicate.ToString(); } - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { bool success = false; + using (var scope = new AssertionScope()) { // Try without conversion @@ -34,6 +36,7 @@ public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationCon } bool converted = false; + if (!success && context.Options.ConversionSelector.RequiresConversion(comparands, context.CurrentNode)) { // Convert into a child context @@ -46,6 +49,7 @@ public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationCon { // Try again after conversion success = ExecuteAssertion(comparands, context); + if (success) { // If the assertion succeeded after conversion, discard the failures from @@ -75,7 +79,8 @@ private bool ExecuteAssertion(Comparands comparands, IEquivalencyValidationConte bool expectationIsValidType = AssertionScope.Current .ForCondition(expectationIsNull || comparands.Expectation.GetType().IsSameOrInherits(typeof(TSubject))) - .FailWith("Expected " + context.CurrentNode.Description + " from expectation to be a {0}{reason}, but found a {1}.", + .FailWith( + "Expected " + context.CurrentNode.Description + " from expectation to be a {0}{reason}, but found a {1}.", typeof(TSubject), comparands.Expectation?.GetType()); if (subjectIsValidType && expectationIsValidType) diff --git a/Src/FluentAssertions/Equivalency/Steps/AutoConversionStep.cs b/Src/FluentAssertions/Equivalency/Steps/AutoConversionStep.cs index ca4e87e311..51c67b8e80 100644 --- a/Src/FluentAssertions/Equivalency/Steps/AutoConversionStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/AutoConversionStep.cs @@ -13,14 +13,15 @@ namespace FluentAssertions.Equivalency.Steps; /// public class AutoConversionStep : IEquivalencyStep { - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { if (!context.Options.ConversionSelector.RequiresConversion(comparands, context.CurrentNode)) { return EquivalencyResult.ContinueWithNext; } - if ((comparands.Expectation is null) || (comparands.Subject is null)) + if (comparands.Expectation is null || comparands.Subject is null) { return EquivalencyResult.ContinueWithNext; } @@ -35,13 +36,15 @@ public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationCon if (TryChangeType(comparands.Subject, expectationType, out object convertedSubject)) { - context.Tracer.WriteLine(member => Invariant($"Converted subject {comparands.Subject} at {member.Description} to {expectationType}")); + context.Tracer.WriteLine(member => + Invariant($"Converted subject {comparands.Subject} at {member.Description} to {expectationType}")); comparands.Subject = convertedSubject; } else { - context.Tracer.WriteLine(member => Invariant($"Subject {comparands.Subject} at {member.Description} could not be converted to {expectationType}")); + context.Tracer.WriteLine(member => + Invariant($"Subject {comparands.Subject} at {member.Description} could not be converted to {expectationType}")); } return EquivalencyResult.ContinueWithNext; @@ -50,6 +53,7 @@ public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationCon private static bool TryChangeType(object subject, Type expectationType, out object conversionResult) { conversionResult = null; + try { conversionResult = Convert.ChangeType(subject, expectationType, CultureInfo.InvariantCulture); diff --git a/Src/FluentAssertions/Equivalency/Steps/ConstraintCollectionEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/ConstraintCollectionEquivalencyStep.cs index 644a3be769..991692215b 100644 --- a/Src/FluentAssertions/Equivalency/Steps/ConstraintCollectionEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/ConstraintCollectionEquivalencyStep.cs @@ -7,12 +7,14 @@ namespace FluentAssertions.Equivalency.Steps; public class ConstraintCollectionEquivalencyStep : EquivalencyStep { - protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { if (comparands.Subject is not ConstraintCollection) { AssertionScope.Current - .FailWith("Expected a value of type ConstraintCollection at {context:Constraints}, but found {0}", comparands.Subject.GetType()); + .FailWith("Expected a value of type ConstraintCollection at {context:Constraints}, but found {0}", + comparands.Subject.GetType()); } else { @@ -28,13 +30,14 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc { AssertionScope.Current .ForCondition(subjectConstraints.TryGetValue(constraintName, out Constraint subjectConstraint)) - .FailWith("Expected constraint named {0} in {context:Constraints collection}{reason}, but did not find one", constraintName); + .FailWith("Expected constraint named {0} in {context:Constraints collection}{reason}, but did not find one", + constraintName); AssertionScope.Current .ForCondition(expectationConstraints.TryGetValue(constraintName, out Constraint expectationConstraint)) .FailWith("Found unexpected constraint named {0} in {context:Constraints collection}", constraintName); - if ((subjectConstraint is not null) && (expectationConstraint is not null)) + if (subjectConstraint is not null && expectationConstraint is not null) { Comparands newComparands = new() { diff --git a/Src/FluentAssertions/Equivalency/Steps/ConstraintEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/ConstraintEquivalencyStep.cs index f36b001923..5420d16788 100644 --- a/Src/FluentAssertions/Equivalency/Steps/ConstraintEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/ConstraintEquivalencyStep.cs @@ -9,7 +9,8 @@ namespace FluentAssertions.Equivalency.Steps; public class ConstraintEquivalencyStep : EquivalencyStep { - protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { if (comparands.Subject is not Constraint) { @@ -36,14 +37,14 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc if (matchingType) { - if ((subject is UniqueConstraint subjectUniqueConstraint) - && (expectation is UniqueConstraint expectationUniqueConstraint)) + if (subject is UniqueConstraint subjectUniqueConstraint + && expectation is UniqueConstraint expectationUniqueConstraint) { CompareConstraints(nestedValidator, context, subjectUniqueConstraint, expectationUniqueConstraint, selectedMembers); } - else if ((subject is ForeignKeyConstraint subjectForeignKeyConstraint) - && (expectation is ForeignKeyConstraint expectationForeignKeyConstraint)) + else if (subject is ForeignKeyConstraint subjectForeignKeyConstraint + && expectation is ForeignKeyConstraint expectationForeignKeyConstraint) { CompareConstraints(nestedValidator, context, subjectForeignKeyConstraint, expectationForeignKeyConstraint, selectedMembers); @@ -83,6 +84,7 @@ private static void CompareCommonProperties(IEquivalencyValidationContext contex if (selectedMembers.TryGetValue("ExtendedProperties", out IMember expectationMember)) { IMember matchingMember = FindMatchFor(expectationMember, context.CurrentNode, subject, options); + if (matchingMember is not null) { var nestedComparands = new Comparands @@ -222,7 +224,8 @@ private static void CompareConstraintColumns(DataColumn[] subjectColumns, DataCo } failureMessage.Append("{reason}, but constraint does not include "); - failureMessage.Append((missingColumnNames.Count == 1) + + failureMessage.Append(missingColumnNames.Count == 1 ? "that column. " : "these columns. "); } diff --git a/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs index 1e1e5ee5e5..93b6f5ca94 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs @@ -10,7 +10,8 @@ namespace FluentAssertions.Equivalency.Steps; public class DataColumnEquivalencyStep : EquivalencyStep { [SuppressMessage("Style", "IDE0019:Use pattern matching", Justification = "The code is easier to read without it.")] - protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { var subject = comparands.Subject as DataColumn; var expectation = comparands.Expectation as DataColumn; @@ -54,9 +55,9 @@ private static void CompareSubjectAndExpectationOfTypeDataColumn(Comparands comp var dataTableConfig = context.Options as DataEquivalencyAssertionOptions; var dataColumnConfig = context.Options as DataEquivalencyAssertionOptions; - if ((dataSetConfig?.ShouldExcludeColumn(subject) == true) - || (dataTableConfig?.ShouldExcludeColumn(subject) == true) - || (dataColumnConfig?.ShouldExcludeColumn(subject) == true)) + if (dataSetConfig?.ShouldExcludeColumn(subject) == true + || dataTableConfig?.ShouldExcludeColumn(subject) == true + || dataColumnConfig?.ShouldExcludeColumn(subject) == true) { compareColumn = false; } @@ -77,6 +78,7 @@ private static void CompareMember(IMember expectationMember, Comparands comparan IEquivalencyValidationContext context) { IMember matchingMember = FindMatchFor(expectationMember, comparands.Subject, context); + if (matchingMember is not null) { var nestedComparands = new Comparands @@ -108,7 +110,7 @@ where match is not null // DataColumn.BeEquivalentTo extension method in DataColumnAssertions.cs. If this ever // needs to change, keep them in sync. private static readonly ISet CandidateMembers = - new HashSet() + new HashSet { nameof(DataColumn.AllowDBNull), nameof(DataColumn.AutoIncrement), diff --git a/Src/FluentAssertions/Equivalency/Steps/DataRelationEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataRelationEquivalencyStep.cs index 9dbc341504..a84a754262 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataRelationEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataRelationEquivalencyStep.cs @@ -10,7 +10,8 @@ namespace FluentAssertions.Equivalency.Steps; public class DataRelationEquivalencyStep : EquivalencyStep { [SuppressMessage("Style", "IDE0019:Use pattern matching", Justification = "The code is easier to read without it.")] - protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { var subject = comparands.Subject as DataRelation; var expectation = comparands.Expectation as DataRelation; @@ -89,6 +90,7 @@ private static void CompareCollections(IEquivalencyValidationContext context, Co if (selectedMembers.TryGetValue(nameof(DataRelation.ExtendedProperties), out IMember expectationMember)) { IMember matchingMember = FindMatchFor(expectationMember, context.CurrentNode, comparands.Subject, config); + if (matchingMember is not null) { var nestedComparands = new Comparands @@ -171,8 +173,8 @@ private static void CompareDataRelationColumns(DataRelation subject, DataRelatio DataColumn expectationColumn = expectationColumns[i]; bool columnsAreEquivalent = - (subjectColumn.Table.TableName == expectationColumn.Table.TableName) && - (subjectColumn.ColumnName == expectationColumn.ColumnName); + subjectColumn.Table.TableName == expectationColumn.Table.TableName && + subjectColumn.ColumnName == expectationColumn.ColumnName; AssertionScope.Current .ForCondition(columnsAreEquivalent) diff --git a/Src/FluentAssertions/Equivalency/Steps/DataRowCollectionEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataRowCollectionEquivalencyStep.cs index 3a0ef78cc5..1206932a38 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataRowCollectionEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataRowCollectionEquivalencyStep.cs @@ -8,7 +8,8 @@ namespace FluentAssertions.Equivalency.Steps; public class DataRowCollectionEquivalencyStep : EquivalencyStep { - protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { if (comparands.Subject is not DataRowCollection) { @@ -52,6 +53,7 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc default: AssertionScope.Current.FailWith( "Unknown RowMatchMode {0} when trying to compare {context:DataRowCollection}", rowMatchMode); + break; } } @@ -60,7 +62,8 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc return EquivalencyResult.AssertionCompleted; } - private static void MatchRowsByIndexAndCompare(IEquivalencyValidationContext context, IEquivalencyValidator parent, DataRowCollection subject, DataRowCollection expectation) + private static void MatchRowsByIndexAndCompare(IEquivalencyValidationContext context, IEquivalencyValidator parent, + DataRowCollection subject, DataRowCollection expectation) { for (int index = 0; index < expectation.Count; index++) { @@ -69,7 +72,8 @@ private static void MatchRowsByIndexAndCompare(IEquivalencyValidationContext con } } - private static void MatchRowsByPrimaryKeyAndCompare(IEquivalencyValidator parent, IEquivalencyValidationContext context, DataRowCollection subject, DataRowCollection expectation) + private static void MatchRowsByPrimaryKeyAndCompare(IEquivalencyValidator parent, IEquivalencyValidationContext context, + DataRowCollection subject, DataRowCollection expectation) { Type[] subjectPrimaryKeyTypes = null; Type[] expectationPrimaryKeyTypes = null; @@ -99,7 +103,9 @@ private static Type[] GatherPrimaryKeyColumnTypes(DataTable table, string compar if (table.PrimaryKey is null or { Length: 0 }) { AssertionScope.Current - .FailWith("Table {0} containing {1} {context:DataRowCollection} does not have a primary key. RowMatchMode.PrimaryKey cannot be applied.", table.TableName, comparisonTerm); + .FailWith( + "Table {0} containing {1} {context:DataRowCollection} does not have a primary key. RowMatchMode.PrimaryKey cannot be applied.", + table.TableName, comparisonTerm); } else { @@ -118,11 +124,11 @@ private static bool ComparePrimaryKeyTypes(Type[] subjectPrimaryKeyTypes, Type[] { bool matchingTypes = false; - if ((subjectPrimaryKeyTypes is not null) && (expectationPrimaryKeyTypes is not null)) + if (subjectPrimaryKeyTypes is not null && expectationPrimaryKeyTypes is not null) { matchingTypes = subjectPrimaryKeyTypes.Length == expectationPrimaryKeyTypes.Length; - for (int i = 0; matchingTypes && (i < subjectPrimaryKeyTypes.Length); i++) + for (int i = 0; matchingTypes && i < subjectPrimaryKeyTypes.Length; i++) { if (subjectPrimaryKeyTypes[i] != expectationPrimaryKeyTypes[i]) { @@ -133,14 +139,16 @@ private static bool ComparePrimaryKeyTypes(Type[] subjectPrimaryKeyTypes, Type[] if (!matchingTypes) { AssertionScope.Current - .FailWith("Subject and expectation primary keys of table containing {context:DataRowCollection} do not have the same schema and cannot be compared. RowMatchMode.PrimaryKey cannot be applied."); + .FailWith( + "Subject and expectation primary keys of table containing {context:DataRowCollection} do not have the same schema and cannot be compared. RowMatchMode.PrimaryKey cannot be applied."); } } return matchingTypes; } - private static void GatherRowsByPrimaryKeyAndCompareData(IEquivalencyValidator parent, IEquivalencyValidationContext context, DataRowCollection subject, DataRowCollection expectation) + private static void GatherRowsByPrimaryKeyAndCompareData(IEquivalencyValidator parent, IEquivalencyValidationContext context, + DataRowCollection subject, DataRowCollection expectation) { var expectationRowByKey = expectation.Cast() .ToDictionary(row => ExtractPrimaryKey(row)); @@ -173,7 +181,9 @@ private static void GatherRowsByPrimaryKeyAndCompareData(IEquivalencyValidator p else { AssertionScope.Current - .FailWith("Expected to find a row with key {0} in {context:DataRowCollection}{reason}, but no such row was found", expectationRowByKey.Keys.Single()); + .FailWith( + "Expected to find a row with key {0} in {context:DataRowCollection}{reason}, but no such row was found", + expectationRowByKey.Keys.Single()); } } } @@ -218,7 +228,7 @@ public override int GetHashCode() for (int i = 0; i < values.Length; i++) { - hash = (hash * 389) ^ values[i].GetHashCode(); + hash = hash * 389 ^ values[i].GetHashCode(); } return hash; diff --git a/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs index d9aaeed690..fedad03d3b 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs @@ -12,7 +12,8 @@ namespace FluentAssertions.Equivalency.Steps; public class DataRowEquivalencyStep : EquivalencyStep { [SuppressMessage("Style", "IDE0019:Use pattern matching", Justification = "The code is easier to read without it.")] - protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { var subject = comparands.Subject as DataRow; var expectation = comparands.Expectation as DataRow; @@ -54,7 +55,8 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc expectation.GetType(), subject.GetType()); } - SelectedDataRowMembers selectedMembers = GetMembersFromExpectation(comparands, context.CurrentNode, context.Options); + SelectedDataRowMembers selectedMembers = + GetMembersFromExpectation(comparands, context.CurrentNode, context.Options); CompareScalarProperties(subject, expectation, selectedMembers); @@ -98,26 +100,26 @@ private static void CompareFieldValues(IEquivalencyValidationContext context, IE .Select(col => col.ColumnName); bool ignoreUnmatchedColumns = - (dataSetConfig?.IgnoreUnmatchedColumns == true) || - (dataTableConfig?.IgnoreUnmatchedColumns == true) || - (dataRowConfig?.IgnoreUnmatchedColumns == true); + dataSetConfig?.IgnoreUnmatchedColumns == true || + dataTableConfig?.IgnoreUnmatchedColumns == true || + dataRowConfig?.IgnoreUnmatchedColumns == true; DataRowVersion subjectVersion = - (subject.RowState == DataRowState.Deleted) + subject.RowState == DataRowState.Deleted ? DataRowVersion.Original : DataRowVersion.Current; DataRowVersion expectationVersion = - (expectation.RowState == DataRowState.Deleted) + expectation.RowState == DataRowState.Deleted ? DataRowVersion.Original : DataRowVersion.Current; bool compareOriginalVersions = - (subject.RowState == DataRowState.Modified) && (expectation.RowState == DataRowState.Modified); + subject.RowState == DataRowState.Modified && expectation.RowState == DataRowState.Modified; - if ((dataSetConfig?.ExcludeOriginalData == true) - || (dataTableConfig?.ExcludeOriginalData == true) - || (dataRowConfig?.ExcludeOriginalData == true)) + if (dataSetConfig?.ExcludeOriginalData == true + || dataTableConfig?.ExcludeOriginalData == true + || dataRowConfig?.ExcludeOriginalData == true) { compareOriginalVersions = false; } @@ -128,9 +130,9 @@ private static void CompareFieldValues(IEquivalencyValidationContext context, IE DataColumn subjectColumn = subject.Table.Columns[columnName]; if (subjectColumn is not null - && ((dataSetConfig?.ShouldExcludeColumn(subjectColumn) == true) - || (dataTableConfig?.ShouldExcludeColumn(subjectColumn) == true) - || (dataRowConfig?.ShouldExcludeColumn(subjectColumn) == true))) + && (dataSetConfig?.ShouldExcludeColumn(subjectColumn) == true + || dataTableConfig?.ShouldExcludeColumn(subjectColumn) == true + || dataRowConfig?.ShouldExcludeColumn(subjectColumn) == true)) { continue; } @@ -146,7 +148,7 @@ private static void CompareFieldValues(IEquivalencyValidationContext context, IE .FailWith("Found unexpected column {0} in {context:DataRow}", columnName); } - if ((subjectColumn is not null) && (expectationColumn is not null)) + if (subjectColumn is not null && expectationColumn is not null) { CompareFieldValue(context, parent, subject, expectation, subjectColumn, subjectVersion, expectationColumn, expectationVersion); @@ -172,7 +174,8 @@ private static void CompareFieldValue(IEquivalencyValidationContext context, IEq if (nestedContext is not null) { parent.RecursivelyAssertEquality( - new Comparands(subject[subjectColumn, subjectVersion], expectation[expectationColumn, expectationVersion], typeof(object)), + new Comparands(subject[subjectColumn, subjectVersion], expectation[expectationColumn, expectationVersion], + typeof(object)), nestedContext); } } @@ -185,7 +188,7 @@ private class SelectedDataRowMembers } private static readonly ConcurrentDictionary<(Type CompileTimeType, Type RuntimeType, IEquivalencyAssertionOptions Config), - SelectedDataRowMembers> SelectedMembersCache = new(); + SelectedDataRowMembers> SelectedMembersCache = new(); private static SelectedDataRowMembers GetMembersFromExpectation(Comparands comparands, INode currentNode, IEquivalencyAssertionOptions config) diff --git a/Src/FluentAssertions/Equivalency/Steps/DataSetEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataSetEquivalencyStep.cs index e49727d7ce..8c2f838df6 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataSetEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataSetEquivalencyStep.cs @@ -8,7 +8,8 @@ namespace FluentAssertions.Equivalency.Steps; public class DataSetEquivalencyStep : EquivalencyStep { - protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { var subject = comparands.Subject as DataSet; @@ -29,7 +30,8 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc } else { - AssertionScope.Current.FailWith("Expected {context:DataSet} to be of type {0}, but found {1} instead", expectation.GetType(), comparands.Subject.GetType()); + AssertionScope.Current.FailWith("Expected {context:DataSet} to be of type {0}, but found {1} instead", + expectation.GetType(), comparands.Subject.GetType()); } } else @@ -40,7 +42,8 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc { AssertionScope.Current .ForCondition(subject.GetType() == expectation.GetType()) - .FailWith("Expected {context:DataSet} to be of type {0}{reason}, but found {1}", expectation.GetType(), subject.GetType()); + .FailWith("Expected {context:DataSet} to be of type {0}{reason}, but found {1}", expectation.GetType(), + subject.GetType()); } var selectedMembers = GetMembersFromExpectation(comparands, context.CurrentNode, context.Options) @@ -63,82 +66,97 @@ private static void CompareScalarProperties(DataSet subject, DataSet expectation { AssertionScope.Current .ForCondition(subject.DataSetName == expectation.DataSetName) - .FailWith("Expected {context:DataSet} to have DataSetName {0}{reason}, but found {1} instead", expectation.DataSetName, subject.DataSetName); + .FailWith("Expected {context:DataSet} to have DataSetName {0}{reason}, but found {1} instead", + expectation.DataSetName, subject.DataSetName); } if (selectedMembers.ContainsKey(nameof(expectation.CaseSensitive))) { AssertionScope.Current .ForCondition(subject.CaseSensitive == expectation.CaseSensitive) - .FailWith("Expected {context:DataSet} to have CaseSensitive value of {0}{reason}, but found {1} instead", expectation.CaseSensitive, subject.CaseSensitive); + .FailWith("Expected {context:DataSet} to have CaseSensitive value of {0}{reason}, but found {1} instead", + expectation.CaseSensitive, subject.CaseSensitive); } if (selectedMembers.ContainsKey(nameof(expectation.EnforceConstraints))) { AssertionScope.Current .ForCondition(subject.EnforceConstraints == expectation.EnforceConstraints) - .FailWith("Expected {context:DataSet} to have EnforceConstraints value of {0}{reason}, but found {1} instead", expectation.EnforceConstraints, subject.EnforceConstraints); + .FailWith("Expected {context:DataSet} to have EnforceConstraints value of {0}{reason}, but found {1} instead", + expectation.EnforceConstraints, subject.EnforceConstraints); } if (selectedMembers.ContainsKey(nameof(expectation.HasErrors))) { AssertionScope.Current .ForCondition(subject.HasErrors == expectation.HasErrors) - .FailWith("Expected {context:DataSet} to have HasErrors value of {0}{reason}, but found {1} instead", expectation.HasErrors, subject.HasErrors); + .FailWith("Expected {context:DataSet} to have HasErrors value of {0}{reason}, but found {1} instead", + expectation.HasErrors, subject.HasErrors); } if (selectedMembers.ContainsKey(nameof(expectation.Locale))) { AssertionScope.Current .ForCondition(subject.Locale == expectation.Locale) - .FailWith("Expected {context:DataSet} to have Locale value of {0}{reason}, but found {1} instead", expectation.Locale, subject.Locale); + .FailWith("Expected {context:DataSet} to have Locale value of {0}{reason}, but found {1} instead", + expectation.Locale, subject.Locale); } if (selectedMembers.ContainsKey(nameof(expectation.Namespace))) { AssertionScope.Current .ForCondition(subject.Namespace == expectation.Namespace) - .FailWith("Expected {context:DataSet} to have Namespace value of {0}{reason}, but found {1} instead", expectation.Namespace, subject.Namespace); + .FailWith("Expected {context:DataSet} to have Namespace value of {0}{reason}, but found {1} instead", + expectation.Namespace, subject.Namespace); } if (selectedMembers.ContainsKey(nameof(expectation.Prefix))) { AssertionScope.Current .ForCondition(subject.Prefix == expectation.Prefix) - .FailWith("Expected {context:DataSet} to have Prefix value of {0}{reason}, but found {1} instead", expectation.Prefix, subject.Prefix); + .FailWith("Expected {context:DataSet} to have Prefix value of {0}{reason}, but found {1} instead", + expectation.Prefix, subject.Prefix); } if (selectedMembers.ContainsKey(nameof(expectation.RemotingFormat))) { AssertionScope.Current .ForCondition(subject.RemotingFormat == expectation.RemotingFormat) - .FailWith("Expected {context:DataSet} to have RemotingFormat value of {0}{reason}, but found {1} instead", expectation.RemotingFormat, subject.RemotingFormat); + .FailWith("Expected {context:DataSet} to have RemotingFormat value of {0}{reason}, but found {1} instead", + expectation.RemotingFormat, subject.RemotingFormat); } if (selectedMembers.ContainsKey(nameof(expectation.SchemaSerializationMode))) { AssertionScope.Current .ForCondition(subject.SchemaSerializationMode == expectation.SchemaSerializationMode) - .FailWith("Expected {context:DataSet} to have SchemaSerializationMode value of {0}{reason}, but found {1} instead", expectation.SchemaSerializationMode, subject.SchemaSerializationMode); + .FailWith( + "Expected {context:DataSet} to have SchemaSerializationMode value of {0}{reason}, but found {1} instead", + expectation.SchemaSerializationMode, subject.SchemaSerializationMode); } } - private static void CompareCollections(IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config, DataSet subject, DataSet expectation, DataEquivalencyAssertionOptions dataConfig, Dictionary selectedMembers) + private static void CompareCollections(IEquivalencyValidationContext context, IEquivalencyValidator parent, + IEquivalencyAssertionOptions config, DataSet subject, DataSet expectation, + DataEquivalencyAssertionOptions dataConfig, Dictionary selectedMembers) { // Note: The collections here are listed in the XML documentation for the DataSet.BeEquivalentTo extension // method in DataSetAssertions.cs. If this ever needs to change, keep them in sync. - CompareExtendedProperties(new Comparands(subject, expectation, typeof(DataSet)), context, parent, config, selectedMembers); + CompareExtendedProperties(new Comparands(subject, expectation, typeof(DataSet)), context, parent, config, + selectedMembers); CompareTables(context, parent, subject, expectation, dataConfig, selectedMembers); } - private static void CompareExtendedProperties(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config, Dictionary selectedMembers) + private static void CompareExtendedProperties(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator parent, IEquivalencyAssertionOptions config, Dictionary selectedMembers) { foreach (var collectionName in new[] { nameof(DataSet.ExtendedProperties), nameof(DataSet.Relations) }) { if (selectedMembers.TryGetValue(collectionName, out IMember expectationMember)) { IMember matchingMember = FindMatchFor(expectationMember, comparands.Subject, context.CurrentNode, config); + if (matchingMember is not null) { var nestedComparands = new Comparands @@ -155,13 +173,15 @@ private static void CompareExtendedProperties(Comparands comparands, IEquivalenc } } - private static void CompareTables(IEquivalencyValidationContext context, IEquivalencyValidator parent, DataSet subject, DataSet expectation, DataEquivalencyAssertionOptions dataConfig, Dictionary selectedMembers) + private static void CompareTables(IEquivalencyValidationContext context, IEquivalencyValidator parent, DataSet subject, + DataSet expectation, DataEquivalencyAssertionOptions dataConfig, Dictionary selectedMembers) { if (selectedMembers.ContainsKey(nameof(expectation.Tables))) { bool success = AssertionScope.Current .ForCondition(subject.Tables.Count == expectation.Tables.Count) - .FailWith("Expected {context:DataSet} to contain {0}, but found {1} table(s)", expectation.Tables.Count, subject.Tables.Count); + .FailWith("Expected {context:DataSet} to contain {0}, but found {1} table(s)", expectation.Tables.Count, + subject.Tables.Count); if (!success) { @@ -175,17 +195,18 @@ private static void CompareTables(IEquivalencyValidationContext context, IEquiva if (excludeCaseSensitive || excludeLocale) { - dataConfig.Excluding((IMemberInfo memberInfo) => - (memberInfo.DeclaringType == typeof(DataTable)) && + dataConfig.Excluding(memberInfo => + memberInfo.DeclaringType == typeof(DataTable) && ( - (excludeCaseSensitive && (memberInfo.Name == nameof(DataTable.CaseSensitive))) - || - (excludeLocale && (memberInfo.Name == nameof(DataTable.Locale))))); + (excludeCaseSensitive && memberInfo.Name == nameof(DataTable.CaseSensitive)) + || + (excludeLocale && memberInfo.Name == nameof(DataTable.Locale)))); } } IEnumerable expectationTableNames = expectation.Tables.Cast() .Select(table => table.TableName); + IEnumerable subjectTableNames = subject.Tables.Cast() .Select(table => table.TableName); @@ -221,7 +242,8 @@ private static void CompareTable(IEquivalencyValidationContext context, IEquival } } - private static IMember FindMatchFor(IMember selectedMemberInfo, object subject, INode currentNode, IEquivalencyAssertionOptions options) + private static IMember FindMatchFor(IMember selectedMemberInfo, object subject, INode currentNode, + IEquivalencyAssertionOptions options) { IEnumerable query = from rule in options.MatchingRules diff --git a/Src/FluentAssertions/Equivalency/Steps/DataTableEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataTableEquivalencyStep.cs index 143bf66c2e..1ec6f5fd43 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataTableEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataTableEquivalencyStep.cs @@ -10,7 +10,8 @@ namespace FluentAssertions.Equivalency.Steps; public class DataTableEquivalencyStep : EquivalencyStep { [SuppressMessage("Style", "IDE0019:Use pattern matching", Justification = "The code is easier to read without it.")] - protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { var subject = comparands.Subject as DataTable; var expectation = comparands.Expectation as DataTable; @@ -32,7 +33,8 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc } else { - AssertionScope.Current.FailWith("Expected {context:DataTable} to be of type {0}, but found {1} instead", expectation.GetType(), comparands.Subject.GetType()); + AssertionScope.Current.FailWith("Expected {context:DataTable} to be of type {0}, but found {1} instead", + expectation.GetType(), comparands.Subject.GetType()); } } else @@ -41,11 +43,12 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc var dataTableConfig = context.Options as DataEquivalencyAssertionOptions; if (dataSetConfig?.AllowMismatchedTypes != true - && dataTableConfig?.AllowMismatchedTypes != true) + && dataTableConfig?.AllowMismatchedTypes != true) { AssertionScope.Current .ForCondition(subject.GetType() == expectation.GetType()) - .FailWith("Expected {context:DataTable} to be of type {0}{reason}, but found {1}", expectation.GetType(), subject.GetType()); + .FailWith("Expected {context:DataTable} to be of type {0}{reason}, but found {1}", expectation.GetType(), + subject.GetType()); } var selectedMembers = GetMembersFromExpectation(context.CurrentNode, comparands, context.Options) @@ -60,7 +63,8 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc return EquivalencyResult.AssertionCompleted; } - private static void CompareScalarProperties(DataTable subject, DataTable expectation, Dictionary selectedMembers) + private static void CompareScalarProperties(DataTable subject, DataTable expectation, + Dictionary selectedMembers) { // Note: The members here are listed in the XML documentation for the DataTable.BeEquivalentTo extension // method in DataTableAssertions.cs. If this ever needs to change, keep them in sync. @@ -68,60 +72,69 @@ private static void CompareScalarProperties(DataTable subject, DataTable expecta { AssertionScope.Current .ForCondition(subject.TableName == expectation.TableName) - .FailWith("Expected {context:DataTable} to have TableName {0}{reason}, but found {1} instead", expectation.TableName, subject.TableName); + .FailWith("Expected {context:DataTable} to have TableName {0}{reason}, but found {1} instead", + expectation.TableName, subject.TableName); } if (selectedMembers.ContainsKey(nameof(expectation.CaseSensitive))) { AssertionScope.Current .ForCondition(subject.CaseSensitive == expectation.CaseSensitive) - .FailWith("Expected {context:DataTable} to have CaseSensitive value of {0}{reason}, but found {1} instead", expectation.CaseSensitive, subject.CaseSensitive); + .FailWith("Expected {context:DataTable} to have CaseSensitive value of {0}{reason}, but found {1} instead", + expectation.CaseSensitive, subject.CaseSensitive); } if (selectedMembers.ContainsKey(nameof(expectation.DisplayExpression))) { AssertionScope.Current .ForCondition(subject.DisplayExpression == expectation.DisplayExpression) - .FailWith("Expected {context:DataTable} to have DisplayExpression value of {0}{reason}, but found {1} instead", expectation.DisplayExpression, subject.DisplayExpression); + .FailWith("Expected {context:DataTable} to have DisplayExpression value of {0}{reason}, but found {1} instead", + expectation.DisplayExpression, subject.DisplayExpression); } if (selectedMembers.ContainsKey(nameof(expectation.HasErrors))) { AssertionScope.Current .ForCondition(subject.HasErrors == expectation.HasErrors) - .FailWith("Expected {context:DataTable} to have HasErrors value of {0}{reason}, but found {1} instead", expectation.HasErrors, subject.HasErrors); + .FailWith("Expected {context:DataTable} to have HasErrors value of {0}{reason}, but found {1} instead", + expectation.HasErrors, subject.HasErrors); } if (selectedMembers.ContainsKey(nameof(expectation.Locale))) { AssertionScope.Current .ForCondition(subject.Locale == expectation.Locale) - .FailWith("Expected {context:DataTable} to have Locale value of {0}{reason}, but found {1} instead", expectation.Locale, subject.Locale); + .FailWith("Expected {context:DataTable} to have Locale value of {0}{reason}, but found {1} instead", + expectation.Locale, subject.Locale); } if (selectedMembers.ContainsKey(nameof(expectation.Namespace))) { AssertionScope.Current .ForCondition(subject.Namespace == expectation.Namespace) - .FailWith("Expected {context:DataTable} to have Namespace value of {0}{reason}, but found {1} instead", expectation.Namespace, subject.Namespace); + .FailWith("Expected {context:DataTable} to have Namespace value of {0}{reason}, but found {1} instead", + expectation.Namespace, subject.Namespace); } if (selectedMembers.ContainsKey(nameof(expectation.Prefix))) { AssertionScope.Current .ForCondition(subject.Prefix == expectation.Prefix) - .FailWith("Expected {context:DataTable} to have Prefix value of {0}{reason}, but found {1} instead", expectation.Prefix, subject.Prefix); + .FailWith("Expected {context:DataTable} to have Prefix value of {0}{reason}, but found {1} instead", + expectation.Prefix, subject.Prefix); } if (selectedMembers.ContainsKey(nameof(expectation.RemotingFormat))) { AssertionScope.Current .ForCondition(subject.RemotingFormat == expectation.RemotingFormat) - .FailWith("Expected {context:DataTable} to have RemotingFormat value of {0}{reason}, but found {1} instead", expectation.RemotingFormat, subject.RemotingFormat); + .FailWith("Expected {context:DataTable} to have RemotingFormat value of {0}{reason}, but found {1} instead", + expectation.RemotingFormat, subject.RemotingFormat); } } - private static void CompareCollections(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config, Dictionary selectedMembers) + private static void CompareCollections(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator parent, IEquivalencyAssertionOptions config, Dictionary selectedMembers) { // Note: The collections here are listed in the XML documentation for the DataTable.BeEquivalentTo extension // method in DataTableAssertions.cs. If this ever needs to change, keep them in sync. @@ -141,6 +154,7 @@ private static void CompareCollections(Comparands comparands, IEquivalencyValida if (selectedMembers.TryGetValue(collectionName, out IMember expectationMember)) { IMember matchingMember = FindMatchFor(expectationMember, comparands.Subject, context.CurrentNode, config); + if (matchingMember is not null) { IEquivalencyValidationContext nestedContext = context.AsNestedMember(expectationMember); @@ -158,7 +172,8 @@ private static void CompareCollections(Comparands comparands, IEquivalencyValida } } - private static IMember FindMatchFor(IMember selectedMemberInfo, object subject, INode currentNode, IEquivalencyAssertionOptions config) + private static IMember FindMatchFor(IMember selectedMemberInfo, object subject, INode currentNode, + IEquivalencyAssertionOptions config) { IEnumerable query = from rule in config.MatchingRules @@ -169,7 +184,8 @@ where match is not null return query.FirstOrDefault(); } - private static IEnumerable GetMembersFromExpectation(INode currentNode, Comparands comparands, IEquivalencyAssertionOptions config) + private static IEnumerable GetMembersFromExpectation(INode currentNode, Comparands comparands, + IEquivalencyAssertionOptions config) { IEnumerable members = Enumerable.Empty(); diff --git a/Src/FluentAssertions/Equivalency/Steps/DictionaryEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DictionaryEquivalencyStep.cs index fee9fe5e46..d6b3433fbc 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DictionaryEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DictionaryEquivalencyStep.cs @@ -8,7 +8,8 @@ namespace FluentAssertions.Equivalency.Steps; public class DictionaryEquivalencyStep : EquivalencyStep { [SuppressMessage("ReSharper", "PossibleNullReferenceException")] - protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { var subject = comparands.Subject as IDictionary; var expectation = comparands.Expectation as IDictionary; @@ -21,13 +22,18 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc { if (context.Options.IsRecursive) { - context.Tracer.WriteLine(member => Invariant($"Recursing into dictionary item {key} at {member.Description}")); - nestedValidator.RecursivelyAssertEquality(new Comparands(subject[key], expectation[key], typeof(object)), context.AsDictionaryItem(key)); + context.Tracer.WriteLine(member => + Invariant($"Recursing into dictionary item {key} at {member.Description}")); + + nestedValidator.RecursivelyAssertEquality(new Comparands(subject[key], expectation[key], typeof(object)), + context.AsDictionaryItem(key)); } else { context.Tracer.WriteLine(member => - Invariant($"Comparing dictionary item {key} at {member.Description} between subject and expectation")); + Invariant( + $"Comparing dictionary item {key} at {member.Description} between subject and expectation")); + subject[key].Should().Be(expectation[key], context.Reason.FormattedMessage, context.Reason.Arguments); } } @@ -40,14 +46,14 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc private static bool PreconditionsAreMet(IDictionary expectation, IDictionary subject) { return AssertIsDictionary(subject) - && AssertEitherIsNotNull(expectation, subject) - && AssertSameLength(expectation, subject); + && AssertEitherIsNotNull(expectation, subject) + && AssertSameLength(expectation, subject); } private static bool AssertEitherIsNotNull(IDictionary expectation, IDictionary subject) { return AssertionScope.Current - .ForCondition(((expectation is null) && (subject is null)) || (expectation is not null)) + .ForCondition((expectation is null && subject is null) || expectation is not null) .FailWith("Expected {context:subject} to be {0}{reason}, but found {1}.", null, subject); } @@ -61,7 +67,7 @@ private static bool AssertIsDictionary(IDictionary subject) private static bool AssertSameLength(IDictionary expectation, IDictionary subject) { return AssertionScope.Current - .ForCondition((expectation is null) || (subject.Keys.Count == expectation.Keys.Count)) + .ForCondition(expectation is null || subject.Keys.Count == expectation.Keys.Count) .FailWith("Expected {context:subject} to be a dictionary with {0} item(s), but it only contains {1} item(s).", expectation?.Keys.Count, subject?.Keys.Count); } diff --git a/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs b/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs index 82fcead6e3..d7506b3fed 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs @@ -42,6 +42,7 @@ public static bool TryGetFrom(Type target, string role, out DictionaryInterfaceI result = null; var interfaces = GetDictionaryInterfacesFrom(target); + if (interfaces.Length > 1) { throw new ArgumentException( diff --git a/Src/FluentAssertions/Equivalency/Steps/EnumEqualityStep.cs b/Src/FluentAssertions/Equivalency/Steps/EnumEqualityStep.cs index 8adbf1ae50..48a9110dba 100644 --- a/Src/FluentAssertions/Equivalency/Steps/EnumEqualityStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/EnumEqualityStep.cs @@ -10,7 +10,8 @@ namespace FluentAssertions.Equivalency.Steps; public class EnumEqualityStep : IEquivalencyStep { - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { if (!comparands.GetExpectedType(context.Options).IsEnum) { @@ -24,7 +25,9 @@ public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationCon decimal? expectationsUnderlyingValue = ExtractDecimal(comparands.Expectation); string expectationName = GetDisplayNameForEnumComparison(comparands.Expectation, expectationsUnderlyingValue); - return new FailReason($"Expected {{context:enum}} to be equivalent to {expectationName}{{reason}}, but found {{0}}.", comparands.Subject); + return new FailReason( + $"Expected {{context:enum}} to be equivalent to {expectationName}{{reason}}, but found {{0}}.", + comparands.Subject); }); if (succeeded) @@ -59,7 +62,8 @@ private static void HandleByValue(Comparands comparands) string subjectsName = GetDisplayNameForEnumComparison(comparands.Subject, subjectsUnderlyingValue); string expectationName = GetDisplayNameForEnumComparison(comparands.Expectation, expectationsUnderlyingValue); - return new FailReason($"Expected {{context:enum}} to equal {expectationName} by value{{reason}}, but found {subjectsName}."); + return new FailReason( + $"Expected {{context:enum}} to equal {expectationName} by value{{reason}}, but found {subjectsName}."); }); } @@ -77,8 +81,9 @@ private static void HandleByName(Comparands comparands) string subjectsName = GetDisplayNameForEnumComparison(comparands.Subject, subjectsUnderlyingValue); string expectationName = GetDisplayNameForEnumComparison(comparands.Expectation, expectationsUnderlyingValue); + return new FailReason( - $"Expected {{context:enum}} to equal {expectationName} by name{{reason}}, but found {subjectsName}."); + $"Expected {{context:enum}} to equal {expectationName} by name{{reason}}, but found {subjectsName}."); }); } diff --git a/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyStep.cs index 05947d63f9..bb11a573f0 100644 --- a/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyStep.cs @@ -7,7 +7,8 @@ namespace FluentAssertions.Equivalency.Steps; public class EnumerableEquivalencyStep : IEquivalencyStep { - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { if (!IsCollection(comparands.GetExpectedType(context.Options))) { @@ -37,8 +38,8 @@ private static bool AssertSubjectIsCollection(object subject) if (conditionMet) { conditionMet = AssertionScope.Current - .ForCondition(IsCollection(subject.GetType())) - .FailWith("Expected a collection, but {context:Subject} is of a non-collection type."); + .ForCondition(IsCollection(subject.GetType())) + .FailWith("Expected a collection, but {context:Subject} is of a non-collection type."); } return conditionMet; diff --git a/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyValidator.cs b/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyValidator.cs index 9466ab16b3..89e1d694fb 100644 --- a/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyValidator.cs +++ b/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyValidator.cs @@ -40,12 +40,15 @@ public void Execute(object[] subject, T[] expectation) { using var _ = context.Tracer.WriteBlock(member => Invariant($"Structurally comparing {subject} and expectation {expectation} at {member.Description}")); + AssertElementGraphEquivalency(subject, expectation, context.CurrentNode); } else { using var _ = context.Tracer.WriteBlock(member => - Invariant($"Comparing subject {subject} and expectation {expectation} at {member.Description} using simple value equality")); + Invariant( + $"Comparing subject {subject} and expectation {expectation} at {member.Description} using simple value equality")); + subject.Should().BeEquivalentTo(expectation); } } @@ -89,20 +92,26 @@ private void AssertElementGraphEquivalency(object[] subjects, T[] expectation private void AssertElementGraphEquivalencyWithStrictOrdering(object[] subjects, T[] expectations) { int failedCount = 0; + foreach (int index in Enumerable.Range(0, expectations.Length)) { T expectation = expectations[index]; using var _ = context.Tracer.WriteBlock(member => - Invariant($"Strictly comparing expectation {expectation} at {member.Description} to item with index {index} in {subjects}")); + Invariant( + $"Strictly comparing expectation {expectation} at {member.Description} to item with index {index} in {subjects}")); + bool succeeded = StrictlyMatchAgainst(subjects, expectation, index); + if (!succeeded) { failedCount++; + if (failedCount >= FailedItemsFastFailThreshold) { context.Tracer.WriteLine(member => $"Aborting strict order comparison of collections after {FailedItemsFastFailThreshold} items failed at {member.Description}"); + break; } } @@ -112,20 +121,26 @@ private void AssertElementGraphEquivalencyWithStrictOrdering(object[] subject private void AssertElementGraphEquivalencyWithLooseOrdering(object[] subjects, T[] expectations) { int failedCount = 0; + foreach (int index in Enumerable.Range(0, expectations.Length)) { T expectation = expectations[index]; using var _ = context.Tracer.WriteBlock(member => - Invariant($"Finding the best match of {expectation} within all items in {subjects} at {member.Description}[{index}]")); + Invariant( + $"Finding the best match of {expectation} within all items in {subjects} at {member.Description}[{index}]")); + bool succeeded = LooselyMatchAgainst(subjects, expectation, index); + if (!succeeded) { failedCount++; + if (failedCount >= FailedItemsFastFailThreshold) { context.Tracer.WriteLine(member => $"Fail failing loose order comparison of collection after {FailedItemsFastFailThreshold} items failed at {member.Description}"); + break; } } @@ -138,7 +153,10 @@ private bool LooselyMatchAgainst(IList subjects, T expectation, int e { var results = new AssertionResultSet(); int index = 0; - GetTraceMessage getMessage = member => $"Comparing subject at {member.Description}[{index}] with the expectation at {member.Description}[{expectationIndex}]"; + + GetTraceMessage getMessage = member => + $"Comparing subject at {member.Description}[{index}] with the expectation at {member.Description}[{expectationIndex}]"; + int indexToBeRemoved = -1; for (var metaIndex = 0; metaIndex < unmatchedSubjectIndexes.Count; metaIndex++) @@ -150,6 +168,7 @@ private bool LooselyMatchAgainst(IList subjects, T expectation, int e string[] failures = TryToMatch(subject, expectation, expectationIndex); results.AddSet(index, failures); + if (results.ContainsSuccessfulSet()) { context.Tracer.WriteLine(_ => "It's a match"); @@ -178,7 +197,9 @@ private bool LooselyMatchAgainst(IList subjects, T expectation, int e private string[] TryToMatch(object subject, T expectation, int expectationIndex) { using var scope = new AssertionScope(); - parent.RecursivelyAssertEquality(new Comparands(subject, expectation, typeof(T)), context.AsCollectionItem(expectationIndex)); + + parent.RecursivelyAssertEquality(new Comparands(subject, expectation, typeof(T)), + context.AsCollectionItem(expectationIndex)); return scope.Discard(); } diff --git a/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyValidatorExtensions.cs b/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyValidatorExtensions.cs index dc0c94751a..657b8f6add 100644 --- a/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyValidatorExtensions.cs +++ b/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyValidatorExtensions.cs @@ -6,20 +6,22 @@ namespace FluentAssertions.Equivalency.Steps; internal static class EnumerableEquivalencyValidatorExtensions { - public static Continuation AssertEitherCollectionIsNotEmpty(this IAssertionScope scope, ICollection subject, ICollection expectation) + public static Continuation AssertEitherCollectionIsNotEmpty(this IAssertionScope scope, ICollection subject, + ICollection expectation) { return scope - .ForCondition((subject.Count > 0) || (expectation.Count == 0)) + .ForCondition(subject.Count > 0 || expectation.Count == 0) .FailWith(", but found an empty collection.") .Then - .ForCondition((subject.Count == 0) || (expectation.Count > 0)) + .ForCondition(subject.Count == 0 || expectation.Count > 0) .FailWith(", but {0}{2}contains {1} item(s).", subject, subject.Count, Environment.NewLine); } - public static Continuation AssertCollectionHasEnoughItems(this IAssertionScope scope, ICollection subject, ICollection expectation) + public static Continuation AssertCollectionHasEnoughItems(this IAssertionScope scope, ICollection subject, + ICollection expectation) { return scope .ForCondition(subject.Count >= expectation.Count) @@ -30,7 +32,8 @@ public static Continuation AssertCollectionHasEnoughItems(this IAssertionScop Environment.NewLine); } - public static Continuation AssertCollectionHasNotTooManyItems(this IAssertionScope scope, ICollection subject, ICollection expectation) + public static Continuation AssertCollectionHasNotTooManyItems(this IAssertionScope scope, ICollection subject, + ICollection expectation) { return scope .ForCondition(subject.Count <= expectation.Count) diff --git a/Src/FluentAssertions/Equivalency/Steps/EqualityComparerEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/EqualityComparerEquivalencyStep.cs index 91a9cfcf6e..d704ef80f6 100644 --- a/Src/FluentAssertions/Equivalency/Steps/EqualityComparerEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/EqualityComparerEquivalencyStep.cs @@ -13,7 +13,8 @@ public EqualityComparerEquivalencyStep(IEqualityComparer comparer) this.comparer = comparer ?? throw new ArgumentNullException(nameof(comparer)); } - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { if (comparands.GetExpectedType(context.Options) != typeof(T)) { diff --git a/Src/FluentAssertions/Equivalency/Steps/GenericDictionaryEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/GenericDictionaryEquivalencyStep.cs index 7ff38e45fe..c4f5bd2782 100644 --- a/Src/FluentAssertions/Equivalency/Steps/GenericDictionaryEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/GenericDictionaryEquivalencyStep.cs @@ -27,6 +27,7 @@ public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationCon { Type expectationType = comparands.GetExpectedType(context.Options); bool isDictionary = DictionaryInterfaceInfo.TryGetFrom(expectationType, "expectation", out var expectedDictionary); + if (isDictionary) { Handle(comparands, expectedDictionary, context, nestedValidator); @@ -46,6 +47,7 @@ private static void Handle(Comparands comparands, DictionaryInterfaceInfo expect && AssertExpectationIsNotNull(comparands.Subject, comparands.Expectation)) { var (isDictionary, actualDictionary) = EnsureSubjectIsDictionary(comparands, expectedDictionary); + if (isDictionary) { if (AssertSameLength(comparands, actualDictionary, expectedDictionary)) @@ -111,7 +113,7 @@ private static bool AssertSameLength(Comparands comparands, DictionaryInterfaceI } private static bool AssertSameLength( - IDictionary subject, IDictionary expectation) + IDictionary subject, IDictionary expectation) // Type constraint of TExpectedKey is asymmetric in regards to TSubjectKey // but it is valid. This constraint is implicitly enforced by the dictionary interface info which is called before @@ -164,6 +166,7 @@ private static bool AssertSameLength(); + foreach (TSubjectKey subjectKey in subject.Keys) { if (!presentKeys.Contains(subjectKey)) diff --git a/Src/FluentAssertions/Equivalency/Steps/GenericEnumerableEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/GenericEnumerableEquivalencyStep.cs index 2a0e1161d6..e96835f67a 100644 --- a/Src/FluentAssertions/Equivalency/Steps/GenericEnumerableEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/GenericEnumerableEquivalencyStep.cs @@ -15,9 +15,11 @@ public class GenericEnumerableEquivalencyStep : IEquivalencyStep (HandleImpl).GetMethodInfo().GetGenericMethodDefinition(); #pragma warning restore SA1110 - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { Type expectedType = comparands.GetExpectedType(context.Options); + if (comparands.Expectation is null || !IsGenericCollection(expectedType)) { return EquivalencyResult.ContinueWithNext; @@ -45,7 +47,8 @@ public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationCon try { - HandleMethod.MakeGenericMethod(typeOfEnumeration).Invoke(null, new[] { validator, subjectAsArray, comparands.Expectation }); + HandleMethod.MakeGenericMethod(typeOfEnumeration) + .Invoke(null, new[] { validator, subjectAsArray, comparands.Expectation }); } catch (TargetInvocationException e) { @@ -56,8 +59,8 @@ public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationCon return EquivalencyResult.AssertionCompleted; } - private static void HandleImpl(EnumerableEquivalencyValidator validator, object[] subject, IEnumerable expectation) - => validator.Execute(subject, ToArray(expectation)); + private static void HandleImpl(EnumerableEquivalencyValidator validator, object[] subject, IEnumerable expectation) => + validator.Execute(subject, ToArray(expectation)); private static bool AssertSubjectIsCollection(object subject) { @@ -84,7 +87,7 @@ private static bool IsGenericCollection(Type type) { Type[] enumerableInterfaces = GetIEnumerableInterfaces(type); - return (!typeof(string).IsAssignableFrom(type)) && enumerableInterfaces.Any(); + return !typeof(string).IsAssignableFrom(type) && enumerableInterfaces.Any(); } private static Type[] GetIEnumerableInterfaces(Type type) @@ -97,7 +100,7 @@ private static Type[] GetIEnumerableInterfaces(Type type) Type soughtType = typeof(IEnumerable<>); - return Common.TypeExtensions.GetClosedGenericInterfaces(type, soughtType); + return type.GetClosedGenericInterfaces(soughtType); } private static Type GetTypeOfEnumeration(Type enumerableType) diff --git a/Src/FluentAssertions/Equivalency/Steps/ReferenceEqualityEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/ReferenceEqualityEquivalencyStep.cs index 7ba6b772a6..dc1e6b6018 100644 --- a/Src/FluentAssertions/Equivalency/Steps/ReferenceEqualityEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/ReferenceEqualityEquivalencyStep.cs @@ -2,8 +2,11 @@ public class ReferenceEqualityEquivalencyStep : IEquivalencyStep { - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { - return ReferenceEquals(comparands.Subject, comparands.Expectation) ? EquivalencyResult.AssertionCompleted : EquivalencyResult.ContinueWithNext; + return ReferenceEquals(comparands.Subject, comparands.Expectation) + ? EquivalencyResult.AssertionCompleted + : EquivalencyResult.ContinueWithNext; } } diff --git a/Src/FluentAssertions/Equivalency/Steps/RunAllUserStepsEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/RunAllUserStepsEquivalencyStep.cs index 776baf5102..6bfc9d801c 100644 --- a/Src/FluentAssertions/Equivalency/Steps/RunAllUserStepsEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/RunAllUserStepsEquivalencyStep.cs @@ -6,7 +6,8 @@ /// public class RunAllUserStepsEquivalencyStep : IEquivalencyStep { - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { foreach (IEquivalencyStep step in context.Options.UserEquivalencySteps) { diff --git a/Src/FluentAssertions/Equivalency/Steps/SimpleEqualityEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/SimpleEqualityEquivalencyStep.cs index 4c7a947c7e..0d15f6c0ea 100644 --- a/Src/FluentAssertions/Equivalency/Steps/SimpleEqualityEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/SimpleEqualityEquivalencyStep.cs @@ -2,7 +2,8 @@ namespace FluentAssertions.Equivalency.Steps; public class SimpleEqualityEquivalencyStep : IEquivalencyStep { - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { if (!context.Options.IsRecursive && !context.CurrentNode.IsRoot) { diff --git a/Src/FluentAssertions/Equivalency/Steps/StringEqualityEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/StringEqualityEquivalencyStep.cs index f607c7a32b..ce7f0f5ef9 100644 --- a/Src/FluentAssertions/Equivalency/Steps/StringEqualityEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/StringEqualityEquivalencyStep.cs @@ -5,7 +5,8 @@ namespace FluentAssertions.Equivalency.Steps; public class StringEqualityEquivalencyStep : IEquivalencyStep { - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { Type expectationType = comparands.GetExpectedType(context.Options); @@ -20,6 +21,7 @@ public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationCon } bool subjectIsString = ValidateSubjectIsString(comparands, context.CurrentNode); + if (subjectIsString) { string subject = (string)comparands.Subject; @@ -37,7 +39,7 @@ private static bool ValidateAgainstNulls(Comparands comparands, INode currentNod object expected = comparands.Expectation; object subject = comparands.Subject; - bool onlyOneNull = (expected is null) != (subject is null); + bool onlyOneNull = expected is null != subject is null; if (onlyOneNull) { diff --git a/Src/FluentAssertions/Equivalency/Steps/StructuralEqualityEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/StructuralEqualityEquivalencyStep.cs index de1dee688c..498a63794f 100644 --- a/Src/FluentAssertions/Equivalency/Steps/StructuralEqualityEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/StructuralEqualityEquivalencyStep.cs @@ -18,23 +18,24 @@ public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationCon if (comparands.Expectation is null) { AssertionScope.Current - .BecauseOf(context.Reason) - .FailWith( - "Expected {context:subject} to be {reason}, but found {0}.", - comparands.Subject); + .BecauseOf(context.Reason) + .FailWith( + "Expected {context:subject} to be {reason}, but found {0}.", + comparands.Subject); } else if (comparands.Subject is null) { AssertionScope.Current - .BecauseOf(context.Reason) - .FailWith( - "Expected {context:object} to be {0}{reason}, but found {1}.", - comparands.Expectation, - comparands.Subject); + .BecauseOf(context.Reason) + .FailWith( + "Expected {context:object} to be {0}{reason}, but found {1}.", + comparands.Expectation, + comparands.Subject); } else { IMember[] selectedMembers = GetMembersFromExpectation(context.CurrentNode, comparands, context.Options).ToArray(); + if (context.CurrentNode.IsRoot && !selectedMembers.Any()) { throw new InvalidOperationException( @@ -55,6 +56,7 @@ private static void AssertMemberEquality(Comparands comparands, IEquivalencyVali IEquivalencyValidator parent, IMember selectedMember, IEquivalencyAssertionOptions options) { IMember matchingMember = FindMatchFor(selectedMember, context.CurrentNode, comparands.Subject, options); + if (matchingMember is not null) { var nestedComparands = new Comparands diff --git a/Src/FluentAssertions/Equivalency/Steps/ValueTypeEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/ValueTypeEquivalencyStep.cs index 1a620a7492..9340e807c7 100644 --- a/Src/FluentAssertions/Equivalency/Steps/ValueTypeEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/ValueTypeEquivalencyStep.cs @@ -7,18 +7,21 @@ namespace FluentAssertions.Equivalency.Steps; /// public class ValueTypeEquivalencyStep : IEquivalencyStep { - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { Type expectationType = comparands.GetExpectedType(context.Options); EqualityStrategy strategy = context.Options.GetEqualityStrategy(expectationType); bool canHandle = strategy is EqualityStrategy.Equals or EqualityStrategy.ForceEquals; + if (canHandle) { context.Tracer.WriteLine(member => { - string strategyName = (strategy == EqualityStrategy.Equals) - ? $"{expectationType} overrides Equals" : "we are forced to use Equals"; + string strategyName = strategy == EqualityStrategy.Equals + ? $"{expectationType} overrides Equals" + : "we are forced to use Equals"; return $"Treating {member.Description} as a value type because {strategyName}."; }); diff --git a/Src/FluentAssertions/Equivalency/Steps/XAttributeEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/XAttributeEquivalencyStep.cs index 8fe6a13044..b9ed03a5b7 100644 --- a/Src/FluentAssertions/Equivalency/Steps/XAttributeEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/XAttributeEquivalencyStep.cs @@ -4,7 +4,8 @@ namespace FluentAssertions.Equivalency.Steps; public class XAttributeEquivalencyStep : EquivalencyStep { - protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { var subject = (XAttribute)comparands.Subject; var expectation = (XAttribute)comparands.Expectation; diff --git a/Src/FluentAssertions/Equivalency/Steps/XDocumentEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/XDocumentEquivalencyStep.cs index c239827394..76f569bee3 100644 --- a/Src/FluentAssertions/Equivalency/Steps/XDocumentEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/XDocumentEquivalencyStep.cs @@ -4,7 +4,8 @@ namespace FluentAssertions.Equivalency.Steps; public class XDocumentEquivalencyStep : EquivalencyStep { - protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { var subject = (XDocument)comparands.Subject; var expectation = (XDocument)comparands.Expectation; diff --git a/Src/FluentAssertions/Equivalency/Steps/XElementEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/XElementEquivalencyStep.cs index 964273145c..022038ca6c 100644 --- a/Src/FluentAssertions/Equivalency/Steps/XElementEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/XElementEquivalencyStep.cs @@ -4,7 +4,8 @@ namespace FluentAssertions.Equivalency.Steps; public class XElementEquivalencyStep : EquivalencyStep { - protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { var subject = (XElement)comparands.Subject; var expectation = (XElement)comparands.Expectation; diff --git a/Src/FluentAssertions/Equivalency/Tracing/Tracer.cs b/Src/FluentAssertions/Equivalency/Tracing/Tracer.cs index c9e52e4a1a..465278ed81 100644 --- a/Src/FluentAssertions/Equivalency/Tracing/Tracer.cs +++ b/Src/FluentAssertions/Equivalency/Tracing/Tracer.cs @@ -47,5 +47,5 @@ public IDisposable WriteBlock(GetTraceMessage getTraceMessage) } } - public override string ToString() => (traceWriter is not null) ? traceWriter.ToString() : string.Empty; + public override string ToString() => traceWriter is not null ? traceWriter.ToString() : string.Empty; } diff --git a/Src/FluentAssertions/EquivalencyPlan.cs b/Src/FluentAssertions/EquivalencyPlan.cs index eff8980a0a..e7cbdb809b 100644 --- a/Src/FluentAssertions/EquivalencyPlan.cs +++ b/Src/FluentAssertions/EquivalencyPlan.cs @@ -53,6 +53,7 @@ public void AddAfter() int insertIndex = Math.Max(steps.Count - 1, 0); IEquivalencyStep predecessor = steps.LastOrDefault(s => s is TPredecessor); + if (predecessor is not null) { insertIndex = Math.Min(insertIndex, steps.LastIndexOf(predecessor) + 1); @@ -79,6 +80,7 @@ public void InsertBefore() int insertIndex = Math.Max(steps.Count - 1, 0); IEquivalencyStep equalityStep = steps.LastOrDefault(s => s is TSuccessor); + if (equalityStep is not null) { insertIndex = steps.LastIndexOf(equalityStep); @@ -111,7 +113,7 @@ public void Reset() private static List GetDefaultSteps() { - return new(18) + return new List(18) { new RunAllUserStepsEquivalencyStep(), new AutoConversionStep(), diff --git a/Src/FluentAssertions/EventRaisingExtensions.cs b/Src/FluentAssertions/EventRaisingExtensions.cs index f33781dbfc..b3e92228c0 100644 --- a/Src/FluentAssertions/EventRaisingExtensions.cs +++ b/Src/FluentAssertions/EventRaisingExtensions.cs @@ -29,11 +29,12 @@ public static IEventRecording WithSender(this IEventRecording eventRecording, ob bool hasSender = Execute.Assertion .ForCondition(@event.Parameters.Any()) .FailWith("Expected event from sender {0}, " + - $"but event {eventRecording.EventName} does not have any parameters", expectedSender); + $"but event {eventRecording.EventName} does not have any parameters", expectedSender); if (hasSender) { object sender = @event.Parameters.First(); + if (ReferenceEquals(sender, expectedSender)) { eventsForSender.Add(@event); @@ -119,6 +120,7 @@ public static IEventRecording WithArgs(this IEventRecording eventRecording, p } bool isMatch = hasArgumentOfRightType; + for (int index = 0; index < predicates.Length && isMatch; index++) { isMatch = compiledPredicates[index]?.Invoke(typedParameters[index]) ?? true; @@ -135,7 +137,8 @@ public static IEventRecording WithArgs(this IEventRecording eventRecording, p if (!foundMatchingEvent) { Execute.Assertion - .FailWith("Expected at least one event with some arguments of type <{0}> that pairwise match {1}, but found none.", + .FailWith( + "Expected at least one event with some arguments of type <{0}> that pairwise match {1}, but found none.", typeof(T), string.Join(" | ", predicates.Where(p => p is not null).Select(p => p.Body.ToString()))); } diff --git a/Src/FluentAssertions/Events/EventAssertions.cs b/Src/FluentAssertions/Events/EventAssertions.cs index 986889cf1c..8a5f28e820 100644 --- a/Src/FluentAssertions/Events/EventAssertions.cs +++ b/Src/FluentAssertions/Events/EventAssertions.cs @@ -19,7 +19,7 @@ public class EventAssertions : ReferenceTypeAssertions> protected internal EventAssertions(IMonitor monitor) : base(monitor.Subject) { - this.Monitor = monitor; + Monitor = monitor; } /// @@ -43,6 +43,7 @@ protected internal EventAssertions(IMonitor monitor) public IEventRecording Raise(string eventName, string because = "", params object[] becauseArgs) { IEventRecording recording = Monitor.GetRecordingFor(eventName); + if (!recording.Any()) { Execute.Assertion @@ -69,6 +70,7 @@ public IEventRecording Raise(string eventName, string because = "", params objec public void NotRaise(string eventName, string because = "", params object[] becauseArgs) { IEventRecording events = Monitor.GetRecordingFor(eventName); + if (events.Any()) { Execute.Assertion @@ -102,7 +104,8 @@ public IEventRecording RaisePropertyChangeFor(Expression> proper { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected object {0} to raise event {1} for property {2}{reason}, but it did not raise that event at all.", + .FailWith( + "Expected object {0} to raise event {1} for property {2}{reason}, but it did not raise that event at all.", Monitor.Subject, PropertyChangedEventName, propertyName); } diff --git a/Src/FluentAssertions/Events/EventMonitor.cs b/Src/FluentAssertions/Events/EventMonitor.cs index eb63581fcf..d23458af63 100644 --- a/Src/FluentAssertions/Events/EventMonitor.cs +++ b/Src/FluentAssertions/Events/EventMonitor.cs @@ -88,6 +88,7 @@ private void Attach(Type typeDefiningEventsToMonitor, Func utcNow) } EventInfo[] events = GetPublicEvents(typeDefiningEventsToMonitor); + if (!events.Any()) { throw new InvalidOperationException($"Type {typeDefiningEventsToMonitor.Name} does not expose any events."); @@ -127,6 +128,7 @@ private void AttachEventHandler(EventInfo eventInfo, Func utcNow) if (!recorderMap.TryGetValue(eventInfo.Name, out _)) { var recorder = new EventRecorder(subject.Target, eventInfo.Name, utcNow, threadSafeSequenceGenerator); + if (recorderMap.TryAdd(eventInfo.Name, recorder)) { recorder.Attach(subject, eventInfo); diff --git a/Src/FluentAssertions/Events/EventRecorder.cs b/Src/FluentAssertions/Events/EventRecorder.cs index a360e982be..4fa3410cae 100644 --- a/Src/FluentAssertions/Events/EventRecorder.cs +++ b/Src/FluentAssertions/Events/EventRecorder.cs @@ -26,7 +26,8 @@ internal sealed class EventRecorder : IEventRecording, IDisposable /// The name of the event that's recorded /// A delegate to get the current date and time in UTC format. /// Class used to generate a sequence in a thread-safe manner. - public EventRecorder(object eventRaiser, string eventName, Func utcNow, ThreadSafeSequenceGenerator sequenceGenerator) + public EventRecorder(object eventRaiser, string eventName, Func utcNow, + ThreadSafeSequenceGenerator sequenceGenerator) { this.utcNow = utcNow; EventObject = eventRaiser; diff --git a/Src/FluentAssertions/Execution/AssertionFailedException.cs b/Src/FluentAssertions/Execution/AssertionFailedException.cs index d8e4b3b3e9..391b67227c 100644 --- a/Src/FluentAssertions/Execution/AssertionFailedException.cs +++ b/Src/FluentAssertions/Execution/AssertionFailedException.cs @@ -1,5 +1,4 @@ using System; - using System.Runtime.Serialization; namespace FluentAssertions.Execution; @@ -8,7 +7,6 @@ namespace FluentAssertions.Execution; /// Represents the default exception in case no test framework is configured. /// [Serializable] - #pragma warning disable CA1032, RCS1194 // AssertionFailedException should never be constructed with an empty message public class AssertionFailedException : Exception #pragma warning restore CA1032, RCS1194 diff --git a/Src/FluentAssertions/Execution/AssertionScope.cs b/Src/FluentAssertions/Execution/AssertionScope.cs index 4dac024317..0b0be13621 100644 --- a/Src/FluentAssertions/Execution/AssertionScope.cs +++ b/Src/FluentAssertions/Execution/AssertionScope.cs @@ -20,7 +20,6 @@ public sealed class AssertionScope : IAssertionScope { #region Private Definitions - private readonly FormattingOptions formattingOptions = AssertionOptions.FormattingOptions.Clone(); private readonly IAssertionStrategy assertionStrategy; private readonly ContextDataItems contextData = new(); private readonly StringBuilder tracing = new(); @@ -40,7 +39,7 @@ private sealed class DeferredReportable public DeferredReportable(Func valueFunc) { - lazyValue = new(valueFunc); + lazyValue = new Lazy(valueFunc); } public override string ToString() => lazyValue.Value; @@ -100,7 +99,8 @@ public AssertionScope(Lazy context) private AssertionScope(IAssertionStrategy assertionStrategy, AssertionScope parent) { this.assertionStrategy = assertionStrategy - ?? throw new ArgumentNullException(nameof(assertionStrategy)); + ?? throw new ArgumentNullException(nameof(assertionStrategy)); + this.parent = parent; if (parent is not null) @@ -137,7 +137,7 @@ public AssertionScope UsingLineBreaks { get { - formattingOptions.UseLineBreaks = true; + FormattingOptions.UseLineBreaks = true; return this; } } @@ -145,7 +145,7 @@ public AssertionScope UsingLineBreaks /// /// Exposes the options the scope will use for formatting objects in case an assertion fails. /// - public FormattingOptions FormattingOptions => formattingOptions; + public FormattingOptions FormattingOptions { get; } = AssertionOptions.FormattingOptions.Clone(); internal bool Succeeded { @@ -168,13 +168,18 @@ public AssertionScope BecauseOf(string because, params object[] becauseArgs) try { string becauseOrEmpty = because ?? string.Empty; - return (becauseArgs?.Any() == true) ? string.Format(CultureInfo.InvariantCulture, becauseOrEmpty, becauseArgs) : becauseOrEmpty; + + return becauseArgs?.Any() == true + ? 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 + $"**WARNING** because message '{because}' could not be formatted with string.Format{Environment.NewLine}{formatException.StackTrace}"; } }; + return this; } @@ -182,9 +187,10 @@ public AssertionScope BecauseOf(string because, params object[] becauseArgs) public AssertionScope WithExpectation(string message, params object[] args) { Func localReason = reason; + expectation = () => { - var messageBuilder = new MessageBuilder(formattingOptions); + var messageBuilder = new MessageBuilder(FormattingOptions); string reason = localReason?.Invoke() ?? string.Empty; string identifier = GetIdentifier(); @@ -246,10 +252,13 @@ public Continuation FailWith(Func failReasonFunc) return FailWith(() => { string localReason = reason?.Invoke() ?? string.Empty; - var messageBuilder = new MessageBuilder(formattingOptions); + var messageBuilder = new MessageBuilder(FormattingOptions); string identifier = GetIdentifier(); FailReason failReason = failReasonFunc(); - string result = messageBuilder.Build(failReason.Message, failReason.Args, localReason, contextData, identifier, fallbackIdentifier); + + string result = messageBuilder.Build(failReason.Message, failReason.Args, localReason, contextData, identifier, + fallbackIdentifier); + return result; }); } @@ -262,6 +271,7 @@ private Continuation FailWith(Func failReasonFunc) try { bool failed = succeeded != true; + if (failed) { string result = failReasonFunc(); @@ -287,7 +297,7 @@ private Continuation FailWith(Func failReasonFunc) /// public Continuation FailWith(string message) { - return FailWith(() => new FailReason(message, new object[0])); + return FailWith(() => new FailReason(message)); } /// @@ -306,6 +316,7 @@ public Continuation FailWith(string message, params Func[] argProviders) private string GetIdentifier() { var identifier = Context?.Value; + if (string.IsNullOrEmpty(identifier)) { identifier = CallerIdentity; @@ -358,7 +369,8 @@ public void AddReportable(string key, string value) /// public void AddReportable(string key, Func valueFunc) { - contextData.Add(new ContextDataItems.DataItem(key, new DeferredReportable(valueFunc), reportable: true, requiresFormatting: false)); + contextData.Add(new ContextDataItems.DataItem(key, new DeferredReportable(valueFunc), reportable: true, + requiresFormatting: false)); } /// diff --git a/Src/FluentAssertions/Execution/CollectingAssertionStrategy.cs b/Src/FluentAssertions/Execution/CollectingAssertionStrategy.cs index e2e984ef5b..26ec686600 100644 --- a/Src/FluentAssertions/Execution/CollectingAssertionStrategy.cs +++ b/Src/FluentAssertions/Execution/CollectingAssertionStrategy.cs @@ -3,7 +3,6 @@ using System.Globalization; using System.Linq; using System.Text; - using FluentAssertions.Common; namespace FluentAssertions.Execution; diff --git a/Src/FluentAssertions/Execution/ContextDataItems.cs b/Src/FluentAssertions/Execution/ContextDataItems.cs index 5fef534a18..519200f7e4 100644 --- a/Src/FluentAssertions/Execution/ContextDataItems.cs +++ b/Src/FluentAssertions/Execution/ContextDataItems.cs @@ -19,6 +19,7 @@ public IDictionary GetReportable() public string AsStringOrDefault(string key) { DataItem item = items.SingleOrDefault(i => i.Key == key); + if (item is not null) { if (item.RequiresFormatting) @@ -80,7 +81,7 @@ public DataItem(string key, object value, bool reportable, bool requiresFormatti public DataItem Clone() { - object value = (Value is ICloneable2 cloneable) ? cloneable.Clone() : Value; + object value = Value is ICloneable2 cloneable ? cloneable.Clone() : Value; return new DataItem(Key, value, Reportable, RequiresFormatting); } } diff --git a/Src/FluentAssertions/Execution/ContinuationOfGiven.cs b/Src/FluentAssertions/Execution/ContinuationOfGiven.cs index 0825b02bf7..f080c83d08 100644 --- a/Src/FluentAssertions/Execution/ContinuationOfGiven.cs +++ b/Src/FluentAssertions/Execution/ContinuationOfGiven.cs @@ -5,19 +5,18 @@ namespace FluentAssertions.Execution; /// public class ContinuationOfGiven { - private readonly GivenSelector parent; private readonly bool succeeded; internal ContinuationOfGiven(GivenSelector parent, bool succeeded) { this.succeeded = succeeded; - this.parent = parent; + Then = parent; } /// /// Continuous the assertion chain if the previous assertion was successful. /// - public GivenSelector Then => parent; + public GivenSelector Then { get; } /// /// Provides back-wards compatibility for code that expects to return a boolean. diff --git a/Src/FluentAssertions/Execution/DefaultAssertionStrategy.cs b/Src/FluentAssertions/Execution/DefaultAssertionStrategy.cs index 2a2ef7e850..7e404e102d 100644 --- a/Src/FluentAssertions/Execution/DefaultAssertionStrategy.cs +++ b/Src/FluentAssertions/Execution/DefaultAssertionStrategy.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; - using FluentAssertions.Common; namespace FluentAssertions.Execution; diff --git a/Src/FluentAssertions/Execution/GivenSelectorExtensions.cs b/Src/FluentAssertions/Execution/GivenSelectorExtensions.cs index b7db0dcdda..2d32816641 100644 --- a/Src/FluentAssertions/Execution/GivenSelectorExtensions.cs +++ b/Src/FluentAssertions/Execution/GivenSelectorExtensions.cs @@ -19,38 +19,39 @@ public static ContinuationOfGiven> AssertEitherCollectionIsNotEmp this GivenSelector> givenSelector, int length) { return givenSelector - .ForCondition(items => (items.Count > 0) || (length == 0)) + .ForCondition(items => items.Count > 0 || length == 0) .FailWith("but found empty collection.") .Then - .ForCondition(items => (items.Count == 0) || (length > 0)) + .ForCondition(items => items.Count == 0 || length > 0) .FailWith("but found {0}.", items => items); } - public static ContinuationOfGiven> AssertCollectionHasEnoughItems(this GivenSelector> givenSelector, - int length) + public static ContinuationOfGiven> AssertCollectionHasEnoughItems( + this GivenSelector> givenSelector, int length) { return givenSelector .Given(items => items.ConvertOrCastToCollection()) .AssertCollectionHasEnoughItems(length); } - public static ContinuationOfGiven> AssertCollectionHasEnoughItems(this GivenSelector> givenSelector, int length) + public static ContinuationOfGiven> AssertCollectionHasEnoughItems( + this GivenSelector> givenSelector, int length) { return givenSelector .ForCondition(items => items.Count >= length) .FailWith("but {0} contains {1} item(s) less.", items => items, items => length - items.Count); } - public static ContinuationOfGiven> AssertCollectionHasNotTooManyItems(this GivenSelector> givenSelector, - int length) + public static ContinuationOfGiven> AssertCollectionHasNotTooManyItems( + this GivenSelector> givenSelector, int length) { return givenSelector .ForCondition(items => items.Count <= length) .FailWith("but {0} contains {1} item(s) too many.", items => items, items => items.Count - length); } - public static ContinuationOfGiven> AssertCollectionsHaveSameCount(this GivenSelector> givenSelector, - int length) + public static ContinuationOfGiven> AssertCollectionsHaveSameCount( + this GivenSelector> givenSelector, int length) { return givenSelector .AssertEitherCollectionIsNotEmpty(length) @@ -60,7 +61,8 @@ public static ContinuationOfGiven> AssertCollectionsHaveSameCount .AssertCollectionHasNotTooManyItems(length); } - public static ContinuationOfGiven> AssertCollectionsHaveSameItems(this GivenSelector> givenSelector, + public static ContinuationOfGiven> AssertCollectionsHaveSameItems( + this GivenSelector> givenSelector, ICollection expected, Func, ICollection, int> findIndex) { return givenSelector diff --git a/Src/FluentAssertions/Execution/LateBoundTestFramework.cs b/Src/FluentAssertions/Execution/LateBoundTestFramework.cs index 06bca61c42..ad40e206ff 100644 --- a/Src/FluentAssertions/Execution/LateBoundTestFramework.cs +++ b/Src/FluentAssertions/Execution/LateBoundTestFramework.cs @@ -13,6 +13,7 @@ internal abstract class LateBoundTestFramework : ITestFramework public void Throw(string message) { Type exceptionType = assembly.GetType(ExceptionFullName); + if (exceptionType is null) { throw new Exception( diff --git a/Src/FluentAssertions/Execution/MessageBuilder.cs b/Src/FluentAssertions/Execution/MessageBuilder.cs index 678fc6b95d..aed96ac9a6 100644 --- a/Src/FluentAssertions/Execution/MessageBuilder.cs +++ b/Src/FluentAssertions/Execution/MessageBuilder.cs @@ -30,7 +30,8 @@ public MessageBuilder(FormattingOptions formattingOptions) } // SMELL: Too many parameters. - public string Build(string message, object[] messageArgs, string reason, ContextDataItems contextData, string identifier, string fallbackIdentifier) + public string Build(string message, object[] messageArgs, string reason, ContextDataItems contextData, string identifier, + string fallbackIdentifier) { message = Regex.Replace(message, "{reason}", SanitizeReason(reason)); @@ -50,6 +51,7 @@ private static string SubstituteIdentifier(string message, string identifier, st message = Regex.Replace(message, pattern, match => { const string result = " "; + if (!string.IsNullOrEmpty(identifier)) { return result + identifier; @@ -97,7 +99,8 @@ private string FormatArgumentPlaceholders(string failureMessage, object[] failur } catch (FormatException formatException) { - return $"**WARNING** failure message '{failureMessage}' could not be formatted with string.Format{Environment.NewLine}{formatException.StackTrace}"; + return + $"**WARNING** failure message '{failureMessage}' could not be formatted with string.Format{Environment.NewLine}{formatException.StackTrace}"; } } @@ -135,6 +138,6 @@ private string ExtractLeadingBlanksFrom(string text) private bool StartsWithBlank(string text) { - return (text.Length > 0) && blanks.Contains(text[0]); + return text.Length > 0 && blanks.Contains(text[0]); } } diff --git a/Src/FluentAssertions/Execution/NSpecFramework.cs b/Src/FluentAssertions/Execution/NSpecFramework.cs index 04d25c330b..cd903275f3 100644 --- a/Src/FluentAssertions/Execution/NSpecFramework.cs +++ b/Src/FluentAssertions/Execution/NSpecFramework.cs @@ -32,6 +32,7 @@ public bool IsAvailable public void Throw(string message) { Type exceptionType = assembly.GetType("NSpec.Domain.AssertionException"); + if (exceptionType is null) { throw new Exception("Failed to create the NSpec assertion type"); diff --git a/Src/FluentAssertions/Execution/TestFrameworkProvider.cs b/Src/FluentAssertions/Execution/TestFrameworkProvider.cs index b8278a6d6e..486dede58e 100644 --- a/Src/FluentAssertions/Execution/TestFrameworkProvider.cs +++ b/Src/FluentAssertions/Execution/TestFrameworkProvider.cs @@ -52,6 +52,7 @@ private ITestFramework DetectFramework() private ITestFramework AttemptToDetectUsingAppSetting() { string frameworkName = configuration.TestFrameworkName; + if (string.IsNullOrEmpty(frameworkName)) { return null; @@ -60,7 +61,9 @@ private ITestFramework AttemptToDetectUsingAppSetting() if (!Frameworks.TryGetValue(frameworkName, out ITestFramework framework)) { string frameworks = string.Join(", ", Frameworks.Keys); - var message = $"FluentAssertions was configured to use the test framework '{frameworkName}' but this is not supported. " + + + var message = + $"FluentAssertions was configured to use the test framework '{frameworkName}' but this is not supported. " + $"Please use one of the supported frameworks: {frameworks}."; throw new InvalidOperationException(message); @@ -69,9 +72,11 @@ private ITestFramework AttemptToDetectUsingAppSetting() if (!framework.IsAvailable) { string frameworks = string.Join(", ", Frameworks.Keys); + var innerMessage = framework is LateBoundTestFramework lateBoundTestFramework ? $"the required assembly '{lateBoundTestFramework.AssemblyName}' could not be found" : "it could not be found"; + var message = $"FluentAssertions was configured to use the test framework '{frameworkName}' but {innerMessage}. " + $"Please use one of the supported frameworks: {frameworks}."; diff --git a/Src/FluentAssertions/Execution/XUnit2TestFramework.cs b/Src/FluentAssertions/Execution/XUnit2TestFramework.cs index 776148b64b..a9c993a2b0 100644 --- a/Src/FluentAssertions/Execution/XUnit2TestFramework.cs +++ b/Src/FluentAssertions/Execution/XUnit2TestFramework.cs @@ -33,6 +33,7 @@ public bool IsAvailable public void Throw(string message) { Type exceptionType = assembly.GetType("Xunit.Sdk.XunitException"); + if (exceptionType is null) { throw new Exception("Failed to create the XUnit assertion type"); diff --git a/Src/FluentAssertions/Extensions/FluentDateTimeExtensions.cs b/Src/FluentAssertions/Extensions/FluentDateTimeExtensions.cs index 3e7c82c0d2..a9068bad60 100644 --- a/Src/FluentAssertions/Extensions/FluentDateTimeExtensions.cs +++ b/Src/FluentAssertions/Extensions/FluentDateTimeExtensions.cs @@ -142,7 +142,8 @@ public static DateTime At(this DateTime date, TimeSpan time) /// Returns a new value for the specified and time with the specified /// , and optionally . /// - public static DateTime At(this DateTime date, int hours, int minutes, int seconds = 0, int milliseconds = 0, int microseconds = 0, int nanoseconds = 0) + public static DateTime At(this DateTime date, int hours, int minutes, int seconds = 0, int milliseconds = 0, + int microseconds = 0, int nanoseconds = 0) { if (microseconds is < 0 or > 999) { @@ -173,7 +174,8 @@ public static DateTime At(this DateTime date, int hours, int minutes, int second /// Returns a new value for the specified and time with the specified /// , and optionally . /// - public static DateTimeOffset At(this DateTimeOffset date, int hours, int minutes, int seconds = 0, int milliseconds = 0, int microseconds = 0, int nanoseconds = 0) + public static DateTimeOffset At(this DateTimeOffset date, int hours, int minutes, int seconds = 0, int milliseconds = 0, + int microseconds = 0, int nanoseconds = 0) { if (microseconds is < 0 or > 999) { diff --git a/Src/FluentAssertions/Formatting/AggregateExceptionValueFormatter.cs b/Src/FluentAssertions/Formatting/AggregateExceptionValueFormatter.cs index 048f6d448d..5c51953044 100644 --- a/Src/FluentAssertions/Formatting/AggregateExceptionValueFormatter.cs +++ b/Src/FluentAssertions/Formatting/AggregateExceptionValueFormatter.cs @@ -20,6 +20,7 @@ public bool CanHandle(object value) public void Format(object value, FormattedObjectGraph formattedGraph, FormattingContext context, FormatChild formatChild) { var exception = (AggregateException)value; + if (exception.InnerExceptions.Count == 1) { formattedGraph.AddFragment("(aggregated) "); diff --git a/Src/FluentAssertions/Formatting/AttributeBasedFormatter.cs b/Src/FluentAssertions/Formatting/AttributeBasedFormatter.cs index 15ce688e70..a73c5d94eb 100644 --- a/Src/FluentAssertions/Formatting/AttributeBasedFormatter.cs +++ b/Src/FluentAssertions/Formatting/AttributeBasedFormatter.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; - using FluentAssertions.Common; namespace FluentAssertions.Formatting; @@ -25,7 +24,7 @@ public class AttributeBasedFormatter : IValueFormatter /// public bool CanHandle(object value) { - return IsScanningEnabled && (value is not null) && (GetFormatter(value) is not null); + return IsScanningEnabled && value is not null && GetFormatter(value) is not null; } private static bool IsScanningEnabled @@ -37,7 +36,7 @@ public void Format(object value, FormattedObjectGraph formattedGraph, Formatting { MethodInfo method = GetFormatter(value); - object[] parameters = new[] { value, formattedGraph }; + object[] parameters = { value, formattedGraph }; method.Invoke(null, parameters); } @@ -45,6 +44,7 @@ public void Format(object value, FormattedObjectGraph formattedGraph, Formatting private MethodInfo GetFormatter(object value) { Type valueType = value.GetType(); + do { if (Formatters.TryGetValue(valueType, out var formatter)) @@ -89,8 +89,10 @@ where method.IsStatic where method.IsDecoratedWithOrInherit() let methodParameters = method.GetParameters() where methodParameters.Length == 2 - select new { Type = methodParameters.First().ParameterType, Method = method } into formatter - group formatter by formatter.Type into formatterGroup + select new { Type = methodParameters.First().ParameterType, Method = method } + into formatter + group formatter by formatter.Type + into formatterGroup select formatterGroup.First(); return query.ToDictionary(f => f.Type, f => f.Method); @@ -101,8 +103,8 @@ private static bool Applicable(Assembly assembly) Configuration configuration = Configuration.Current; ValueFormatterDetectionMode mode = configuration.ValueFormatterDetectionMode; - return (mode == ValueFormatterDetectionMode.Scan) || ( - (mode == ValueFormatterDetectionMode.Specific) && + return mode == ValueFormatterDetectionMode.Scan || ( + mode == ValueFormatterDetectionMode.Specific && assembly.FullName.Split(',')[0].Equals(configuration.ValueFormatterAssembly, StringComparison.OrdinalIgnoreCase)); } } diff --git a/Src/FluentAssertions/Formatting/DateOnlyValueFormatter.cs b/Src/FluentAssertions/Formatting/DateOnlyValueFormatter.cs index 39ec6cc6c2..c3b77fa28e 100644 --- a/Src/FluentAssertions/Formatting/DateOnlyValueFormatter.cs +++ b/Src/FluentAssertions/Formatting/DateOnlyValueFormatter.cs @@ -2,7 +2,6 @@ using System.Globalization; #if NET6_0_OR_GREATER - namespace FluentAssertions.Formatting; public class DateOnlyValueFormatter : IValueFormatter diff --git a/Src/FluentAssertions/Formatting/DateTimeOffsetValueFormatter.cs b/Src/FluentAssertions/Formatting/DateTimeOffsetValueFormatter.cs index 8a02cc856f..3fb53bd65e 100644 --- a/Src/FluentAssertions/Formatting/DateTimeOffsetValueFormatter.cs +++ b/Src/FluentAssertions/Formatting/DateTimeOffsetValueFormatter.cs @@ -36,12 +36,14 @@ public void Format(object value, FormattedObjectGraph formattedGraph, Formatting formattedGraph.AddFragment("<"); bool hasDate = HasDate(dateTimeOffset); + if (hasDate) { formattedGraph.AddFragment(dateTimeOffset.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)); } bool hasTime = HasTime(dateTimeOffset); + if (hasTime) { if (hasDate) @@ -103,9 +105,9 @@ public void Format(object value, FormattedObjectGraph formattedGraph, Formatting private static bool HasTime(DateTimeOffset dateTime) { - return (dateTime.Hour != 0) - || (dateTime.Minute != 0) - || (dateTime.Second != 0) + return dateTime.Hour != 0 + || dateTime.Minute != 0 + || dateTime.Second != 0 || HasMilliSeconds(dateTime) || HasMicroSeconds(dateTime) || HasNanoSeconds(dateTime); @@ -113,7 +115,7 @@ private static bool HasTime(DateTimeOffset dateTime) private static bool HasDate(DateTimeOffset dateTime) { - return (dateTime.Day != 1) || (dateTime.Month != 1) || (dateTime.Year != 1); + return dateTime.Day != 1 || dateTime.Month != 1 || dateTime.Year != 1; } private static bool HasMilliSeconds(DateTimeOffset dateTime) diff --git a/Src/FluentAssertions/Formatting/DefaultValueFormatter.cs b/Src/FluentAssertions/Formatting/DefaultValueFormatter.cs index bc6f549841..945c8e4ac5 100644 --- a/Src/FluentAssertions/Formatting/DefaultValueFormatter.cs +++ b/Src/FluentAssertions/Formatting/DefaultValueFormatter.cs @@ -77,6 +77,7 @@ private void WriteTypeAndMemberValues(object obj, FormattedObjectGraph formatted MemberInfo[] members = GetMembers(type); using var iterator = new Iterator(members.OrderBy(mi => mi.Name, StringComparer.Ordinal)); + while (iterator.MoveNext()) { WriteMemberValueTextFor(obj, iterator.Current, formattedGraph, formatChild); @@ -98,7 +99,8 @@ private void WriteTypeAndMemberValues(object obj, FormattedObjectGraph formatted /// The default is . protected virtual string TypeDisplayName(Type type) => type.FullName; - private static void WriteMemberValueTextFor(object value, MemberInfo member, FormattedObjectGraph formattedGraph, FormatChild formatChild) + private static void WriteMemberValueTextFor(object value, MemberInfo member, FormattedObjectGraph formattedGraph, + FormatChild formatChild) { object memberValue; diff --git a/Src/FluentAssertions/Formatting/DictionaryValueFormatter.cs b/Src/FluentAssertions/Formatting/DictionaryValueFormatter.cs index fcf618a4cc..acb428052c 100644 --- a/Src/FluentAssertions/Formatting/DictionaryValueFormatter.cs +++ b/Src/FluentAssertions/Formatting/DictionaryValueFormatter.cs @@ -33,6 +33,7 @@ public void Format(object value, FormattedObjectGraph formattedGraph, Formatting IEnumerable> collection = AsEnumerable((IDictionary)value); using var iterator = new Iterator>(collection, MaxItems); + while (iterator.MoveNext()) { if (iterator.IsFirst) @@ -86,6 +87,7 @@ private static void AddLineOrFragment(FormattedObjectGraph formattedGraph, int s private static IEnumerable> AsEnumerable(IDictionary dictionary) { IDictionaryEnumerator iterator = dictionary.GetEnumerator(); + using (iterator as IDisposable) { while (iterator.MoveNext()) diff --git a/Src/FluentAssertions/Formatting/EnumValueFormatter.cs b/Src/FluentAssertions/Formatting/EnumValueFormatter.cs index 01bd2a64db..516e3f2a88 100644 --- a/Src/FluentAssertions/Formatting/EnumValueFormatter.cs +++ b/Src/FluentAssertions/Formatting/EnumValueFormatter.cs @@ -22,6 +22,7 @@ public void Format(object value, FormattedObjectGraph formattedGraph, Formatting { string typePart = value.GetType().Name; string namePart = value.ToString().Replace(", ", "|", StringComparison.Ordinal); + string valuePart = Convert.ToDecimal(value, CultureInfo.InvariantCulture) .ToString(CultureInfo.InvariantCulture); diff --git a/Src/FluentAssertions/Formatting/EnumerableExtensions.cs b/Src/FluentAssertions/Formatting/EnumerableExtensions.cs index 51e18a4f7e..621ebebd62 100644 --- a/Src/FluentAssertions/Formatting/EnumerableExtensions.cs +++ b/Src/FluentAssertions/Formatting/EnumerableExtensions.cs @@ -9,7 +9,7 @@ internal static string JoinUsingWritingStyle(this IEnumerable items) { var buffer = new StringBuilder(); - T lastItem = default(T); + T lastItem = default; bool first = true; foreach (var item in items) diff --git a/Src/FluentAssertions/Formatting/EnumerableValueFormatter.cs b/Src/FluentAssertions/Formatting/EnumerableValueFormatter.cs index f0b95b60fc..cf9f8c3cff 100644 --- a/Src/FluentAssertions/Formatting/EnumerableValueFormatter.cs +++ b/Src/FluentAssertions/Formatting/EnumerableValueFormatter.cs @@ -33,6 +33,7 @@ public void Format(object value, FormattedObjectGraph formattedGraph, Formatting IEnumerable collection = ((IEnumerable)value).Cast(); using var iterator = new Iterator(collection, MaxItems); + while (iterator.MoveNext()) { if (iterator.IsFirst) diff --git a/Src/FluentAssertions/Formatting/FormattedObjectGraph.cs b/Src/FluentAssertions/Formatting/FormattedObjectGraph.cs index dc489ccf6b..93c5c4d29a 100644 --- a/Src/FluentAssertions/Formatting/FormattedObjectGraph.cs +++ b/Src/FluentAssertions/Formatting/FormattedObjectGraph.cs @@ -36,7 +36,7 @@ public FormattedObjectGraph(int maxLines) /// /// Returns the number of lines of text currently in the graph. /// - public int LineCount => lines.Count + ((lineBuilder.Length > 0) ? 1 : 0); + public int LineCount => lines.Count + (lineBuilder.Length > 0 ? 1 : 0); /// /// Starts a new line with the provided text fragment. Additional text can be added to @@ -90,6 +90,7 @@ private void AppendSafely(string line) if (lines.Count == maxLines) { lines.Add(string.Empty); + lines.Add( $"(Output has exceeded the maximum of {maxLines} lines. " + $"Increase {nameof(FormattingOptions)}.{nameof(FormattingOptions.MaxLines)} on {nameof(AssertionScope)} or {nameof(AssertionOptions)} to include more lines.)"); @@ -109,6 +110,7 @@ private void AppendSafely(string line) public IDisposable WithIndentation() { indentation++; + return new Disposable(() => { if (indentation > 0) diff --git a/Src/FluentAssertions/Formatting/Formatter.cs b/Src/FluentAssertions/Formatting/Formatter.cs index da81118ad6..e8baec4993 100644 --- a/Src/FluentAssertions/Formatting/Formatter.cs +++ b/Src/FluentAssertions/Formatting/Formatter.cs @@ -122,7 +122,8 @@ public static string ToString(object value, FormattingOptions options = null) } } - private static void FormatChild(string path, object value, FormattedObjectGraph output, FormattingContext context, FormattingOptions options, ObjectGraph graph) + private static void FormatChild(string path, object value, FormattedObjectGraph output, FormattingContext context, + FormattingOptions options, ObjectGraph graph) { try { @@ -135,7 +136,7 @@ private static void FormatChild(string path, object value, FormattedObjectGraph else if (graph.Depth > options.MaxDepth) { output.AddLine($"Maximum recursion depth of {options.MaxDepth} was reached. " + - $" Increase {nameof(FormattingOptions.MaxDepth)} on {nameof(AssertionScope)} or {nameof(AssertionOptions)} to get more details."); + $" Increase {nameof(FormattingOptions.MaxDepth)} on {nameof(AssertionScope)} or {nameof(AssertionOptions)} to get more details."); } else { diff --git a/Src/FluentAssertions/Formatting/FormattingOptions.cs b/Src/FluentAssertions/Formatting/FormattingOptions.cs index 205a54d9c3..370cfbc28b 100644 --- a/Src/FluentAssertions/Formatting/FormattingOptions.cs +++ b/Src/FluentAssertions/Formatting/FormattingOptions.cs @@ -25,7 +25,7 @@ public class FormattingOptions internal FormattingOptions Clone() { - return new() + return new FormattingOptions { UseLineBreaks = UseLineBreaks, MaxDepth = MaxDepth, diff --git a/Src/FluentAssertions/Formatting/MultidimensionalArrayFormatter.cs b/Src/FluentAssertions/Formatting/MultidimensionalArrayFormatter.cs index 5ab552b644..3bf43400df 100644 --- a/Src/FluentAssertions/Formatting/MultidimensionalArrayFormatter.cs +++ b/Src/FluentAssertions/Formatting/MultidimensionalArrayFormatter.cs @@ -47,6 +47,7 @@ public void Format(object value, FormattedObjectGraph formattedGraph, Formatting { enumerator.MoveNext(); formatChild(string.Join("-", dimensionIndices), enumerator.Current, formattedGraph); + if (!IsLastIteration(arr, currentDimensionIndex, currentLoopIndex)) { formattedGraph.AddFragment(", "); @@ -74,6 +75,7 @@ public void Format(object value, FormattedObjectGraph formattedGraph, Formatting } currentDimensionIndex = dimensionIndices[currentLoopIndex]; + if (!IsLastIteration(arr, currentDimensionIndex, currentLoopIndex)) { formattedGraph.AddFragment(", "); @@ -91,7 +93,7 @@ private static bool IsFirstIteration(Array arr, int index, int dimension) private static bool IsInnerMostLoop(Array arr, int index) { - return index == arr.Rank - 1; + return index == (arr.Rank - 1); } private static bool IsLastIteration(Array arr, int index, int dimension) diff --git a/Src/FluentAssertions/Formatting/PredicateLambdaExpressionValueFormatter.cs b/Src/FluentAssertions/Formatting/PredicateLambdaExpressionValueFormatter.cs index a05f1088fb..0313f1cc16 100644 --- a/Src/FluentAssertions/Formatting/PredicateLambdaExpressionValueFormatter.cs +++ b/Src/FluentAssertions/Formatting/PredicateLambdaExpressionValueFormatter.cs @@ -116,7 +116,7 @@ private static bool ExpressionIsConstant(Expression expression) /// private sealed class AndOperatorChainExtractor : ExpressionVisitor { - public List AndChain { get; } = new List(); + public List AndChain { get; } = new(); public override Expression Visit(Expression node) { diff --git a/Src/FluentAssertions/Formatting/TimeOnlyValueFormatter.cs b/Src/FluentAssertions/Formatting/TimeOnlyValueFormatter.cs index 7dab076414..ef8b8fd3a8 100644 --- a/Src/FluentAssertions/Formatting/TimeOnlyValueFormatter.cs +++ b/Src/FluentAssertions/Formatting/TimeOnlyValueFormatter.cs @@ -2,7 +2,6 @@ using System.Globalization; #if NET6_0_OR_GREATER - namespace FluentAssertions.Formatting; public class TimeOnlyValueFormatter : IValueFormatter diff --git a/Src/FluentAssertions/Formatting/TimeSpanValueFormatter.cs b/Src/FluentAssertions/Formatting/TimeSpanValueFormatter.cs index 71337bb5c3..4bd1343a4d 100644 --- a/Src/FluentAssertions/Formatting/TimeSpanValueFormatter.cs +++ b/Src/FluentAssertions/Formatting/TimeSpanValueFormatter.cs @@ -42,7 +42,7 @@ public void Format(object value, FormattedObjectGraph formattedGraph, Formatting formattedGraph.AddFragment("default"); } - string sign = (timeSpan.Ticks >= 0) ? string.Empty : "-"; + string sign = timeSpan.Ticks >= 0 ? string.Empty : "-"; if (fragments.Count == 1) { @@ -73,9 +73,10 @@ private static List GetNonZeroFragments(TimeSpan timeSpan) private static void AddMicrosecondsIfNotZero(TimeSpan timeSpan, List fragments) { var ticks = timeSpan.Ticks % TimeSpan.TicksPerMillisecond; + if (ticks > 0) { - var microSeconds = ticks / (double)TimeSpan.TicksPerMillisecond * 1000; + var microSeconds = ticks * (1000.0 / TimeSpan.TicksPerMillisecond); fragments.Add(microSeconds.ToString("0.0", CultureInfo.InvariantCulture) + "µs"); } } diff --git a/Src/FluentAssertions/Formatting/ValueFormatterAttribute.cs b/Src/FluentAssertions/Formatting/ValueFormatterAttribute.cs index 42c6cbe439..73c924daf4 100644 --- a/Src/FluentAssertions/Formatting/ValueFormatterAttribute.cs +++ b/Src/FluentAssertions/Formatting/ValueFormatterAttribute.cs @@ -5,7 +5,7 @@ namespace FluentAssertions.Formatting; /// /// Marks a static method as a kind of for a particular type. /// -[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Method)] public class ValueFormatterAttribute : Attribute { } diff --git a/Src/FluentAssertions/Numeric/ComparableTypeAssertions.cs b/Src/FluentAssertions/Numeric/ComparableTypeAssertions.cs index d9f3e6420b..79558d964a 100644 --- a/Src/FluentAssertions/Numeric/ComparableTypeAssertions.cs +++ b/Src/FluentAssertions/Numeric/ComparableTypeAssertions.cs @@ -248,7 +248,8 @@ public AndConstraint BeLessThanOrEqualTo(T expected, string because } [EditorBrowsable(EditorBrowsableState.Never)] - public AndConstraint BeLessOrEqualTo(T expected, string because = "", params object[] becauseArgs) => BeLessThanOrEqualTo(expected, because, becauseArgs); + public AndConstraint BeLessOrEqualTo(T expected, string because = "", params object[] becauseArgs) => + BeLessThanOrEqualTo(expected, because, becauseArgs); /// /// Asserts that the subject is greater than another object according to its implementation of . @@ -297,7 +298,8 @@ public AndConstraint BeGreaterThanOrEqualTo(T expected, string beca } [EditorBrowsable(EditorBrowsableState.Never)] - public AndConstraint BeGreaterOrEqualTo(T expected, string because = "", params object[] becauseArgs) => BeGreaterThanOrEqualTo(expected, because, becauseArgs); + public AndConstraint BeGreaterOrEqualTo(T expected, string because = "", params object[] becauseArgs) => + BeGreaterThanOrEqualTo(expected, because, becauseArgs); /// /// Asserts that a value is within a range. @@ -322,7 +324,7 @@ public AndConstraint BeInRange(T minimumValue, T maximumValue, stri params object[] becauseArgs) { Execute.Assertion - .ForCondition((Subject.CompareTo(minimumValue) >= Equal) && (Subject.CompareTo(maximumValue) <= Equal)) + .ForCondition(Subject.CompareTo(minimumValue) >= Equal && Subject.CompareTo(maximumValue) <= Equal) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:object} to be between {0} and {1}{reason}, but found {2}.", minimumValue, maximumValue, Subject); @@ -353,7 +355,7 @@ public AndConstraint NotBeInRange(T minimumValue, T maximumValue, s params object[] becauseArgs) { Execute.Assertion - .ForCondition(!((Subject.CompareTo(minimumValue) >= Equal) && (Subject.CompareTo(maximumValue) <= Equal))) + .ForCondition(!(Subject.CompareTo(minimumValue) >= Equal && Subject.CompareTo(maximumValue) <= Equal)) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:object} to not be between {0} and {1}{reason}, but found {2}.", minimumValue, maximumValue, Subject); diff --git a/Src/FluentAssertions/Numeric/DecimalAssertions.cs b/Src/FluentAssertions/Numeric/DecimalAssertions.cs index c9329750a4..0b0d91bf00 100644 --- a/Src/FluentAssertions/Numeric/DecimalAssertions.cs +++ b/Src/FluentAssertions/Numeric/DecimalAssertions.cs @@ -19,7 +19,7 @@ private protected override string CalculateDifferenceForFailureMessage(decimal s { try { - decimal difference = checked(subject - expected); + decimal difference = subject - expected; return difference != 0 ? difference.ToString(CultureInfo.InvariantCulture) : null; } catch (OverflowException) diff --git a/Src/FluentAssertions/Numeric/NullableDecimalAssertions.cs b/Src/FluentAssertions/Numeric/NullableDecimalAssertions.cs index 2075dbd8ac..3a2897eb16 100644 --- a/Src/FluentAssertions/Numeric/NullableDecimalAssertions.cs +++ b/Src/FluentAssertions/Numeric/NullableDecimalAssertions.cs @@ -19,7 +19,7 @@ private protected override string CalculateDifferenceForFailureMessage(decimal s { try { - decimal difference = checked(subject - expected); + decimal difference = subject - expected; return difference != 0 ? difference.ToString(CultureInfo.InvariantCulture) : null; } catch (OverflowException) diff --git a/Src/FluentAssertions/Numeric/NumericAssertions.cs b/Src/FluentAssertions/Numeric/NumericAssertions.cs index 10cb36bc78..eab57c3669 100644 --- a/Src/FluentAssertions/Numeric/NumericAssertions.cs +++ b/Src/FluentAssertions/Numeric/NumericAssertions.cs @@ -60,7 +60,8 @@ public AndConstraint Be(T expected, string because = "", params obj Execute.Assertion .ForCondition(Subject?.CompareTo(expected) == 0) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:value} to be {0}{reason}, but found {1}" + GenerateDifferenceMessage(expected), expected, Subject); + .FailWith("Expected {context:value} to be {0}{reason}, but found {1}" + GenerateDifferenceMessage(expected), expected, + Subject); return new AndConstraint((TAssertions)this); } @@ -81,7 +82,8 @@ public AndConstraint Be(T? expected, string because = "", params ob Execute.Assertion .ForCondition(expected is T value ? Subject?.CompareTo(value) == 0 : !Subject.HasValue) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:value} to be {0}{reason}, but found {1}" + GenerateDifferenceMessage(expected), expected, Subject); + .FailWith("Expected {context:value} to be {0}{reason}, but found {1}" + GenerateDifferenceMessage(expected), expected, + Subject); return new AndConstraint((TAssertions)this); } @@ -141,7 +143,7 @@ public AndConstraint NotBe(T? unexpected, string because = "", para public AndConstraint BePositive(string because = "", params object[] becauseArgs) { Execute.Assertion - .ForCondition(Subject?.CompareTo(default(T)) > 0) + .ForCondition(Subject?.CompareTo(default) > 0) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:value} to be positive{reason}, but found {0}.", Subject); @@ -161,7 +163,7 @@ public AndConstraint BePositive(string because = "", params object[ public AndConstraint BeNegative(string because = "", params object[] becauseArgs) { Execute.Assertion - .ForCondition(Subject is T value && !IsNaN(value) && value.CompareTo(default(T)) < 0) + .ForCondition(Subject is T value && !IsNaN(value) && value.CompareTo(default) < 0) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:value} to be negative{reason}, but found {0}.", Subject); @@ -189,7 +191,8 @@ public AndConstraint BeLessThan(T expected, string because = "", pa Execute.Assertion .ForCondition(Subject is T value && !IsNaN(value) && value.CompareTo(expected) < 0) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:value} to be less than {0}{reason}, but found {1}" + GenerateDifferenceMessage(expected), expected, Subject); + .FailWith("Expected {context:value} to be less than {0}{reason}, but found {1}" + GenerateDifferenceMessage(expected), + expected, Subject); return new AndConstraint((TAssertions)this); } @@ -216,13 +219,16 @@ public AndConstraint BeLessThanOrEqualTo(T expected, string because Execute.Assertion .ForCondition(Subject is T value && !IsNaN(value) && value.CompareTo(expected) <= 0) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:value} to be less than or equal to {0}{reason}, but found {1}" + GenerateDifferenceMessage(expected), expected, Subject); + .FailWith( + "Expected {context:value} to be less than or equal to {0}{reason}, but found {1}" + + GenerateDifferenceMessage(expected), expected, Subject); return new AndConstraint((TAssertions)this); } [EditorBrowsable(EditorBrowsableState.Never)] - public AndConstraint BeLessOrEqualTo(T expected, string because = "", params object[] becauseArgs) => BeLessThanOrEqualTo(expected, because, becauseArgs); + public AndConstraint BeLessOrEqualTo(T expected, string because = "", params object[] becauseArgs) => + BeLessThanOrEqualTo(expected, because, becauseArgs); /// /// Asserts that the numeric value is greater than the specified value. @@ -246,7 +252,9 @@ public AndConstraint BeGreaterThan(T expected, string because = "", Execute.Assertion .ForCondition(Subject?.CompareTo(expected) > 0) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:value} to be greater than {0}{reason}, but found {1}" + GenerateDifferenceMessage(expected), expected, Subject); + .FailWith( + "Expected {context:value} to be greater than {0}{reason}, but found {1}" + GenerateDifferenceMessage(expected), + expected, Subject); return new AndConstraint((TAssertions)this); } @@ -273,13 +281,16 @@ public AndConstraint BeGreaterThanOrEqualTo(T expected, string beca Execute.Assertion .ForCondition(Subject?.CompareTo(expected) >= 0) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:value} to be greater than or equal to {0}{reason}, but found {1}" + GenerateDifferenceMessage(expected), expected, Subject); + .FailWith( + "Expected {context:value} to be greater than or equal to {0}{reason}, but found {1}" + + GenerateDifferenceMessage(expected), expected, Subject); return new AndConstraint((TAssertions)this); } [EditorBrowsable(EditorBrowsableState.Never)] - public AndConstraint BeGreaterOrEqualTo(T expected, string because = "", params object[] becauseArgs) => BeGreaterThanOrEqualTo(expected, because, becauseArgs); + public AndConstraint BeGreaterOrEqualTo(T expected, string because = "", params object[] becauseArgs) => + BeGreaterThanOrEqualTo(expected, because, becauseArgs); /// /// Asserts that a value is within a range. @@ -309,7 +320,7 @@ public AndConstraint BeInRange(T minimumValue, T maximumValue, stri } Execute.Assertion - .ForCondition(Subject is T value && (value.CompareTo(minimumValue) >= 0) && (value.CompareTo(maximumValue) <= 0)) + .ForCondition(Subject is T value && value.CompareTo(minimumValue) >= 0 && value.CompareTo(maximumValue) <= 0) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:value} to be between {0} and {1}{reason}, but found {2}.", minimumValue, maximumValue, Subject); @@ -345,7 +356,7 @@ public AndConstraint NotBeInRange(T minimumValue, T maximumValue, s } Execute.Assertion - .ForCondition(Subject is T value && !((value.CompareTo(minimumValue) >= 0) && (value.CompareTo(maximumValue) <= 0))) + .ForCondition(Subject is T value && !(value.CompareTo(minimumValue) >= 0 && value.CompareTo(maximumValue) <= 0)) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:value} to not be between {0} and {1}{reason}, but found {2}.", minimumValue, maximumValue, Subject); @@ -407,6 +418,7 @@ public AndConstraint BeOfType(Type expectedType, string because = " Guard.ThrowIfArgumentIsNull(expectedType); Type subjectType = Subject?.GetType(); + if (expectedType.IsGenericTypeDefinition && subjectType?.IsGenericType == true) { (subjectType?.GetGenericTypeDefinition()).Should().Be(expectedType, because, becauseArgs); @@ -495,6 +507,7 @@ public override bool Equals(object obj) => private string GenerateDifferenceMessage(T? expected) { const string noDifferenceMessage = "."; + if (Subject is not T subject || expected is not T expectedValue) { return noDifferenceMessage; diff --git a/Src/FluentAssertions/NumericAssertionsExtensions.cs b/Src/FluentAssertions/NumericAssertionsExtensions.cs index 4716e88336..d96fb306b8 100644 --- a/Src/FluentAssertions/NumericAssertionsExtensions.cs +++ b/Src/FluentAssertions/NumericAssertionsExtensions.cs @@ -2,7 +2,6 @@ using FluentAssertions.Common; using FluentAssertions.Execution; using FluentAssertions.Numeric; -using FluentAssertions.Primitives; namespace FluentAssertions; @@ -36,18 +35,21 @@ public static AndConstraint> BeCloseTo(this NumericAsse { sbyte actualValue = parent.Subject.Value; sbyte minValue = (sbyte)(nearbyValue - delta); + if (minValue > nearbyValue) { minValue = sbyte.MinValue; } sbyte maxValue = (sbyte)(nearbyValue + delta); + if (maxValue < nearbyValue) { maxValue = sbyte.MaxValue; } - FailIfValueOutsideBounds(minValue <= actualValue && actualValue <= maxValue, nearbyValue, delta, actualValue, because, becauseArgs); + FailIfValueOutsideBounds(minValue <= actualValue && actualValue <= maxValue, nearbyValue, delta, actualValue, because, + becauseArgs); return new AndConstraint>(parent); } @@ -75,18 +77,21 @@ public static AndConstraint> BeCloseTo(this NumericAsser { byte actualValue = parent.Subject.Value; byte minValue = (byte)(nearbyValue - delta); + if (minValue > nearbyValue) { minValue = byte.MinValue; } byte maxValue = (byte)(nearbyValue + delta); + if (maxValue < nearbyValue) { maxValue = byte.MaxValue; } - FailIfValueOutsideBounds(minValue <= actualValue && actualValue <= maxValue, nearbyValue, delta, actualValue, because, becauseArgs); + FailIfValueOutsideBounds(minValue <= actualValue && actualValue <= maxValue, nearbyValue, delta, actualValue, because, + becauseArgs); return new AndConstraint>(parent); } @@ -114,18 +119,21 @@ public static AndConstraint> BeCloseTo(this NumericAsse { short actualValue = parent.Subject.Value; short minValue = (short)(nearbyValue - delta); + if (minValue > nearbyValue) { minValue = short.MinValue; } short maxValue = (short)(nearbyValue + delta); + if (maxValue < nearbyValue) { maxValue = short.MaxValue; } - FailIfValueOutsideBounds(minValue <= actualValue && actualValue <= maxValue, nearbyValue, delta, actualValue, because, becauseArgs); + FailIfValueOutsideBounds(minValue <= actualValue && actualValue <= maxValue, nearbyValue, delta, actualValue, because, + becauseArgs); return new AndConstraint>(parent); } @@ -153,18 +161,21 @@ public static AndConstraint> BeCloseTo(this NumericAss { ushort actualValue = parent.Subject.Value; ushort minValue = (ushort)(nearbyValue - delta); + if (minValue > nearbyValue) { minValue = ushort.MinValue; } ushort maxValue = (ushort)(nearbyValue + delta); + if (maxValue < nearbyValue) { maxValue = ushort.MaxValue; } - FailIfValueOutsideBounds(minValue <= actualValue && actualValue <= maxValue, nearbyValue, delta, actualValue, because, becauseArgs); + FailIfValueOutsideBounds(minValue <= actualValue && actualValue <= maxValue, nearbyValue, delta, actualValue, because, + becauseArgs); return new AndConstraint>(parent); } @@ -192,18 +203,21 @@ public static AndConstraint> BeCloseTo(this NumericAssert { int actualValue = parent.Subject.Value; int minValue = (int)(nearbyValue - delta); + if (minValue > nearbyValue) { minValue = int.MinValue; } int maxValue = (int)(nearbyValue + delta); + if (maxValue < nearbyValue) { maxValue = int.MaxValue; } - FailIfValueOutsideBounds(minValue <= actualValue && actualValue <= maxValue, nearbyValue, delta, actualValue, because, becauseArgs); + FailIfValueOutsideBounds(minValue <= actualValue && actualValue <= maxValue, nearbyValue, delta, actualValue, because, + becauseArgs); return new AndConstraint>(parent); } @@ -231,18 +245,21 @@ public static AndConstraint> BeCloseTo(this NumericAsser { uint actualValue = parent.Subject.Value; uint minValue = nearbyValue - delta; + if (minValue > nearbyValue) { minValue = uint.MinValue; } uint maxValue = nearbyValue + delta; + if (maxValue < nearbyValue) { maxValue = uint.MaxValue; } - FailIfValueOutsideBounds(minValue <= actualValue && actualValue <= maxValue, nearbyValue, delta, actualValue, because, becauseArgs); + FailIfValueOutsideBounds(minValue <= actualValue && actualValue <= maxValue, nearbyValue, delta, actualValue, because, + becauseArgs); return new AndConstraint>(parent); } @@ -272,7 +289,8 @@ public static AndConstraint> BeCloseTo(this NumericAsser long minValue = GetMinValue(nearbyValue, delta); long maxValue = GetMaxValue(nearbyValue, delta); - FailIfValueOutsideBounds(minValue <= actualValue && actualValue <= maxValue, nearbyValue, delta, actualValue, because, becauseArgs); + FailIfValueOutsideBounds(minValue <= actualValue && actualValue <= maxValue, nearbyValue, delta, actualValue, because, + becauseArgs); return new AndConstraint>(parent); } @@ -300,18 +318,21 @@ public static AndConstraint> BeCloseTo(this NumericAsse { ulong actualValue = parent.Subject.Value; ulong minValue = nearbyValue - delta; + if (minValue > nearbyValue) { minValue = ulong.MinValue; } ulong maxValue = nearbyValue + delta; + if (maxValue < nearbyValue) { maxValue = ulong.MaxValue; } - FailIfValueOutsideBounds(minValue <= actualValue && actualValue <= maxValue, nearbyValue, delta, actualValue, because, becauseArgs); + FailIfValueOutsideBounds(minValue <= actualValue && actualValue <= maxValue, nearbyValue, delta, actualValue, because, + becauseArgs); return new AndConstraint>(parent); } @@ -354,18 +375,21 @@ public static AndConstraint> NotBeCloseTo(this NumericA { sbyte actualValue = parent.Subject.Value; sbyte minValue = (sbyte)(distantValue - delta); + if (minValue > distantValue) { minValue = sbyte.MinValue; } sbyte maxValue = (sbyte)(distantValue + delta); + if (maxValue < distantValue) { maxValue = sbyte.MaxValue; } - FailIfValueInsideBounds(!(minValue <= actualValue && actualValue <= maxValue), distantValue, delta, actualValue, because, becauseArgs); + FailIfValueInsideBounds(!(minValue <= actualValue && actualValue <= maxValue), distantValue, delta, actualValue, because, + becauseArgs); return new AndConstraint>(parent); } @@ -393,18 +417,21 @@ public static AndConstraint> NotBeCloseTo(this NumericAs { byte actualValue = parent.Subject.Value; byte minValue = (byte)(distantValue - delta); + if (minValue > distantValue) { minValue = byte.MinValue; } byte maxValue = (byte)(distantValue + delta); + if (maxValue < distantValue) { maxValue = byte.MaxValue; } - FailIfValueInsideBounds(!(minValue <= actualValue && actualValue <= maxValue), distantValue, delta, actualValue, because, becauseArgs); + FailIfValueInsideBounds(!(minValue <= actualValue && actualValue <= maxValue), distantValue, delta, actualValue, because, + becauseArgs); return new AndConstraint>(parent); } @@ -432,18 +459,21 @@ public static AndConstraint> NotBeCloseTo(this NumericA { short actualValue = parent.Subject.Value; short minValue = (short)(distantValue - delta); + if (minValue > distantValue) { minValue = short.MinValue; } short maxValue = (short)(distantValue + delta); + if (maxValue < distantValue) { maxValue = short.MaxValue; } - FailIfValueInsideBounds(!(minValue <= actualValue && actualValue <= maxValue), distantValue, delta, actualValue, because, becauseArgs); + FailIfValueInsideBounds(!(minValue <= actualValue && actualValue <= maxValue), distantValue, delta, actualValue, because, + becauseArgs); return new AndConstraint>(parent); } @@ -471,18 +501,21 @@ public static AndConstraint> NotBeCloseTo(this Numeric { ushort actualValue = parent.Subject.Value; ushort minValue = (ushort)(distantValue - delta); + if (minValue > distantValue) { minValue = ushort.MinValue; } ushort maxValue = (ushort)(distantValue + delta); + if (maxValue < distantValue) { maxValue = ushort.MaxValue; } - FailIfValueInsideBounds(!(minValue <= actualValue && actualValue <= maxValue), distantValue, delta, actualValue, because, becauseArgs); + FailIfValueInsideBounds(!(minValue <= actualValue && actualValue <= maxValue), distantValue, delta, actualValue, because, + becauseArgs); return new AndConstraint>(parent); } @@ -510,18 +543,21 @@ public static AndConstraint> NotBeCloseTo(this NumericAss { int actualValue = parent.Subject.Value; int minValue = (int)(distantValue - delta); + if (minValue > distantValue) { minValue = int.MinValue; } int maxValue = (int)(distantValue + delta); + if (maxValue < distantValue) { maxValue = int.MaxValue; } - FailIfValueInsideBounds(!(minValue <= actualValue && actualValue <= maxValue), distantValue, delta, actualValue, because, becauseArgs); + FailIfValueInsideBounds(!(minValue <= actualValue && actualValue <= maxValue), distantValue, delta, actualValue, because, + becauseArgs); return new AndConstraint>(parent); } @@ -549,18 +585,21 @@ public static AndConstraint> NotBeCloseTo(this NumericAs { uint actualValue = parent.Subject.Value; uint minValue = distantValue - delta; + if (minValue > distantValue) { minValue = uint.MinValue; } uint maxValue = distantValue + delta; + if (maxValue < distantValue) { maxValue = uint.MaxValue; } - FailIfValueInsideBounds(!(minValue <= actualValue && actualValue <= maxValue), distantValue, delta, actualValue, because, becauseArgs); + FailIfValueInsideBounds(!(minValue <= actualValue && actualValue <= maxValue), distantValue, delta, actualValue, because, + becauseArgs); return new AndConstraint>(parent); } @@ -590,7 +629,8 @@ public static AndConstraint> NotBeCloseTo(this NumericAs long minValue = GetMinValue(distantValue, delta); long maxValue = GetMaxValue(distantValue, delta); - FailIfValueInsideBounds(!(minValue <= actualValue && actualValue <= maxValue), distantValue, delta, actualValue, because, becauseArgs); + FailIfValueInsideBounds(!(minValue <= actualValue && actualValue <= maxValue), distantValue, delta, actualValue, because, + becauseArgs); return new AndConstraint>(parent); } @@ -618,18 +658,21 @@ public static AndConstraint> NotBeCloseTo(this NumericA { ulong actualValue = parent.Subject.Value; ulong minValue = distantValue - delta; + if (minValue > distantValue) { minValue = ulong.MinValue; } ulong maxValue = distantValue + delta; + if (maxValue < distantValue) { maxValue = ulong.MaxValue; } - FailIfValueInsideBounds(!(minValue <= actualValue && actualValue <= maxValue), distantValue, delta, actualValue, because, becauseArgs); + FailIfValueInsideBounds(!(minValue <= actualValue && actualValue <= maxValue), distantValue, delta, actualValue, because, + becauseArgs); return new AndConstraint>(parent); } @@ -677,7 +720,8 @@ public static AndConstraint> BeApproximately(th bool success = Execute.Assertion .ForCondition(parent.Subject is not null) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:value} to approximate {0} +/- {1}{reason}, but it was .", expectedValue, precision); + .FailWith("Expected {context:value} to approximate {0} +/- {1}{reason}, but it was .", expectedValue, + precision); if (success) { @@ -721,7 +765,8 @@ public static AndConstraint> BeApproximately(th bool succeeded = Execute.Assertion .ForCondition(expectedValue is not null) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:value} to approximate {0} +/- {1}{reason}, but it was {2}.", expectedValue, precision, parent.Subject); + .FailWith("Expected {context:value} to approximate {0} +/- {1}{reason}, but it was {2}.", expectedValue, precision, + parent.Subject); if (succeeded) { @@ -763,17 +808,20 @@ public static AndConstraint> BeApproximately(this Numer if (float.IsPositiveInfinity(expectedValue)) { - FailIfDifferenceOutsidePrecision(float.IsPositiveInfinity(parent.Subject.Value), parent, expectedValue, precision, float.NaN, because, becauseArgs); + FailIfDifferenceOutsidePrecision(float.IsPositiveInfinity(parent.Subject.Value), parent, expectedValue, precision, + float.NaN, because, becauseArgs); } else if (float.IsNegativeInfinity(expectedValue)) { - FailIfDifferenceOutsidePrecision(float.IsNegativeInfinity(parent.Subject.Value), parent, expectedValue, precision, float.NaN, because, becauseArgs); + FailIfDifferenceOutsidePrecision(float.IsNegativeInfinity(parent.Subject.Value), parent, expectedValue, precision, + float.NaN, because, becauseArgs); } else { float actualDifference = Math.Abs(expectedValue - parent.Subject.Value); - FailIfDifferenceOutsidePrecision(actualDifference <= precision, parent, expectedValue, precision, actualDifference, because, becauseArgs); + FailIfDifferenceOutsidePrecision(actualDifference <= precision, parent, expectedValue, precision, actualDifference, + because, becauseArgs); } return new AndConstraint>(parent); @@ -806,7 +854,8 @@ public static AndConstraint> BeApproximately(t bool success = Execute.Assertion .ForCondition(parent.Subject is not null) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:value} to approximate {0} +/- {1}{reason}, but it was .", expectedValue, precision); + .FailWith("Expected {context:value} to approximate {0} +/- {1}{reason}, but it was .", expectedValue, + precision); if (success) { @@ -850,7 +899,8 @@ public static AndConstraint> BeApproximately(t bool succeeded = Execute.Assertion .ForCondition(expectedValue is not null) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:value} to approximate {0} +/- {1}{reason}, but it was {2}.", expectedValue, precision, parent.Subject); + .FailWith("Expected {context:value} to approximate {0} +/- {1}{reason}, but it was {2}.", expectedValue, precision, + parent.Subject); if (succeeded) { @@ -892,17 +942,20 @@ public static AndConstraint> BeApproximately(this Nume if (double.IsPositiveInfinity(expectedValue)) { - FailIfDifferenceOutsidePrecision(double.IsPositiveInfinity(parent.Subject.Value), parent, expectedValue, precision, double.NaN, because, becauseArgs); + FailIfDifferenceOutsidePrecision(double.IsPositiveInfinity(parent.Subject.Value), parent, expectedValue, precision, + double.NaN, because, becauseArgs); } else if (double.IsNegativeInfinity(expectedValue)) { - FailIfDifferenceOutsidePrecision(double.IsNegativeInfinity(parent.Subject.Value), parent, expectedValue, precision, double.NaN, because, becauseArgs); + FailIfDifferenceOutsidePrecision(double.IsNegativeInfinity(parent.Subject.Value), parent, expectedValue, precision, + double.NaN, because, becauseArgs); } else { double actualDifference = Math.Abs(expectedValue - parent.Subject.Value); - FailIfDifferenceOutsidePrecision(actualDifference <= precision, parent, expectedValue, precision, actualDifference, because, becauseArgs); + FailIfDifferenceOutsidePrecision(actualDifference <= precision, parent, expectedValue, precision, actualDifference, + because, becauseArgs); } return new AndConstraint>(parent); @@ -926,7 +979,8 @@ public static AndConstraint> BeApproximately(this Nume /// Zero or more objects to format using the placeholders in . /// /// is negative. - public static AndConstraint> BeApproximately(this NullableNumericAssertions parent, + public static AndConstraint> BeApproximately( + this NullableNumericAssertions parent, decimal expectedValue, decimal precision, string because = "", params object[] becauseArgs) { @@ -935,7 +989,8 @@ public static AndConstraint> BeApproximately( bool success = Execute.Assertion .ForCondition(parent.Subject is not null) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:value} to approximate {0} +/- {1}{reason}, but it was .", expectedValue, precision); + .FailWith("Expected {context:value} to approximate {0} +/- {1}{reason}, but it was .", expectedValue, + precision); if (success) { @@ -965,7 +1020,8 @@ public static AndConstraint> BeApproximately( /// Zero or more objects to format using the placeholders in . /// /// is negative. - public static AndConstraint> BeApproximately(this NullableNumericAssertions parent, + public static AndConstraint> BeApproximately( + this NullableNumericAssertions parent, decimal? expectedValue, decimal precision, string because = "", params object[] becauseArgs) { @@ -979,7 +1035,8 @@ public static AndConstraint> BeApproximately( bool succeeded = Execute.Assertion .ForCondition(expectedValue is not null) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:value} to approximate {0} +/- {1}{reason}, but it was {2}.", expectedValue, precision, parent.Subject); + .FailWith("Expected {context:value} to approximate {0} +/- {1}{reason}, but it was {2}.", expectedValue, precision, + parent.Subject); if (succeeded) { @@ -1016,7 +1073,8 @@ public static AndConstraint> BeApproximately(this Num decimal actualDifference = Math.Abs(expectedValue - parent.Subject.Value); - FailIfDifferenceOutsidePrecision(actualDifference <= precision, parent, expectedValue, precision, actualDifference, because, becauseArgs); + FailIfDifferenceOutsidePrecision(actualDifference <= precision, parent, expectedValue, precision, actualDifference, + because, becauseArgs); return new AndConstraint>(parent); } @@ -1096,7 +1154,7 @@ public static AndConstraint> NotBeApproximately { Guard.ThrowIfArgumentIsNegative(precision); - if ((parent.Subject is null) != (unexpectedValue is null)) + if (parent.Subject is null != unexpectedValue is null) { return new AndConstraint>(parent); } @@ -1104,7 +1162,8 @@ public static AndConstraint> NotBeApproximately bool succeeded = Execute.Assertion .ForCondition(parent.Subject is not null && unexpectedValue is not null) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:value} to not approximate {0} +/- {1}{reason}, but it was {2}.", unexpectedValue, precision, parent.Subject); + .FailWith("Expected {context:value} to not approximate {0} +/- {1}{reason}, but it was {2}.", unexpectedValue, + precision, parent.Subject); if (succeeded) { @@ -1146,17 +1205,20 @@ public static AndConstraint> NotBeApproximately(this Nu if (float.IsPositiveInfinity(unexpectedValue)) { - FailIfDifferenceWithinPrecision(parent, !float.IsPositiveInfinity(parent.Subject.Value), unexpectedValue, precision, float.NaN, because, becauseArgs); + FailIfDifferenceWithinPrecision(parent, !float.IsPositiveInfinity(parent.Subject.Value), unexpectedValue, precision, + float.NaN, because, becauseArgs); } else if (float.IsNegativeInfinity(unexpectedValue)) { - FailIfDifferenceWithinPrecision(parent, !float.IsNegativeInfinity(parent.Subject.Value), unexpectedValue, precision, float.NaN, because, becauseArgs); + FailIfDifferenceWithinPrecision(parent, !float.IsNegativeInfinity(parent.Subject.Value), unexpectedValue, precision, + float.NaN, because, becauseArgs); } else { float actualDifference = Math.Abs(unexpectedValue - parent.Subject.Value); - FailIfDifferenceWithinPrecision(parent, actualDifference > precision, unexpectedValue, precision, actualDifference, because, becauseArgs); + FailIfDifferenceWithinPrecision(parent, actualDifference > precision, unexpectedValue, precision, actualDifference, + because, becauseArgs); } return new AndConstraint>(parent); @@ -1180,7 +1242,8 @@ public static AndConstraint> NotBeApproximately(this Nu /// Zero or more objects to format using the placeholders in . /// /// - public static AndConstraint is negative.> NotBeApproximately(this NullableNumericAssertions parent, + public static AndConstraint> NotBeApproximately( + this NullableNumericAssertions parent, double unexpectedValue, double precision, string because = "", params object[] becauseArgs) { @@ -1214,13 +1277,14 @@ public static AndConstraint> NotBeApproximatel /// Zero or more objects to format using the placeholders in . /// /// - public static AndConstraint is negative.> NotBeApproximately(this NullableNumericAssertions parent, + public static AndConstraint> NotBeApproximately( + this NullableNumericAssertions parent, double? unexpectedValue, double precision, string because = "", params object[] becauseArgs) { Guard.ThrowIfArgumentIsNegative(precision); - if ((parent.Subject is null) != (unexpectedValue is null)) + if (parent.Subject is null != unexpectedValue is null) { return new AndConstraint>(parent); } @@ -1228,7 +1292,8 @@ public static AndConstraint> NotBeApproximatel bool succeeded = Execute.Assertion .ForCondition(parent.Subject is not null && unexpectedValue is not null) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:value} to not approximate {0} +/- {1}{reason}, but it was {2}.", unexpectedValue, precision, parent.Subject); + .FailWith("Expected {context:value} to not approximate {0} +/- {1}{reason}, but it was {2}.", unexpectedValue, + precision, parent.Subject); if (succeeded) { @@ -1270,17 +1335,20 @@ public static AndConstraint> NotBeApproximately(this N if (double.IsPositiveInfinity(unexpectedValue)) { - FailIfDifferenceWithinPrecision(parent, !double.IsPositiveInfinity(parent.Subject.Value), unexpectedValue, precision, double.NaN, because, becauseArgs); + FailIfDifferenceWithinPrecision(parent, !double.IsPositiveInfinity(parent.Subject.Value), unexpectedValue, precision, + double.NaN, because, becauseArgs); } else if (double.IsNegativeInfinity(unexpectedValue)) { - FailIfDifferenceWithinPrecision(parent, !double.IsNegativeInfinity(parent.Subject.Value), unexpectedValue, precision, double.NaN, because, becauseArgs); + FailIfDifferenceWithinPrecision(parent, !double.IsNegativeInfinity(parent.Subject.Value), unexpectedValue, precision, + double.NaN, because, becauseArgs); } else { double actualDifference = Math.Abs(unexpectedValue - parent.Subject.Value); - FailIfDifferenceWithinPrecision(parent, actualDifference > precision, unexpectedValue, precision, actualDifference, because, becauseArgs); + FailIfDifferenceWithinPrecision(parent, actualDifference > precision, unexpectedValue, precision, actualDifference, + because, becauseArgs); } return new AndConstraint>(parent); @@ -1304,7 +1372,8 @@ public static AndConstraint> NotBeApproximately(this N /// Zero or more objects to format using the placeholders in . /// /// - public static AndConstraint is negative.> NotBeApproximately(this NullableNumericAssertions parent, + public static AndConstraint> NotBeApproximately( + this NullableNumericAssertions parent, decimal unexpectedValue, decimal precision, string because = "", params object[] becauseArgs) { @@ -1338,13 +1407,14 @@ public static AndConstraint> NotBeApproximate /// Zero or more objects to format using the placeholders in . /// /// - public static AndConstraint is negative.> NotBeApproximately(this NullableNumericAssertions parent, + public static AndConstraint> NotBeApproximately( + this NullableNumericAssertions parent, decimal? unexpectedValue, decimal precision, string because = "", params object[] becauseArgs) { Guard.ThrowIfArgumentIsNegative(precision); - if ((parent.Subject is null) != (unexpectedValue is null)) + if (parent.Subject is null != unexpectedValue is null) { return new AndConstraint>(parent); } @@ -1352,7 +1422,8 @@ public static AndConstraint> NotBeApproximate bool succeeded = Execute.Assertion .ForCondition(parent.Subject is not null && unexpectedValue is not null) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:value} to not approximate {0} +/- {1}{reason}, but it was {2}.", unexpectedValue, precision, parent.Subject); + .FailWith("Expected {context:value} to not approximate {0} +/- {1}{reason}, but it was {2}.", unexpectedValue, + precision, parent.Subject); if (succeeded) { @@ -1389,7 +1460,8 @@ public static AndConstraint> NotBeApproximately(this decimal actualDifference = Math.Abs(unexpectedValue - parent.Subject.Value); - FailIfDifferenceWithinPrecision(parent, actualDifference > precision, unexpectedValue, precision, actualDifference, because, becauseArgs); + FailIfDifferenceWithinPrecision(parent, actualDifference > precision, unexpectedValue, precision, actualDifference, + because, becauseArgs); return new AndConstraint>(parent); } @@ -1411,11 +1483,11 @@ private static void FailIfDifferenceWithinPrecision( private static long GetMinValue(long value, ulong delta) { - long minValue = (delta <= ulong.MaxValue / 2) - ? (value - (long)delta) - : ((value < 0) - ? long.MinValue - : (-(long)(delta - (ulong)value))); + long minValue = delta <= (ulong.MaxValue / 2) + ? value - (long)delta + : value < 0 + ? long.MinValue + : -(long)(delta - (ulong)value); if (minValue > value) { @@ -1427,11 +1499,11 @@ private static long GetMinValue(long value, ulong delta) private static long GetMaxValue(long value, ulong delta) { - long maxValue = (delta <= ulong.MaxValue / 2) - ? (value + (long)delta) - : ((value >= 0) + long maxValue = delta <= (ulong.MaxValue / 2) + ? value + (long)delta + : value >= 0 ? long.MaxValue - : ((long)((ulong)value + delta))); + : (long)((ulong)value + delta); if (maxValue < value) { diff --git a/Src/FluentAssertions/ObjectAssertionsExtensions.cs b/Src/FluentAssertions/ObjectAssertionsExtensions.cs index 29fe4b2033..f856f5e922 100644 --- a/Src/FluentAssertions/ObjectAssertionsExtensions.cs +++ b/Src/FluentAssertions/ObjectAssertionsExtensions.cs @@ -115,7 +115,8 @@ public static AndConstraint BeDataContractSerializable(this Ob /// /// public static AndConstraint is . BeDataContractSerializable(this ObjectAssertions assertions, - Func, EquivalencyAssertionOptions> options, string because = "", params object[] becauseArgs) + Func, EquivalencyAssertionOptions> options, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(options); @@ -144,6 +145,7 @@ public static AndConstraint BeDataContractSerializable(this private static object CreateCloneUsingBinarySerializer(object subject) { using var stream = new MemoryStream(); + var binaryFormatter = new BinaryFormatter { Binder = new SimpleBinder(subject.GetType()) @@ -167,7 +169,7 @@ public SimpleBinder(Type type) public override Type BindToType(string assemblyName, string typeName) { - if ((type.FullName == typeName) && (type.Assembly.FullName == assemblyName)) + if (type.FullName == typeName && type.Assembly.FullName == assemblyName) { return type; } diff --git a/Src/FluentAssertions/Primitives/BooleanAssertions.cs b/Src/FluentAssertions/Primitives/BooleanAssertions.cs index 709ec3e397..446e0c34a1 100644 --- a/Src/FluentAssertions/Primitives/BooleanAssertions.cs +++ b/Src/FluentAssertions/Primitives/BooleanAssertions.cs @@ -145,7 +145,7 @@ public AndConstraint Imply(bool consequent, .FailWith("but it did not.") .Then .ClearExpectation(); - + return new AndConstraint((TAssertions)this); } diff --git a/Src/FluentAssertions/Primitives/DateOnlyAssertions.cs b/Src/FluentAssertions/Primitives/DateOnlyAssertions.cs index 84bb1189d2..0010847916 100644 --- a/Src/FluentAssertions/Primitives/DateOnlyAssertions.cs +++ b/Src/FluentAssertions/Primitives/DateOnlyAssertions.cs @@ -5,7 +5,6 @@ using FluentAssertions.Execution; #if NET6_0_OR_GREATER - namespace FluentAssertions.Primitives; /// @@ -330,7 +329,8 @@ public AndConstraint NotHaveYear(int unexpected, string because = " Execute.Assertion .BecauseOf(because, becauseArgs) .ForCondition(Subject.HasValue) - .FailWith("Did not expect the year part of {context:the date} to be {0}{reason}, but found a DateOnly.", unexpected) + .FailWith("Did not expect the year part of {context:the date} to be {0}{reason}, but found a DateOnly.", + unexpected) .Then .ForCondition(Subject.Value.Year != unexpected) .FailWith("Did not expect the year part of {context:the date} to be {0}{reason}, but it was.", unexpected, @@ -500,7 +500,8 @@ public AndConstraint BeOneOf(IEnumerable validValues, str /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint BeOneOf(IEnumerable validValues, string because = "", params object[] becauseArgs) + public AndConstraint BeOneOf(IEnumerable validValues, string because = "", + params object[] becauseArgs) { Execute.Assertion .ForCondition(validValues.Contains(Subject)) diff --git a/Src/FluentAssertions/Primitives/DateTimeAssertions.cs b/Src/FluentAssertions/Primitives/DateTimeAssertions.cs index 7903765477..c6c981c303 100644 --- a/Src/FluentAssertions/Primitives/DateTimeAssertions.cs +++ b/Src/FluentAssertions/Primitives/DateTimeAssertions.cs @@ -175,7 +175,7 @@ public AndConstraint BeCloseTo(DateTime nearbyTime, TimeSpan precis .ForCondition(Subject is not null) .FailWith(", but found .") .Then - .ForCondition((Subject >= minimumValue) && (Subject <= maximumValue)) + .ForCondition(Subject >= minimumValue && Subject <= maximumValue) .FailWith(", but {0} was off by {1}.", Subject, difference) .Then .ClearExpectation(); @@ -217,7 +217,7 @@ public AndConstraint NotBeCloseTo(DateTime distantTime, TimeSpan pr DateTime maximumValue = distantTime.AddTicks(Math.Min(precision.Ticks, distanceToMaxInTicks)); Execute.Assertion - .ForCondition((Subject < minimumValue) || (Subject > maximumValue)) + .ForCondition(Subject < minimumValue || Subject > maximumValue) .BecauseOf(because, becauseArgs) .FailWith( "Did not expect {context:the date and time} to be within {0} from {1}{reason}, but it was {2}.", @@ -430,7 +430,8 @@ public AndConstraint NotHaveYear(int unexpected, string because = " Execute.Assertion .BecauseOf(because, becauseArgs) .ForCondition(Subject.HasValue) - .FailWith("Did not expect the year part of {context:the date} to be {0}{reason}, but found a DateTime.", unexpected) + .FailWith("Did not expect the year part of {context:the date} to be {0}{reason}, but found a DateTime.", + unexpected) .Then .ForCondition(Subject.Value.Year != unexpected) .FailWith("Did not expect the year part of {context:the date} to be {0}{reason}, but it was.", unexpected, @@ -887,7 +888,8 @@ public AndConstraint BeOneOf(IEnumerable validValues, str /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint BeOneOf(IEnumerable validValues, string because = "", params object[] becauseArgs) + public AndConstraint BeOneOf(IEnumerable validValues, string because = "", + params object[] becauseArgs) { Execute.Assertion .ForCondition(validValues.Contains(Subject)) @@ -914,12 +916,12 @@ public AndConstraint BeIn(DateTimeKind expectedKind, string because { Execute.Assertion .BecauseOf(because, becauseArgs) - .WithExpectation("Expected {context:the date and time} to be in " + expectedKind.ToString() + "{reason}") + .WithExpectation("Expected {context:the date and time} to be in " + expectedKind + "{reason}") .ForCondition(Subject.HasValue) .FailWith(", but found a DateTime.") .Then .ForCondition(Subject.Value.Kind == expectedKind) - .FailWith(", but found " + Subject.Value.Kind.ToString() + ".") + .FailWith(", but found " + Subject.Value.Kind + ".") .Then .ClearExpectation(); diff --git a/Src/FluentAssertions/Primitives/DateTimeOffsetAssertions.cs b/Src/FluentAssertions/Primitives/DateTimeOffsetAssertions.cs index 1970b37ca2..ce56747d46 100644 --- a/Src/FluentAssertions/Primitives/DateTimeOffsetAssertions.cs +++ b/Src/FluentAssertions/Primitives/DateTimeOffsetAssertions.cs @@ -63,7 +63,8 @@ public AndConstraint Be(DateTimeOffset expected, string because = " { Execute.Assertion .BecauseOf(because, becauseArgs) - .WithExpectation("Expected {context:the date and time} to represent the same point in time as {0}{reason}, ", expected) + .WithExpectation("Expected {context:the date and time} to represent the same point in time as {0}{reason}, ", + expected) .ForCondition(Subject.HasValue) .FailWith("but found a DateTimeOffset.") .Then @@ -92,15 +93,16 @@ public AndConstraint Be(DateTimeOffset? expected, string because = if (!expected.HasValue) { Execute.Assertion - .BecauseOf(because, becauseArgs) - .ForCondition(!Subject.HasValue) - .FailWith("Expected {context:the date and time} to be {reason}, but it was {0}.", Subject); + .BecauseOf(because, becauseArgs) + .ForCondition(!Subject.HasValue) + .FailWith("Expected {context:the date and time} to be {reason}, but it was {0}.", Subject); } else { Execute.Assertion .BecauseOf(because, becauseArgs) - .WithExpectation("Expected {context:the date and time} to represent the same point in time as {0}{reason}, ", expected) + .WithExpectation("Expected {context:the date and time} to represent the same point in time as {0}{reason}, ", + expected) .ForCondition(Subject.HasValue) .FailWith("but found a DateTimeOffset.") .Then @@ -130,7 +132,9 @@ public AndConstraint NotBe(DateTimeOffset unexpected, string becaus Execute.Assertion .ForCondition(Subject != unexpected) .BecauseOf(because, becauseArgs) - .FailWith("Did not expect {context:the date and time} to represent the same point in time as {0}{reason}, but it did.", unexpected); + .FailWith( + "Did not expect {context:the date and time} to represent the same point in time as {0}{reason}, but it did.", + unexpected); return new AndConstraint((TAssertions)this); } @@ -152,7 +156,9 @@ public AndConstraint NotBe(DateTimeOffset? unexpected, string becau Execute.Assertion .ForCondition(Subject != unexpected) .BecauseOf(because, becauseArgs) - .FailWith("Did not expect {context:the date and time} to represent the same point in time as {0}{reason}, but it did.", unexpected); + .FailWith( + "Did not expect {context:the date and time} to represent the same point in time as {0}{reason}, but it did.", + unexpected); return new AndConstraint((TAssertions)this); } @@ -203,9 +209,9 @@ public AndConstraint BeExactly(DateTimeOffset? expected, string bec if (!expected.HasValue) { Execute.Assertion - .BecauseOf(because, becauseArgs) - .ForCondition(!Subject.HasValue) - .FailWith("Expected {context:the date and time} to be {reason}, but it was {0}.", Subject); + .BecauseOf(because, becauseArgs) + .ForCondition(!Subject.HasValue) + .FailWith("Expected {context:the date and time} to be {reason}, but it was {0}.", Subject); } else { @@ -262,7 +268,8 @@ public AndConstraint NotBeExactly(DateTimeOffset? unexpected, strin params object[] becauseArgs) { Execute.Assertion - .ForCondition(!((Subject == null && unexpected == null) || (Subject != null && unexpected != null && Subject.Value.EqualsExact(unexpected.Value)))) + .ForCondition(!((Subject == null && unexpected == null) || + (Subject != null && unexpected != null && Subject.Value.EqualsExact(unexpected.Value)))) .BecauseOf(because, becauseArgs) .FailWith("Did not expect {context:the date and time} to be exactly {0}{reason}, but it was.", unexpected); @@ -353,7 +360,7 @@ public AndConstraint NotBeCloseTo(DateTimeOffset distantTime, TimeS DateTimeOffset maximumValue = distantTime.AddTicks(Math.Min(precision.Ticks, distanceToMaxInTicks)); Execute.Assertion - .ForCondition((Subject < minimumValue) || (Subject > maximumValue)) + .ForCondition(Subject < minimumValue || Subject > maximumValue) .BecauseOf(because, becauseArgs) .FailWith( "Did not expect {context:the date and time} to be within {0} from {1}{reason}, but it was {2}.", @@ -1067,7 +1074,8 @@ public AndConstraint BeOneOf(params DateTimeOffset[] validValues) /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint BeOneOf(IEnumerable validValues, string because = "", params object[] becauseArgs) + public AndConstraint BeOneOf(IEnumerable validValues, string because = "", + params object[] becauseArgs) { return BeOneOf(validValues.Cast(), because, becauseArgs); } @@ -1085,7 +1093,8 @@ public AndConstraint BeOneOf(IEnumerable validValue /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint BeOneOf(IEnumerable validValues, string because = "", params object[] becauseArgs) + public AndConstraint BeOneOf(IEnumerable validValues, string because = "", + params object[] becauseArgs) { Execute.Assertion .ForCondition(validValues.Contains(Subject)) diff --git a/Src/FluentAssertions/Primitives/DateTimeOffsetRangeAssertions.cs b/Src/FluentAssertions/Primitives/DateTimeOffsetRangeAssertions.cs index 84134ae086..f1f8fa0632 100644 --- a/Src/FluentAssertions/Primitives/DateTimeOffsetRangeAssertions.cs +++ b/Src/FluentAssertions/Primitives/DateTimeOffsetRangeAssertions.cs @@ -24,8 +24,7 @@ public class DateTimeOffsetRangeAssertions private readonly TAssertions parentAssertions; private readonly TimeSpanPredicate predicate; - private readonly Dictionary predicates = new Dictionary - + private readonly Dictionary predicates = new() { [TimeSpanCondition.MoreThan] = new TimeSpanPredicate((ts1, ts2) => ts1 > ts2, "more than"), [TimeSpanCondition.AtLeast] = new TimeSpanPredicate((ts1, ts2) => ts1 >= ts2, "at least"), @@ -70,7 +69,7 @@ public AndConstraint Before(DateTimeOffset target, string because = .ForCondition(subject.HasValue) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:the date and time) to be " + predicate.DisplayText + - " {0} before {1}{reason}, but found a DateTime.", timeSpan, target); + " {0} before {1}{reason}, but found a DateTime.", timeSpan, target); if (success) { @@ -107,7 +106,7 @@ public AndConstraint After(DateTimeOffset target, string because = .ForCondition(subject.HasValue) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:the date and time} to be " + predicate.DisplayText + - " {0} after {1}{reason}, but found a DateTime.", timeSpan, target); + " {0} after {1}{reason}, but found a DateTime.", timeSpan, target); if (success) { @@ -127,7 +126,7 @@ public AndConstraint After(DateTimeOffset target, string because = private static string PositionRelativeToTarget(DateTimeOffset actual, DateTimeOffset target) { - return actual - target >= TimeSpan.Zero ? "ahead" : "behind"; + return (actual - target) >= TimeSpan.Zero ? "ahead" : "behind"; } /// diff --git a/Src/FluentAssertions/Primitives/DateTimeRangeAssertions.cs b/Src/FluentAssertions/Primitives/DateTimeRangeAssertions.cs index c42f06ecb8..6eb4fc7c8e 100644 --- a/Src/FluentAssertions/Primitives/DateTimeRangeAssertions.cs +++ b/Src/FluentAssertions/Primitives/DateTimeRangeAssertions.cs @@ -24,8 +24,7 @@ public class DateTimeRangeAssertions private readonly TAssertions parentAssertions; private readonly TimeSpanPredicate predicate; - private readonly Dictionary predicates = new Dictionary - + private readonly Dictionary predicates = new() { [TimeSpanCondition.MoreThan] = new TimeSpanPredicate((ts1, ts2) => ts1 > ts2, "more than"), [TimeSpanCondition.AtLeast] = new TimeSpanPredicate((ts1, ts2) => ts1 >= ts2, "at least"), @@ -70,7 +69,7 @@ public AndConstraint Before(DateTime target, string because = "", .ForCondition(subject.HasValue) .BecauseOf(because, becauseArgs) .FailWith("Expected date and/or time {0} to be " + predicate.DisplayText + - " {1} before {2}{reason}, but found a DateTime.", + " {1} before {2}{reason}, but found a DateTime.", subject, timeSpan, target); if (success) @@ -109,7 +108,7 @@ public AndConstraint After(DateTime target, string because = "", .ForCondition(subject.HasValue) .BecauseOf(because, becauseArgs) .FailWith("Expected date and/or time {0} to be " + predicate.DisplayText + - " {1} after {2}{reason}, but found a DateTime.", + " {1} after {2}{reason}, but found a DateTime.", subject, timeSpan, target); if (success) @@ -130,7 +129,7 @@ public AndConstraint After(DateTime target, string because = "", private static string PositionRelativeToTarget(DateTime actual, DateTime target) { - return actual - target >= TimeSpan.Zero ? "ahead" : "behind"; + return (actual - target) >= TimeSpan.Zero ? "ahead" : "behind"; } /// diff --git a/Src/FluentAssertions/Primitives/EnumAssertions.cs b/Src/FluentAssertions/Primitives/EnumAssertions.cs index c6bd3dcde1..604eb9f1c6 100644 --- a/Src/FluentAssertions/Primitives/EnumAssertions.cs +++ b/Src/FluentAssertions/Primitives/EnumAssertions.cs @@ -195,7 +195,7 @@ public AndConstraint NotBeDefined(string because = "", params objec public AndConstraint HaveValue(decimal expected, string because = "", params object[] becauseArgs) { Execute.Assertion - .ForCondition(Subject is TEnum value && (GetValue(value) == expected)) + .ForCondition(Subject is TEnum value && GetValue(value) == expected) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:the enum} to have value {0}{reason}, but found {1}.", expected, Subject); @@ -217,7 +217,7 @@ public AndConstraint HaveValue(decimal expected, string because = " public AndConstraint NotHaveValue(decimal unexpected, string because = "", params object[] becauseArgs) { Execute.Assertion - .ForCondition(!(Subject is TEnum value && (GetValue(value) == unexpected))) + .ForCondition(!(Subject is TEnum value && GetValue(value) == unexpected)) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:the enum} to not have value {0}{reason}, but found {1}.", unexpected, Subject); @@ -240,7 +240,7 @@ public AndConstraint HaveSameValueAs(T expected, string because where T : struct, Enum { Execute.Assertion - .ForCondition(Subject is TEnum value && (GetValue(value) == GetValue(expected))) + .ForCondition(Subject is TEnum value && GetValue(value) == GetValue(expected)) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:the enum} to have same value as {0}{reason}, but found {1}.", expected, Subject); @@ -263,7 +263,7 @@ public AndConstraint NotHaveSameValueAs(T unexpected, string bec where T : struct, Enum { Execute.Assertion - .ForCondition(!(Subject is TEnum value && (GetValue(value) == GetValue(unexpected)))) + .ForCondition(!(Subject is TEnum value && GetValue(value) == GetValue(unexpected))) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:the enum} to not have same value as {0}{reason}, but found {1}.", unexpected, Subject); @@ -286,7 +286,7 @@ public AndConstraint HaveSameNameAs(T expected, string because = where T : struct, Enum { Execute.Assertion - .ForCondition(Subject is TEnum value && (GetName(value) == GetName(expected))) + .ForCondition(Subject is TEnum value && GetName(value) == GetName(expected)) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:the enum} to have same name as {0}{reason}, but found {1}.", expected, Subject); @@ -309,7 +309,7 @@ public AndConstraint NotHaveSameNameAs(T unexpected, string beca where T : struct, Enum { Execute.Assertion - .ForCondition(!(Subject is TEnum value && (GetName(value) == GetName(unexpected)))) + .ForCondition(!(Subject is TEnum value && GetName(value) == GetName(unexpected))) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:the enum} to not have same name as {0}{reason}, but found {1}.", unexpected, Subject); @@ -417,8 +417,11 @@ public AndConstraint BeOneOf(params TEnum[] validValues) /// public AndConstraint is empty. BeOneOf(IEnumerable validValues, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(validValues, nameof(validValues), "Cannot assert that an enum is one of a null list of enums"); - Guard.ThrowIfArgumentIsEmpty(validValues, nameof(validValues), "Cannot assert that an enum is one of an empty list of enums"); + Guard.ThrowIfArgumentIsNull(validValues, nameof(validValues), + "Cannot assert that an enum is one of a null list of enums"); + + Guard.ThrowIfArgumentIsEmpty(validValues, nameof(validValues), + "Cannot assert that an enum is one of an empty list of enums"); Execute.Assertion .ForCondition(Subject is not null) diff --git a/Src/FluentAssertions/Primitives/HttpResponseMessageAssertions.cs b/Src/FluentAssertions/Primitives/HttpResponseMessageAssertions.cs index 5132d56eb6..49df342a49 100644 --- a/Src/FluentAssertions/Primitives/HttpResponseMessageAssertions.cs +++ b/Src/FluentAssertions/Primitives/HttpResponseMessageAssertions.cs @@ -209,7 +209,8 @@ public AndConstraint HaveStatusCode(HttpStatusCode expected, string /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint NotHaveStatusCode(HttpStatusCode unexpected, string because = "", params object[] becauseArgs) + public AndConstraint NotHaveStatusCode(HttpStatusCode unexpected, string because = "", + params object[] becauseArgs) { var success = Execute.Assertion .ForCondition(Subject is not null) diff --git a/Src/FluentAssertions/Primitives/NegatedStringStartValidator.cs b/Src/FluentAssertions/Primitives/NegatedStringStartValidator.cs index 7984256a8b..fa719a7327 100644 --- a/Src/FluentAssertions/Primitives/NegatedStringStartValidator.cs +++ b/Src/FluentAssertions/Primitives/NegatedStringStartValidator.cs @@ -33,6 +33,7 @@ private bool IgnoreCase protected override void ValidateAgainstMismatch() { bool isMatch = Subject.StartsWith(Expected, stringComparison); + if (isMatch) { Assertion.FailWith(ExpectationDescription + "{0}{reason}, but found {1}.", diff --git a/Src/FluentAssertions/Primitives/NullableDateOnlyAssertions.cs b/Src/FluentAssertions/Primitives/NullableDateOnlyAssertions.cs index 3e40f7b7fe..4c5262b463 100644 --- a/Src/FluentAssertions/Primitives/NullableDateOnlyAssertions.cs +++ b/Src/FluentAssertions/Primitives/NullableDateOnlyAssertions.cs @@ -3,7 +3,6 @@ using FluentAssertions.Execution; #if NET6_0_OR_GREATER - namespace FluentAssertions.Primitives; /// diff --git a/Src/FluentAssertions/Primitives/NullableTimeOnlyAssertions.cs b/Src/FluentAssertions/Primitives/NullableTimeOnlyAssertions.cs index b74ee53883..43ff35b01c 100644 --- a/Src/FluentAssertions/Primitives/NullableTimeOnlyAssertions.cs +++ b/Src/FluentAssertions/Primitives/NullableTimeOnlyAssertions.cs @@ -3,7 +3,6 @@ using FluentAssertions.Execution; #if NET6_0_OR_GREATER - namespace FluentAssertions.Primitives; /// diff --git a/Src/FluentAssertions/Primitives/ObjectAssertions.cs b/Src/FluentAssertions/Primitives/ObjectAssertions.cs index ceb8898663..499d137fb9 100644 --- a/Src/FluentAssertions/Primitives/ObjectAssertions.cs +++ b/Src/FluentAssertions/Primitives/ObjectAssertions.cs @@ -210,6 +210,7 @@ public AndConstraint NotBeEquivalentTo( Guard.ThrowIfArgumentIsNull(config); bool hasMismatches; + using (var scope = new AssertionScope()) { Subject.Should().BeEquivalentTo(unexpected, config); diff --git a/Src/FluentAssertions/Primitives/ReferenceTypeAssertions.cs b/Src/FluentAssertions/Primitives/ReferenceTypeAssertions.cs index 03b2bb3550..71509fde21 100644 --- a/Src/FluentAssertions/Primitives/ReferenceTypeAssertions.cs +++ b/Src/FluentAssertions/Primitives/ReferenceTypeAssertions.cs @@ -128,7 +128,7 @@ public AndWhichConstraint BeOfType(string because = "", param { BeOfType(typeof(T), because, becauseArgs); - T typedSubject = (Subject is T type) + T typedSubject = Subject is T type ? type : default; @@ -162,6 +162,7 @@ public AndConstraint BeOfType(Type expectedType, string because = " if (success) { Type subjectType = Subject.GetType(); + if (expectedType.IsGenericTypeDefinition && subjectType.IsGenericType) { subjectType.GetGenericTypeDefinition().Should().Be(expectedType, because, becauseArgs); @@ -220,6 +221,7 @@ public AndConstraint NotBeOfType(Type unexpectedType, string becaus if (success) { Type subjectType = Subject.GetType(); + if (unexpectedType.IsGenericTypeDefinition && subjectType.IsGenericType) { subjectType.GetGenericTypeDefinition().Should().NotBe(unexpectedType, because, becauseArgs); @@ -262,7 +264,7 @@ public AndWhichConstraint BeAssignableTo(string because = "", .FailWith("Expected {context} to be assignable to {0}{reason}, but {1} is not.", typeof(T), Subject.GetType()); } - T typedSubject = (Subject is T type) + T typedSubject = Subject is T type ? type : default; diff --git a/Src/FluentAssertions/Primitives/SimpleTimeSpanAssertions.cs b/Src/FluentAssertions/Primitives/SimpleTimeSpanAssertions.cs index 4cd2f401ba..1493f10a06 100644 --- a/Src/FluentAssertions/Primitives/SimpleTimeSpanAssertions.cs +++ b/Src/FluentAssertions/Primitives/SimpleTimeSpanAssertions.cs @@ -166,7 +166,8 @@ public AndConstraint BeLessThanOrEqualTo(TimeSpan expected, string } [EditorBrowsable(EditorBrowsableState.Never)] - public AndConstraint BeLessOrEqualTo(TimeSpan expected, string because = "", params object[] becauseArgs) => BeLessThanOrEqualTo(expected, because, becauseArgs); + public AndConstraint BeLessOrEqualTo(TimeSpan expected, string because = "", params object[] becauseArgs) => + BeLessThanOrEqualTo(expected, because, becauseArgs); /// [DebuggerNonUserCode] -public class ExceptionAssertions /// Asserts that the time difference of the current is greater than the @@ -214,7 +215,8 @@ public AndConstraint BeGreaterThanOrEqualTo(TimeSpan expected, stri } [EditorBrowsable(EditorBrowsableState.Never)] - public AndConstraint BeGreaterOrEqualTo(TimeSpan expected, string because = "", params object[] becauseArgs) => BeGreaterThanOrEqualTo(expected, because, becauseArgs); + public AndConstraint BeGreaterOrEqualTo(TimeSpan expected, string because = "", params object[] becauseArgs) => + BeGreaterThanOrEqualTo(expected, because, becauseArgs); /// [DebuggerNonUserCode] -public abstract class DelegateAssertionsBase /// Asserts that the current is within the specified time @@ -247,7 +249,7 @@ public AndConstraint BeCloseTo(TimeSpan nearbyTime, TimeSpan precis TimeSpan maximumValue = nearbyTime + precision; Execute.Assertion - .ForCondition((Subject >= minimumValue) && (Subject.Value <= maximumValue)) + .ForCondition(Subject >= minimumValue && Subject.Value <= maximumValue) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:time} to be within {0} from {1}{reason}, but found {2}.", precision, diff --git a/Src/FluentAssertions/Primitives/StringAssertions.cs b/Src/FluentAssertions/Primitives/StringAssertions.cs index 69622f4ec7..4cc4e3c540 100644 --- a/Src/FluentAssertions/Primitives/StringAssertions.cs +++ b/Src/FluentAssertions/Primitives/StringAssertions.cs @@ -53,7 +53,9 @@ public StringAssertions(string value) /// public AndConstraint Be(string expected, string because = "", params object[] becauseArgs) { - var stringEqualityValidator = new StringEqualityValidator(Subject, expected, StringComparison.Ordinal, because, becauseArgs); + var stringEqualityValidator = + new StringEqualityValidator(Subject, expected, StringComparison.Ordinal, because, becauseArgs); + stringEqualityValidator.Validate(); return new AndConstraint((TAssertions)this); @@ -136,6 +138,7 @@ public AndConstraint NotBeEquivalentTo(string unexpected, string be params object[] becauseArgs) { bool notEquivalent; + using (var scope = new AssertionScope()) { Subject.Should().BeEquivalentTo(unexpected); @@ -209,8 +212,11 @@ public AndConstraint NotBe(string unexpected, string because = "", /// public AndConstraint is empty. Match(string wildcardPattern, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(wildcardPattern, nameof(wildcardPattern), "Cannot match string against . Provide a wildcard pattern or use the BeNull method."); - Guard.ThrowIfArgumentIsEmpty(wildcardPattern, nameof(wildcardPattern), "Cannot match string against an empty string. Provide a wildcard pattern or use the BeEmpty method."); + Guard.ThrowIfArgumentIsNull(wildcardPattern, nameof(wildcardPattern), + "Cannot match string against . Provide a wildcard pattern or use the BeNull method."); + + Guard.ThrowIfArgumentIsEmpty(wildcardPattern, nameof(wildcardPattern), + "Cannot match string against an empty string. Provide a wildcard pattern or use the BeEmpty method."); var stringWildcardMatchingValidator = new StringWildcardMatchingValidator(Subject, wildcardPattern, because, becauseArgs); stringWildcardMatchingValidator.Validate(); @@ -255,8 +261,11 @@ public AndConstraint Match(string wildcardPattern, string because = /// public AndConstraint is empty. NotMatch(string wildcardPattern, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(wildcardPattern, nameof(wildcardPattern), "Cannot match string against . Provide a wildcard pattern or use the NotBeNull method."); - Guard.ThrowIfArgumentIsEmpty(wildcardPattern, nameof(wildcardPattern), "Cannot match string against an empty string. Provide a wildcard pattern or use the NotBeEmpty method."); + Guard.ThrowIfArgumentIsNull(wildcardPattern, nameof(wildcardPattern), + "Cannot match string against . Provide a wildcard pattern or use the NotBeNull method."); + + Guard.ThrowIfArgumentIsEmpty(wildcardPattern, nameof(wildcardPattern), + "Cannot match string against an empty string. Provide a wildcard pattern or use the NotBeEmpty method."); new StringWildcardMatchingValidator(Subject, wildcardPattern, because, becauseArgs) { @@ -304,8 +313,11 @@ public AndConstraint NotMatch(string wildcardPattern, string becaus public AndConstraint MatchEquivalentOf(string wildcardPattern, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(wildcardPattern, nameof(wildcardPattern), "Cannot match string against . Provide a wildcard pattern or use the BeNull method."); - Guard.ThrowIfArgumentIsEmpty(wildcardPattern, nameof(wildcardPattern), "Cannot match string against an empty string. Provide a wildcard pattern or use the BeEmpty method."); + Guard.ThrowIfArgumentIsNull(wildcardPattern, nameof(wildcardPattern), + "Cannot match string against . Provide a wildcard pattern or use the BeNull method."); + + Guard.ThrowIfArgumentIsEmpty(wildcardPattern, nameof(wildcardPattern), + "Cannot match string against an empty string. Provide a wildcard pattern or use the BeEmpty method."); var validator = new StringWildcardMatchingValidator(Subject, wildcardPattern, because, becauseArgs) { @@ -356,8 +368,11 @@ public AndConstraint MatchEquivalentOf(string wildcardPattern, stri public AndConstraint NotMatchEquivalentOf(string wildcardPattern, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(wildcardPattern, nameof(wildcardPattern), "Cannot match string against . Provide a wildcard pattern or use the NotBeNull method."); - Guard.ThrowIfArgumentIsEmpty(wildcardPattern, nameof(wildcardPattern), "Cannot match string against an empty string. Provide a wildcard pattern or use the NotBeEmpty method."); + Guard.ThrowIfArgumentIsNull(wildcardPattern, nameof(wildcardPattern), + "Cannot match string against . Provide a wildcard pattern or use the NotBeNull method."); + + Guard.ThrowIfArgumentIsEmpty(wildcardPattern, nameof(wildcardPattern), + "Cannot match string against an empty string. Provide a wildcard pattern or use the NotBeEmpty method."); var validator = new StringWildcardMatchingValidator(Subject, wildcardPattern, because, becauseArgs) { @@ -391,13 +406,14 @@ public AndConstraint NotMatchEquivalentOf(string wildcardPattern, s /// Zero or more objects to format using the placeholders in . /// /// - public AndConstraint is . MatchRegex([RegexPattern][StringSyntax("Regex")] string regularExpression, + public AndConstraint MatchRegex([RegexPattern] [StringSyntax("Regex")] string regularExpression, OccurrenceConstraint occurrenceConstraint, string because = "", params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(regularExpression, nameof(regularExpression), "Cannot match string against . Provide a regex pattern or use the BeNull method."); Regex regex; + try { regex = new Regex(regularExpression); @@ -406,6 +422,7 @@ public AndConstraint MatchRegex([RegexPattern][StringSyntax("Regex" { Execute.Assertion.FailWith("Cannot match {context:string} against {0} because it is not a valid regular expression.", regularExpression); + return new AndConstraint((TAssertions)this); } @@ -426,12 +443,14 @@ public AndConstraint MatchRegex([RegexPattern][StringSyntax("Regex" /// Zero or more objects to format using the placeholders in . /// /// - public AndConstraint is . MatchRegex([RegexPattern][StringSyntax("Regex")] string regularExpression, + public AndConstraint MatchRegex([RegexPattern] [StringSyntax("Regex")] string regularExpression, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(regularExpression, nameof(regularExpression), "Cannot match string against . Provide a regex pattern or use the BeNull method."); + Guard.ThrowIfArgumentIsNull(regularExpression, nameof(regularExpression), + "Cannot match string against . Provide a regex pattern or use the BeNull method."); Regex regex; + try { regex = new Regex(regularExpression); @@ -440,6 +459,7 @@ public AndConstraint MatchRegex([RegexPattern][StringSyntax("Regex" { Execute.Assertion.FailWith("Cannot match {context:string} against {0} because it is not a valid regular expression.", regularExpression); + return new AndConstraint((TAssertions)this); } @@ -474,7 +494,9 @@ public AndConstraint MatchRegex(Regex regularExpression, "Cannot match string against . Provide a regex pattern or use the BeNull method."); var regexStr = regularExpression.ToString(); - Guard.ThrowIfArgumentIsEmpty(regexStr, nameof(regularExpression), "Cannot match string against an empty string. Provide a regex pattern or use the BeEmpty method."); + + Guard.ThrowIfArgumentIsEmpty(regexStr, nameof(regularExpression), + "Cannot match string against an empty string. Provide a regex pattern or use the BeEmpty method."); bool success = Execute.Assertion .ForCondition(Subject is not null) @@ -520,7 +542,9 @@ public AndConstraint MatchRegex(Regex regularExpression, "Cannot match string against . Provide a regex pattern or use the BeNull method."); var regexStr = regularExpression.ToString(); - Guard.ThrowIfArgumentIsEmpty(regexStr, nameof(regularExpression), "Cannot match string against an empty string. Provide a regex pattern or use the BeEmpty method."); + + Guard.ThrowIfArgumentIsEmpty(regexStr, nameof(regularExpression), + "Cannot match string against an empty string. Provide a regex pattern or use the BeEmpty method."); bool success = Execute.Assertion .ForCondition(Subject is not null) @@ -554,12 +578,14 @@ public AndConstraint MatchRegex(Regex regularExpression, /// Zero or more objects to format using the placeholders in . /// /// - public AndConstraint is . NotMatchRegex([RegexPattern][StringSyntax("Regex")] string regularExpression, + public AndConstraint NotMatchRegex([RegexPattern] [StringSyntax("Regex")] string regularExpression, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(regularExpression, nameof(regularExpression), "Cannot match string against . Provide a regex pattern or use the NotBeNull method."); + Guard.ThrowIfArgumentIsNull(regularExpression, nameof(regularExpression), + "Cannot match string against . Provide a regex pattern or use the NotBeNull method."); Regex regex; + try { regex = new Regex(regularExpression); @@ -568,6 +594,7 @@ public AndConstraint NotMatchRegex([RegexPattern][StringSyntax("Reg { Execute.Assertion.FailWith("Cannot match {context:string} against {0} because it is not a valid regular expression.", regularExpression); + return new AndConstraint((TAssertions)this); } @@ -595,7 +622,9 @@ public AndConstraint NotMatchRegex(Regex regularExpression, string "Cannot match string against . Provide a regex pattern or use the NotBeNull method."); var regexStr = regularExpression.ToString(); - Guard.ThrowIfArgumentIsEmpty(regexStr, nameof(regularExpression), "Cannot match string against an empty regex pattern. Provide a regex pattern or use the NotBeEmpty method."); + + Guard.ThrowIfArgumentIsEmpty(regexStr, nameof(regularExpression), + "Cannot match string against an empty regex pattern. Provide a regex pattern or use the NotBeEmpty method."); bool success = Execute.Assertion .ForCondition(Subject is not null) @@ -655,7 +684,9 @@ public AndConstraint NotStartWith(string unexpected, string because { Guard.ThrowIfArgumentIsNull(unexpected, nameof(unexpected), "Cannot compare start of string with ."); - var negatedStringStartValidator = new NegatedStringStartValidator(Subject, unexpected, StringComparison.Ordinal, because, becauseArgs); + var negatedStringStartValidator = + new NegatedStringStartValidator(Subject, unexpected, StringComparison.Ordinal, because, becauseArgs); + negatedStringStartValidator.Validate(); return new AndConstraint((TAssertions)this); @@ -679,7 +710,9 @@ public AndConstraint StartWithEquivalentOf(string expected, string { Guard.ThrowIfArgumentIsNull(expected, nameof(expected), "Cannot compare string start equivalence with ."); - var stringStartValidator = new StringStartValidator(Subject, expected, StringComparison.OrdinalIgnoreCase, because, becauseArgs); + var stringStartValidator = + new StringStartValidator(Subject, expected, StringComparison.OrdinalIgnoreCase, because, becauseArgs); + stringStartValidator.Validate(); return new AndConstraint((TAssertions)this); @@ -698,11 +731,14 @@ public AndConstraint StartWithEquivalentOf(string expected, string /// Zero or more objects to format using the placeholders in . /// /// - public AndConstraint is . NotStartWithEquivalentOf(string unexpected, string because = "", params object[] becauseArgs) + public AndConstraint NotStartWithEquivalentOf(string unexpected, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(unexpected, nameof(unexpected), "Cannot compare start of string with ."); - var negatedStringStartValidator = new NegatedStringStartValidator(Subject, unexpected, StringComparison.OrdinalIgnoreCase, because, becauseArgs); + var negatedStringStartValidator = + new NegatedStringStartValidator(Subject, unexpected, StringComparison.OrdinalIgnoreCase, because, becauseArgs); + negatedStringStartValidator.Validate(); return new AndConstraint((TAssertions)this); @@ -914,7 +950,8 @@ public AndConstraint Contain(string expected, string because = "", /// /// /// - public AndConstraint is . is empty. Contain(string expected, OccurrenceConstraint occurrenceConstraint, string because = "", params object[] becauseArgs) + public AndConstraint Contain(string expected, OccurrenceConstraint occurrenceConstraint, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(expected, nameof(expected), "Cannot assert string containment against ."); Guard.ThrowIfArgumentIsEmpty(expected, nameof(expected), "Cannot assert string containment against an empty string."); @@ -980,7 +1017,8 @@ public AndConstraint ContainEquivalentOf(string expected, string be /// /// /// - public AndConstraint is . is empty. ContainEquivalentOf(string expected, OccurrenceConstraint occurrenceConstraint, string because = "", params object[] becauseArgs) + public AndConstraint ContainEquivalentOf(string expected, OccurrenceConstraint occurrenceConstraint, + string because = "", params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(expected, nameof(expected), "Cannot assert string containment against ."); Guard.ThrowIfArgumentIsEmpty(expected, nameof(expected), "Cannot assert string containment against an empty string."); @@ -1015,6 +1053,7 @@ public AndConstraint ContainAll(IEnumerable values, string ThrowIfValuesNullOrEmpty(values); IEnumerable missing = values.Where(v => !Contains(Subject, v, StringComparison.Ordinal)); + Execute.Assertion .ForCondition(values.All(v => Contains(Subject, v, StringComparison.Ordinal))) .BecauseOf(because, becauseArgs) diff --git a/Src/FluentAssertions/Primitives/StringEqualityValidator.cs b/Src/FluentAssertions/Primitives/StringEqualityValidator.cs index 83fc21d289..eb098e56a1 100644 --- a/Src/FluentAssertions/Primitives/StringEqualityValidator.cs +++ b/Src/FluentAssertions/Primitives/StringEqualityValidator.cs @@ -18,10 +18,10 @@ public StringEqualityValidator(string subject, string expected, StringComparison protected override bool ValidateAgainstSuperfluousWhitespace() { return Assertion - .ForCondition(!((Expected.Length > Subject.Length) && Expected.TrimEnd().Equals(Subject, comparisonMode))) + .ForCondition(!(Expected.Length > Subject.Length && Expected.TrimEnd().Equals(Subject, comparisonMode))) .FailWith(ExpectationDescription + "{0}{reason}, but it misses some extra whitespace at the end.", Expected) .Then - .ForCondition(!((Subject.Length > Expected.Length) && Subject.TrimEnd().Equals(Expected, comparisonMode))) + .ForCondition(!(Subject.Length > Expected.Length && Subject.TrimEnd().Equals(Expected, comparisonMode))) .FailWith(ExpectationDescription + "{0}{reason}, but it has unexpected whitespace at the end.", Expected); } @@ -34,7 +34,7 @@ protected override bool ValidateAgainstLengthDifferences() string mismatchSegment = GetMismatchSegmentForStringsOfDifferentLengths(); string message = ExpectationDescription + - "{0} with a length of {1}{reason}, but {2} has a length of {3}, differs near " + mismatchSegment + "."; + "{0} with a length of {1}{reason}, but {2} has a length of {3}, differs near " + mismatchSegment + "."; return new FailReason(message, Expected, Expected.Length, Subject, Subject.Length); }); @@ -60,6 +60,7 @@ private string GetMismatchSegmentForStringsOfDifferentLengths() protected override void ValidateAgainstMismatch() { int indexOfMismatch = Subject.IndexOfFirstMismatch(Expected, comparisonMode); + if (indexOfMismatch != -1) { Assertion.FailWith( diff --git a/Src/FluentAssertions/Primitives/StringStartValidator.cs b/Src/FluentAssertions/Primitives/StringStartValidator.cs index ce37991d20..727d645a74 100644 --- a/Src/FluentAssertions/Primitives/StringStartValidator.cs +++ b/Src/FluentAssertions/Primitives/StringStartValidator.cs @@ -41,6 +41,7 @@ protected override bool ValidateAgainstLengthDifferences() protected override void ValidateAgainstMismatch() { bool isMismatch = !Subject.StartsWith(Expected, stringComparison); + if (isMismatch) { int indexOfMismatch = Subject.IndexOfFirstMismatch(Expected, stringComparison); diff --git a/Src/FluentAssertions/Primitives/StringValidator.cs b/Src/FluentAssertions/Primitives/StringValidator.cs index fc0beb391e..fd4ad57083 100644 --- a/Src/FluentAssertions/Primitives/StringValidator.cs +++ b/Src/FluentAssertions/Primitives/StringValidator.cs @@ -30,7 +30,7 @@ protected StringValidator(string subject, string expected, string because, objec public void Validate() { - if ((Expected is not null) || (Subject is not null)) + if (Expected is not null || Subject is not null) { if (ValidateAgainstNulls()) { @@ -52,7 +52,7 @@ public void Validate() private bool ValidateAgainstNulls() { - if ((Expected is null) != (Subject is null)) + if (Expected is null != Subject is null) { Assertion.FailWith(ExpectationDescription + "{0}{reason}, but found {1}.", Expected, Subject); return false; @@ -63,7 +63,7 @@ private bool ValidateAgainstNulls() private static bool IsLongOrMultiline(string value) { - return (value.Length > HumanReadableLength) || value.Contains(Environment.NewLine, StringComparison.Ordinal); + return value.Length > HumanReadableLength || value.Contains(Environment.NewLine, StringComparison.Ordinal); } protected virtual bool ValidateAgainstSuperfluousWhitespace() diff --git a/Src/FluentAssertions/Primitives/StringWildcardMatchingValidator.cs b/Src/FluentAssertions/Primitives/StringWildcardMatchingValidator.cs index e39c38d37f..f1d1d447f4 100644 --- a/Src/FluentAssertions/Primitives/StringWildcardMatchingValidator.cs +++ b/Src/FluentAssertions/Primitives/StringWildcardMatchingValidator.cs @@ -1,7 +1,6 @@ using System; using System.Text; using System.Text.RegularExpressions; - using FluentAssertions.Common; namespace FluentAssertions.Primitives; @@ -30,7 +29,9 @@ protected override void ValidateAgainstMismatch() private bool IsMatch() { - RegexOptions options = IgnoreCase ? (RegexOptions.IgnoreCase | RegexOptions.CultureInvariant) : RegexOptions.None; + RegexOptions options = IgnoreCase + ? RegexOptions.IgnoreCase | RegexOptions.CultureInvariant + : RegexOptions.None; string input = CleanNewLines(Subject); string pattern = ConvertWildcardToRegEx(CleanNewLines(Expected)); @@ -42,8 +43,8 @@ private static string ConvertWildcardToRegEx(string wildcardExpression) { return "^" + Regex.Escape(wildcardExpression) - .Replace("\\*", ".*", StringComparison.Ordinal) - .Replace("\\?", ".", StringComparison.Ordinal) + .Replace("\\*", ".*", StringComparison.Ordinal) + .Replace("\\?", ".", StringComparison.Ordinal) + "$"; } diff --git a/Src/FluentAssertions/Primitives/TimeOnlyAssertions.cs b/Src/FluentAssertions/Primitives/TimeOnlyAssertions.cs index c6bb517e51..c1c49fa914 100644 --- a/Src/FluentAssertions/Primitives/TimeOnlyAssertions.cs +++ b/Src/FluentAssertions/Primitives/TimeOnlyAssertions.cs @@ -6,7 +6,6 @@ using FluentAssertions.Execution; #if NET6_0_OR_GREATER - namespace FluentAssertions.Primitives; /// internal class TimeSpanPredicate { - private readonly string displayText; private readonly Func @@ -151,7 +150,7 @@ public AndConstraint BeCloseTo(TimeOnly nearbyTime, TimeSpan precis { Guard.ThrowIfArgumentIsNegative(precision); - TimeSpan? difference = (Subject != null) + TimeSpan? difference = Subject != null ? MinimumDifference(Subject.Value, nearbyTime) : null; @@ -417,7 +416,8 @@ public AndConstraint NotHaveHours(int unexpected, string because = Execute.Assertion .BecauseOf(because, becauseArgs) .ForCondition(Subject.HasValue) - .FailWith("Did not expect the hours part of {context:the time} to be {0}{reason}, but found a TimeOnly.", unexpected) + .FailWith("Did not expect the hours part of {context:the time} to be {0}{reason}, but found a TimeOnly.", + unexpected) .Then .ForCondition(Subject.Value.Hour != unexpected) .FailWith("Did not expect the hours part of {context:the time} to be {0}{reason}, but it was.", unexpected, @@ -641,7 +641,8 @@ public AndConstraint BeOneOf(IEnumerable validValues, str /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint BeOneOf(IEnumerable validValues, string because = "", params object[] becauseArgs) + public AndConstraint BeOneOf(IEnumerable validValues, string because = "", + params object[] becauseArgs) { Execute.Assertion .ForCondition(validValues.Contains(Subject)) diff --git a/Src/FluentAssertions/Primitives/TimeSpanPredicate.cs b/Src/FluentAssertions/Primitives/TimeSpanPredicate.cs index 9cf183a088..9f8e68982c 100644 --- a/Src/FluentAssertions/Primitives/TimeSpanPredicate.cs +++ b/Src/FluentAssertions/Primitives/TimeSpanPredicate.cs @@ -7,16 +7,15 @@ namespace FluentAssertions.Primitives; /// lambda; public TimeSpanPredicate(Func lambda, string displayText) { this.lambda = lambda; - this.displayText = displayText; + DisplayText = displayText; } - public string DisplayText => displayText; + public string DisplayText { get; } public bool IsMatchedBy(TimeSpan actual, TimeSpan expected) { diff --git a/Src/FluentAssertions/Specialized/AssemblyAssertions.cs b/Src/FluentAssertions/Specialized/AssemblyAssertions.cs index d690a54d8f..02be9f6753 100644 --- a/Src/FluentAssertions/Specialized/AssemblyAssertions.cs +++ b/Src/FluentAssertions/Specialized/AssemblyAssertions.cs @@ -52,9 +52,9 @@ public AndConstraint NotReference(Assembly assembly, string IEnumerable references = Subject.GetReferencedAssemblies().Select(x => x.Name); Execute.Assertion - .BecauseOf(because, becauseArgs) - .ForCondition(!references.Contains(assemblyName)) - .FailWith("Expected assembly {0} not to reference assembly {1}{reason}.", subjectName, assemblyName); + .BecauseOf(because, becauseArgs) + .ForCondition(!references.Contains(assemblyName)) + .FailWith("Expected assembly {0} not to reference assembly {1}{reason}.", subjectName, assemblyName); } return new AndConstraint(this); @@ -90,9 +90,9 @@ public AndConstraint Reference(Assembly assembly, string bec IEnumerable references = Subject.GetReferencedAssemblies().Select(x => x.Name); Execute.Assertion - .BecauseOf(because, becauseArgs) - .ForCondition(references.Contains(assemblyName)) - .FailWith("Expected assembly {0} to reference assembly {1}{reason}, but it does not.", subjectName, assemblyName); + .BecauseOf(because, becauseArgs) + .ForCondition(references.Contains(assemblyName)) + .FailWith("Expected assembly {0} to reference assembly {1}{reason}, but it does not.", subjectName, assemblyName); } return new AndConstraint(this); @@ -112,7 +112,8 @@ public AndConstraint Reference(Assembly assembly, string bec /// /// /// - public AndWhichConstraint is . is empty. DefineType(string @namespace, string name, string because = "", params object[] becauseArgs) + public AndWhichConstraint DefineType(string @namespace, string name, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNullOrEmpty(name); diff --git a/Src/FluentAssertions/Specialized/AsyncFunctionAssertions.cs b/Src/FluentAssertions/Specialized/AsyncFunctionAssertions.cs index 6b71fdc0d4..aaf0233e31 100644 --- a/Src/FluentAssertions/Specialized/AsyncFunctionAssertions.cs +++ b/Src/FluentAssertions/Specialized/AsyncFunctionAssertions.cs @@ -60,6 +60,7 @@ public async Task> CompleteWithinAsync( if (success) { bool completesWithinTimeout = await CompletesWithinTimeoutAsync(task, remainingTime); + Execute.Assertion .ForCondition(completesWithinTimeout) .BecauseOf(because, becauseArgs) @@ -92,9 +93,11 @@ public async Task> NotCompleteWithinAsync( if (success) { (Task task, TimeSpan remainingTime) = InvokeWithTimer(timeSpan); + if (remainingTime >= TimeSpan.Zero) { bool completesWithinTimeout = await CompletesWithinTimeoutAsync(task, remainingTime); + Execute.Assertion .ForCondition(!completesWithinTimeout) .BecauseOf(because, becauseArgs) @@ -265,7 +268,8 @@ public async Task> NotThrowAsync(string b /// Zero or more objects to format using the placeholders in . /// /// - public Task or are negative.> NotThrowAfterAsync(TimeSpan waitTime, TimeSpan pollInterval, string because = "", params object[] becauseArgs) + public Task> NotThrowAfterAsync(TimeSpan waitTime, TimeSpan pollInterval, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNegative(waitTime); Guard.ThrowIfArgumentIsNegative(pollInterval); @@ -288,6 +292,7 @@ async Task> AssertionTaskAsync() while (invocationEndTime is null || invocationEndTime < waitTime) { exception = await InvokeWithInterceptionAsync(Subject); + if (exception is null) { return new AndConstraint((TAssertions)this); @@ -353,8 +358,8 @@ private static async Task InvokeWithInterceptionAsync(Func acti // If an assertion failure occurs, we want the message to talk about "subject" // not "await action". using (CallerIdentifier.OnlyOneFluentAssertionScopeOnCallStack() - ? CallerIdentifier.OverrideStackSearchUsingCurrentScope() - : default) + ? CallerIdentifier.OverrideStackSearchUsingCurrentScope() + : default) { await action(); } diff --git a/Src/FluentAssertions/Specialized/DelegateAssertions.cs b/Src/FluentAssertions/Specialized/DelegateAssertions.cs index 03bd49c569..3329c17799 100644 --- a/Src/FluentAssertions/Specialized/DelegateAssertions.cs +++ b/Src/FluentAssertions/Specialized/DelegateAssertions.cs @@ -176,7 +176,8 @@ public ExceptionAssertions ThrowExactly(string because = /// Zero or more objects to format using the placeholders in . /// /// - public AndConstraint or are negative. NotThrowAfter(TimeSpan waitTime, TimeSpan pollInterval, string because = "", params object[] becauseArgs) + public AndConstraint NotThrowAfter(TimeSpan waitTime, TimeSpan pollInterval, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNegative(waitTime); Guard.ThrowIfArgumentIsNegative(pollInterval); @@ -197,6 +198,7 @@ public AndConstraint NotThrowAfter(TimeSpan waitTime, TimeSpan poll while (invocationEndTime is null || invocationEndTime < waitTime) { exception = InvokeSubjectWithInterception(); + if (exception is null) { break; @@ -232,8 +234,8 @@ private Exception InvokeSubjectWithInterception() // If an assertion failure occurs, we want the message to talk about "subject" // not "action". using (CallerIdentifier.OnlyOneFluentAssertionScopeOnCallStack() - ? CallerIdentifier.OverrideStackSearchUsingCurrentScope() - : default) + ? CallerIdentifier.OverrideStackSearchUsingCurrentScope() + : default) { InvokeSubject(); } @@ -250,7 +252,8 @@ private void FailIfSubjectIsAsyncVoid() { if (Subject.GetMethodInfo().IsDecoratedWithOrInherit()) { - throw new InvalidOperationException("Cannot use action assertions on an async void method. Assign the async method to a variable of type Func instead of Action so that it can be awaited."); + throw new InvalidOperationException( + "Cannot use action assertions on an async void method. Assign the async method to a variable of type Func instead of Action so that it can be awaited."); } } } diff --git a/Src/FluentAssertions/Specialized/DelegateAssertionsBase.cs b/Src/FluentAssertions/Specialized/DelegateAssertionsBase.cs index 37b7e18cbb..29ab2635a0 100644 --- a/Src/FluentAssertions/Specialized/DelegateAssertionsBase.cs +++ b/Src/FluentAssertions/Specialized/DelegateAssertionsBase.cs @@ -12,7 +12,8 @@ namespace FluentAssertions.Specialized; /// Contains a number of methods to assert that a method yields the expected result. /// : ReferenceTypeAssertions> +public abstract class DelegateAssertionsBase + : ReferenceTypeAssertions> where TDelegate : Delegate where TAssertions : DelegateAssertionsBase { @@ -63,6 +64,7 @@ protected AndConstraint NotThrowInternal(Exception exce where TException : Exception { IEnumerable exceptions = extractor.OfType(exception); + Execute.Assertion .ForCondition(!exceptions.Any()) .BecauseOf(because, becauseArgs) diff --git a/Src/FluentAssertions/Specialized/ExceptionAssertions.cs b/Src/FluentAssertions/Specialized/ExceptionAssertions.cs index 0c74c4dab8..b665959082 100644 --- a/Src/FluentAssertions/Specialized/ExceptionAssertions.cs +++ b/Src/FluentAssertions/Specialized/ExceptionAssertions.cs @@ -15,8 +15,7 @@ namespace FluentAssertions.Specialized; /// Contains a number of methods to assert that an is in the correct state. /// : - ReferenceTypeAssertions, ExceptionAssertions> +public class ExceptionAssertions : ReferenceTypeAssertions, ExceptionAssertions> where TException : Exception { #region Private Definitions @@ -183,6 +182,7 @@ public ExceptionAssertions Where(Expression> Guard.ThrowIfArgumentIsNull(exceptionExpression); Func condition = exceptionExpression.Compile(); + Execute.Assertion .ForCondition(condition(SingleSubject)) .BecauseOf(because, becauseArgs) @@ -247,6 +247,7 @@ private TException SingleSubject if (Subject.Count() > 1) { string thrownExceptions = BuildExceptionsString(Subject); + Services.ThrowException( $"More than one exception was thrown. FluentAssertions cannot determine which Exception was meant.{Environment.NewLine}{thrownExceptions}"); } @@ -270,7 +271,7 @@ public ExceptionMessageAssertion() Context = "exception message"; } - public string Context { get; set; } + public string Context { get; } public void Execute(IEnumerable messages, string expectation, string because, params object[] becauseArgs) { @@ -298,6 +299,7 @@ public void Execute(IEnumerable messages, string expectation, string bec { string replacedCurlyBraces = failure.EscapePlaceholders(); + AssertionScope.Current.FailWith(replacedCurlyBraces); } } diff --git a/Src/FluentAssertions/Specialized/ExecutionTime.cs b/Src/FluentAssertions/Specialized/ExecutionTime.cs index effc11fb42..e3249e242b 100644 --- a/Src/FluentAssertions/Specialized/ExecutionTime.cs +++ b/Src/FluentAssertions/Specialized/ExecutionTime.cs @@ -40,6 +40,7 @@ protected ExecutionTime(Action action, string actionDescription, StartTimer crea ActionDescription = actionDescription; IsRunning = true; + Task = Task.Run(() => { // move stopwatch as close to action start as possible @@ -80,6 +81,7 @@ protected ExecutionTime(Func action, string actionDescription, StartTimer ActionDescription = actionDescription; IsRunning = true; + Task = Task.Run(async () => { // move stopwatch as close to action start as possible diff --git a/Src/FluentAssertions/Specialized/ExecutionTimeAssertions.cs b/Src/FluentAssertions/Specialized/ExecutionTimeAssertions.cs index 1b46cab029..13e848fc99 100644 --- a/Src/FluentAssertions/Specialized/ExecutionTimeAssertions.cs +++ b/Src/FluentAssertions/Specialized/ExecutionTimeAssertions.cs @@ -69,7 +69,8 @@ public ExecutionTimeAssertions(ExecutionTime executionTime) /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint BeLessThanOrEqualTo(TimeSpan maxDuration, string because = "", params object[] becauseArgs) + public AndConstraint BeLessThanOrEqualTo(TimeSpan maxDuration, string because = "", + params object[] becauseArgs) { bool Condition(TimeSpan duration) => duration <= maxDuration; (bool isRunning, TimeSpan elapsed) = PollUntil(Condition, expectedResult: false, rate: maxDuration); @@ -78,8 +79,9 @@ public AndConstraint BeLessThanOrEqualTo(TimeSpan maxDu .ForCondition(Condition(elapsed)) .BecauseOf(because, becauseArgs) .FailWith("Execution of " + - execution.ActionDescription.EscapePlaceholders() + " should be less than or equal to {0}{reason}, but it required " + - (isRunning ? "more than " : "exactly ") + "{1}.", + execution.ActionDescription.EscapePlaceholders() + + " should be less than or equal to {0}{reason}, but it required " + + (isRunning ? "more than " : "exactly ") + "{1}.", maxDuration, elapsed); @@ -87,7 +89,8 @@ public AndConstraint BeLessThanOrEqualTo(TimeSpan maxDu } [EditorBrowsable(EditorBrowsableState.Never)] - public AndConstraint BeLessOrEqualTo(TimeSpan maxDuration, string because = "", params object[] becauseArgs) => BeLessThanOrEqualTo(maxDuration, because, becauseArgs); + public AndConstraint BeLessOrEqualTo(TimeSpan maxDuration, string because = "", + params object[] becauseArgs) => BeLessThanOrEqualTo(maxDuration, because, becauseArgs); /// /// Asserts that the execution time of the operation is less than a specified amount of time. @@ -102,7 +105,8 @@ public AndConstraint BeLessThanOrEqualTo(TimeSpan maxDu /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint BeLessThan(TimeSpan maxDuration, string because = "", params object[] becauseArgs) + public AndConstraint BeLessThan(TimeSpan maxDuration, string because = "", + params object[] becauseArgs) { bool Condition(TimeSpan duration) => duration < maxDuration; (bool isRunning, TimeSpan elapsed) = PollUntil(Condition, expectedResult: false, rate: maxDuration); @@ -111,8 +115,8 @@ public AndConstraint BeLessThan(TimeSpan maxDuration, s .ForCondition(Condition(execution.ElapsedTime)) .BecauseOf(because, becauseArgs) .FailWith("Execution of " + - execution.ActionDescription.EscapePlaceholders() + " should be less than {0}{reason}, but it required " + - (isRunning ? "more than " : "exactly ") + "{1}.", + execution.ActionDescription.EscapePlaceholders() + " should be less than {0}{reason}, but it required " + + (isRunning ? "more than " : "exactly ") + "{1}.", maxDuration, elapsed); @@ -132,7 +136,8 @@ public AndConstraint BeLessThan(TimeSpan maxDuration, s /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint BeGreaterThanOrEqualTo(TimeSpan minDuration, string because = "", params object[] becauseArgs) + public AndConstraint BeGreaterThanOrEqualTo(TimeSpan minDuration, string because = "", + params object[] becauseArgs) { bool Condition(TimeSpan duration) => duration >= minDuration; (bool isRunning, TimeSpan elapsed) = PollUntil(Condition, expectedResult: true, rate: minDuration); @@ -141,8 +146,9 @@ public AndConstraint BeGreaterThanOrEqualTo(TimeSpan mi .ForCondition(Condition(elapsed)) .BecauseOf(because, becauseArgs) .FailWith("Execution of " + - execution.ActionDescription.EscapePlaceholders() + " should be greater than or equal to {0}{reason}, but it required " + - (isRunning ? "more than " : "exactly ") + "{1}.", + execution.ActionDescription.EscapePlaceholders() + + " should be greater than or equal to {0}{reason}, but it required " + + (isRunning ? "more than " : "exactly ") + "{1}.", minDuration, elapsed); @@ -150,7 +156,8 @@ public AndConstraint BeGreaterThanOrEqualTo(TimeSpan mi } [EditorBrowsable(EditorBrowsableState.Never)] - public AndConstraint BeGreaterOrEqualTo(TimeSpan minDuration, string because = "", params object[] becauseArgs) => BeGreaterThanOrEqualTo(minDuration, because, becauseArgs); + public AndConstraint BeGreaterOrEqualTo(TimeSpan minDuration, string because = "", + params object[] becauseArgs) => BeGreaterThanOrEqualTo(minDuration, because, becauseArgs); /// [DebuggerNonUserCode] -public class PropertyInfoAssertions : - MemberInfoAssertions /// Asserts that the execution time of the operation is greater than a specified amount of time. @@ -165,7 +172,8 @@ public AndConstraint BeGreaterThanOrEqualTo(TimeSpan mi /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint BeGreaterThan(TimeSpan minDuration, string because = "", params object[] becauseArgs) + public AndConstraint BeGreaterThan(TimeSpan minDuration, string because = "", + params object[] becauseArgs) { bool Condition(TimeSpan duration) => duration > minDuration; (bool isRunning, TimeSpan elapsed) = PollUntil(Condition, expectedResult: true, rate: minDuration); @@ -174,8 +182,8 @@ public AndConstraint BeGreaterThan(TimeSpan minDuration .ForCondition(Condition(elapsed)) .BecauseOf(because, becauseArgs) .FailWith("Execution of " + - execution.ActionDescription.EscapePlaceholders() + " should be greater than {0}{reason}, but it required " + - (isRunning ? "more than " : "exactly ") + "{1}.", + execution.ActionDescription.EscapePlaceholders() + " should be greater than {0}{reason}, but it required " + + (isRunning ? "more than " : "exactly ") + "{1}.", minDuration, elapsed); @@ -200,7 +208,8 @@ public AndConstraint BeGreaterThan(TimeSpan minDuration /// Zero or more objects to format using the placeholders in . /// /// - public AndConstraint is negative. BeCloseTo(TimeSpan expectedDuration, TimeSpan precision, string because = "", params object[] becauseArgs) + public AndConstraint BeCloseTo(TimeSpan expectedDuration, TimeSpan precision, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNegative(precision); @@ -218,8 +227,8 @@ public AndConstraint BeCloseTo(TimeSpan expectedDuratio .ForCondition(MinCondition(elapsed) && MaxCondition(elapsed)) .BecauseOf(because, becauseArgs) .FailWith("Execution of " + execution.ActionDescription.EscapePlaceholders() + - " should be within {0} from {1}{reason}, but it required " + - (isRunning ? "more than " : "exactly ") + "{2}.", + " should be within {0} from {1}{reason}, but it required " + + (isRunning ? "more than " : "exactly ") + "{2}.", precision, expectedDuration, elapsed); @@ -229,5 +238,6 @@ public AndConstraint BeCloseTo(TimeSpan expectedDuratio /// public override bool Equals(object obj) => - throw new NotSupportedException("Equals is not part of Fluent Assertions. Did you mean BeLessThanOrEqualTo() or BeGreaterThanOrEqualTo() instead?"); + throw new NotSupportedException( + "Equals is not part of Fluent Assertions. Did you mean BeLessThanOrEqualTo() or BeGreaterThanOrEqualTo() instead?"); } diff --git a/Src/FluentAssertions/Specialized/FunctionAssertionHelpers.cs b/Src/FluentAssertions/Specialized/FunctionAssertionHelpers.cs index 015de056d8..d40d15548f 100644 --- a/Src/FluentAssertions/Specialized/FunctionAssertionHelpers.cs +++ b/Src/FluentAssertions/Specialized/FunctionAssertionHelpers.cs @@ -15,15 +15,16 @@ internal static T NotThrow(Func subject, string because, object[] becauseA catch (Exception exception) { Execute.Assertion - .ForCondition(exception is null) - .BecauseOf(because, becauseArgs) - .FailWith("Did not expect any exception{reason}, but found {0}.", exception); + .ForCondition(exception is null) + .BecauseOf(because, becauseArgs) + .FailWith("Did not expect any exception{reason}, but found {0}.", exception); return default; } } - internal static TResult NotThrowAfter(Func subject, IClock clock, TimeSpan waitTime, TimeSpan pollInterval, string because, object[] becauseArgs) + internal static TResult NotThrowAfter(Func subject, IClock clock, TimeSpan waitTime, TimeSpan pollInterval, + string because, object[] becauseArgs) { Guard.ThrowIfArgumentIsNegative(waitTime); Guard.ThrowIfArgumentIsNegative(pollInterval); diff --git a/Src/FluentAssertions/Specialized/FunctionAssertions.cs b/Src/FluentAssertions/Specialized/FunctionAssertions.cs index 53904e3d88..fda57829d9 100644 --- a/Src/FluentAssertions/Specialized/FunctionAssertions.cs +++ b/Src/FluentAssertions/Specialized/FunctionAssertions.cs @@ -1,6 +1,5 @@ using System; using System.Diagnostics; -using System.Security; using FluentAssertions.Common; using FluentAssertions.Execution; @@ -42,9 +41,9 @@ protected override void InvokeSubject() public new AndWhichConstraint, T> NotThrow(string because = "", params object[] becauseArgs) { bool success = Execute.Assertion - .ForCondition(Subject is not null) - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context} not to throw{reason}, but found ."); + .ForCondition(Subject is not null) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context} not to throw{reason}, but found ."); T result = default; @@ -79,7 +78,8 @@ protected override void InvokeSubject() /// Zero or more objects to format using the placeholders in . /// /// - public new AndWhichConstraint or are negative., T> NotThrowAfter(TimeSpan waitTime, TimeSpan pollInterval, string because = "", params object[] becauseArgs) + public new AndWhichConstraint, T> NotThrowAfter(TimeSpan waitTime, TimeSpan pollInterval, + string because = "", params object[] becauseArgs) { bool success = Execute.Assertion .ForCondition(Subject is not null) diff --git a/Src/FluentAssertions/Specialized/GenericAsyncFunctionAssertions.cs b/Src/FluentAssertions/Specialized/GenericAsyncFunctionAssertions.cs index 2c33ff9c58..386f497daa 100644 --- a/Src/FluentAssertions/Specialized/GenericAsyncFunctionAssertions.cs +++ b/Src/FluentAssertions/Specialized/GenericAsyncFunctionAssertions.cs @@ -6,7 +6,8 @@ namespace FluentAssertions.Specialized; -public class GenericAsyncFunctionAssertions : AsyncFunctionAssertions, GenericAsyncFunctionAssertions> +public class GenericAsyncFunctionAssertions + : AsyncFunctionAssertions, GenericAsyncFunctionAssertions> { public GenericAsyncFunctionAssertions(Func> subject, IExtractExceptions extractor) : this(subject, extractor, new Clock()) @@ -51,11 +52,12 @@ public GenericAsyncFunctionAssertions(Func> subject, IExtractExcep if (success) { bool completesWithinTimeout = await CompletesWithinTimeoutAsync(task, remainingTime); + success = Execute.Assertion - .ForCondition(completesWithinTimeout) - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:task} to complete within {0}{reason}.", timeSpan); - } + .ForCondition(completesWithinTimeout) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:task} to complete within {0}{reason}.", timeSpan); + } TResult result = success ? task.Result : default; return new AndWhichConstraint, TResult>(this, result); diff --git a/Src/FluentAssertions/Specialized/TaskCompletionSourceAssertions.cs b/Src/FluentAssertions/Specialized/TaskCompletionSourceAssertions.cs index 463cb0b754..6038c9c756 100644 --- a/Src/FluentAssertions/Specialized/TaskCompletionSourceAssertions.cs +++ b/Src/FluentAssertions/Specialized/TaskCompletionSourceAssertions.cs @@ -87,7 +87,6 @@ public async Task> NotCompleteWith return new AndConstraint(this); } } - #endif public class TaskCompletionSourceAssertions : TaskCompletionSourceAssertionsBase @@ -127,10 +126,12 @@ public async Task, T>> Comp if (success) { bool completesWithinTimeout = await CompletesWithinTimeoutAsync(subject.Task, timeSpan); + Execute.Assertion .ForCondition(completesWithinTimeout) .BecauseOf(because, becauseArgs) .FailWith("Expected {context:task} to complete within {0}{reason}.", timeSpan); + T result = subject.Task.IsCompleted ? subject.Task.Result : default; return new AndWhichConstraint, T>(this, result); } @@ -160,6 +161,7 @@ public async Task>> NotCompleteW if (success) { bool completesWithinTimeout = await CompletesWithinTimeoutAsync(subject.Task, timeSpan); + Execute.Assertion .ForCondition(!completesWithinTimeout) .BecauseOf(because, becauseArgs) diff --git a/Src/FluentAssertions/Types/MethodBaseAssertions.cs b/Src/FluentAssertions/Types/MethodBaseAssertions.cs index bd21c36ce1..7ab268bbb7 100644 --- a/Src/FluentAssertions/Types/MethodBaseAssertions.cs +++ b/Src/FluentAssertions/Types/MethodBaseAssertions.cs @@ -71,7 +71,8 @@ public AndConstraint HaveAccessModifier( /// /// - public AndConstraint /// is not a value. NotHaveAccessModifier(CSharpAccessModifier accessModifier, string because = "", params object[] becauseArgs) + public AndConstraint NotHaveAccessModifier(CSharpAccessModifier accessModifier, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsOutOfRange(accessModifier); diff --git a/Src/FluentAssertions/Types/MethodInfoAssertions.cs b/Src/FluentAssertions/Types/MethodInfoAssertions.cs index 52195dae62..cafd02b3de 100644 --- a/Src/FluentAssertions/Types/MethodInfoAssertions.cs +++ b/Src/FluentAssertions/Types/MethodInfoAssertions.cs @@ -37,9 +37,9 @@ public AndConstraint BeVirtual(string because = "", params if (success) { Execute.Assertion - .ForCondition(!Subject.IsNonVirtual()) - .BecauseOf(because, becauseArgs) - .FailWith("Expected method " + SubjectDescription + " to be virtual{reason}, but it is not virtual."); + .ForCondition(!Subject.IsNonVirtual()) + .BecauseOf(because, becauseArgs) + .FailWith("Expected method " + SubjectDescription + " to be virtual{reason}, but it is not virtual."); } return new AndConstraint(this); @@ -93,9 +93,9 @@ public AndConstraint BeAsync(string because = "", params o if (success) { Execute.Assertion - .ForCondition(Subject.IsAsync()) - .BecauseOf(because, becauseArgs) - .FailWith("Expected method " + SubjectDescription + " to be async{reason}, but it is not."); + .ForCondition(Subject.IsAsync()) + .BecauseOf(because, becauseArgs) + .FailWith("Expected method " + SubjectDescription + " to be async{reason}, but it is not."); } return new AndConstraint(this); @@ -139,7 +139,8 @@ public AndConstraint NotBeAsync(string because = "", param /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint> ReturnVoid(string because = "", params object[] becauseArgs) + public AndConstraint> ReturnVoid(string because = "", + params object[] becauseArgs) { bool success = Execute.Assertion .BecauseOf(because, becauseArgs) @@ -170,7 +171,8 @@ public AndConstraint> Ret /// Zero or more objects to format using the placeholders in . /// /// - public AndConstraint is .> Return(Type returnType, string because = "", params object[] becauseArgs) + public AndConstraint> Return(Type returnType, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(returnType); @@ -202,7 +204,8 @@ public AndConstraint> Ret /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint> Return(string because = "", params object[] becauseArgs) + public AndConstraint> Return(string because = "", + params object[] becauseArgs) { return Return(typeof(TReturn), because, becauseArgs); } @@ -217,7 +220,8 @@ public AndConstraint> Ret /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint> NotReturnVoid(string because = "", params object[] becauseArgs) + public AndConstraint> NotReturnVoid(string because = "", + params object[] becauseArgs) { bool success = Execute.Assertion .BecauseOf(because, becauseArgs) @@ -247,7 +251,8 @@ public AndConstraint> Not /// Zero or more objects to format using the placeholders in . /// /// - public AndConstraint is .> NotReturn(Type returnType, string because = "", params object[] becauseArgs) + public AndConstraint> NotReturn(Type returnType, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(returnType); @@ -260,10 +265,10 @@ public AndConstraint> Not if (success) { Execute.Assertion - .ForCondition(returnType != Subject.ReturnType) - .BecauseOf(because, becauseArgs) - .FailWith( - "Expected the return type of method " + Subject.Name + " not to be {0}{reason}, but it is.", returnType); + .ForCondition(returnType != Subject.ReturnType) + .BecauseOf(because, becauseArgs) + .FailWith( + "Expected the return type of method " + Subject.Name + " not to be {0}{reason}, but it is.", returnType); } return new AndConstraint>(this); @@ -280,7 +285,8 @@ public AndConstraint> Not /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint> NotReturn(string because = "", params object[] becauseArgs) + public AndConstraint> NotReturn(string because = "", + params object[] becauseArgs) { return NotReturn(typeof(TReturn), because, becauseArgs); } diff --git a/Src/FluentAssertions/Types/MethodInfoSelector.cs b/Src/FluentAssertions/Types/MethodInfoSelector.cs index 56e085b19f..0a7e74ff17 100644 --- a/Src/FluentAssertions/Types/MethodInfoSelector.cs +++ b/Src/FluentAssertions/Types/MethodInfoSelector.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Reflection; using FluentAssertions.Common; +using static System.Reflection.BindingFlags; namespace FluentAssertions.Types; @@ -35,7 +36,7 @@ public MethodInfoSelector(IEnumerable types) Guard.ThrowIfArgumentContainsNull(types); selectedMethods = types.SelectMany(t => t - .GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) + .GetMethods(DeclaredOnly | Instance | Static | Public | NonPublic) .Where(method => !HasSpecialName(method))); } @@ -152,7 +153,7 @@ public MethodInfoSelector ThatAreNotAbstract() } /// public MethodInfoSelector ThatAreAsync() { @@ -161,7 +162,7 @@ public MethodInfoSelector ThatAreAsync() } /// public MethodInfoSelector ThatAreNotAsync() { @@ -170,7 +171,7 @@ public MethodInfoSelector ThatAreNotAsync() } /// public MethodInfoSelector ThatAreStatic() { @@ -179,7 +180,7 @@ public MethodInfoSelector ThatAreStatic() } /// public MethodInfoSelector ThatAreNotStatic() { @@ -188,7 +189,7 @@ public MethodInfoSelector ThatAreNotStatic() } /// public MethodInfoSelector ThatAreVirtual() { @@ -197,7 +198,7 @@ public MethodInfoSelector ThatAreVirtual() } /// public MethodInfoSelector ThatAreNotVirtual() { diff --git a/Src/FluentAssertions/Types/MethodInfoSelectorAssertions.cs b/Src/FluentAssertions/Types/MethodInfoSelectorAssertions.cs index d0e7635220..ee88f04078 100644 --- a/Src/FluentAssertions/Types/MethodInfoSelectorAssertions.cs +++ b/Src/FluentAssertions/Types/MethodInfoSelectorAssertions.cs @@ -162,7 +162,8 @@ public AndConstraint - /// Only return methods that are async. + /// Only return methods that are async. /// - /// Only return methods that are not async. + /// Only return methods that are not async. /// - /// Only return methods that are static. + /// Only return methods that are static. /// - /// Only return methods that are not static. + /// Only return methods that are not static. /// - /// Only return methods that are virtual. + /// Only return methods that are virtual. /// - /// Only return methods that are not virtual. + /// Only return methods that are not virtual. /// NotBeAsync(string because = " /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint BeDecoratedWith(string because = "", params object[] becauseArgs) + public AndConstraint BeDecoratedWith(string because = "", + params object[] becauseArgs) where TAttribute : Attribute { return BeDecoratedWith(_ => true, because, becauseArgs); @@ -214,7 +215,8 @@ public AndConstraint BeDecoratedWith( /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint NotBeDecoratedWith(string because = "", params object[] becauseArgs) + public AndConstraint NotBeDecoratedWith(string because = "", + params object[] becauseArgs) where TAttribute : Attribute { return NotBeDecoratedWith(_ => true, because, becauseArgs); @@ -267,10 +269,13 @@ public AndConstraint NotBeDecoratedWith /// Zero or more objects to format using the placeholders in . /// - public AndConstraint Be(CSharpAccessModifier accessModifier, string because = "", params object[] becauseArgs) + public AndConstraint Be(CSharpAccessModifier accessModifier, string because = "", + params object[] becauseArgs) { var methods = SubjectMethods.Where(pi => pi.GetCSharpAccessModifier() != accessModifier).ToArray(); - var message = $"Expected all selected methods to be {accessModifier}{{reason}}, but the following methods are not:" + Environment.NewLine + GetDescriptionsFor(methods); + + var message = $"Expected all selected methods to be {accessModifier}{{reason}}, but the following methods are not:" + + Environment.NewLine + GetDescriptionsFor(methods); Execute.Assertion .ForCondition(!methods.Any()) @@ -291,10 +296,13 @@ public AndConstraint Be(CSharpAccessModifier acces /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint NotBe(CSharpAccessModifier accessModifier, string because = "", params object[] becauseArgs) + public AndConstraint NotBe(CSharpAccessModifier accessModifier, string because = "", + params object[] becauseArgs) { var methods = SubjectMethods.Where(pi => pi.GetCSharpAccessModifier() == accessModifier).ToArray(); - var message = $"Expected all selected methods to not be {accessModifier}{{reason}}, but the following methods are:" + Environment.NewLine + GetDescriptionsFor(methods); + + var message = $"Expected all selected methods to not be {accessModifier}{{reason}}, but the following methods are:" + + Environment.NewLine + GetDescriptionsFor(methods); Execute.Assertion .ForCondition(!methods.Any()) diff --git a/Src/FluentAssertions/Types/PropertyInfoAssertions.cs b/Src/FluentAssertions/Types/PropertyInfoAssertions.cs index b449088dd1..e8f329d04f 100644 --- a/Src/FluentAssertions/Types/PropertyInfoAssertions.cs +++ b/Src/FluentAssertions/Types/PropertyInfoAssertions.cs @@ -10,8 +10,7 @@ namespace FluentAssertions.Types; /// Contains a number of methods to assert that a is in the expected state. /// +public class PropertyInfoAssertions : MemberInfoAssertions { public PropertyInfoAssertions(PropertyInfo propertyInfo) : base(propertyInfo) @@ -67,9 +66,9 @@ public AndConstraint NotBeVirtual(string because = "", p if (success) { Execute.Assertion - .ForCondition(!Subject.IsVirtual()) - .BecauseOf(because, becauseArgs) - .FailWith($"Expected property {GetDescriptionFor(Subject)} not to be virtual{{reason}}, but it is."); + .ForCondition(!Subject.IsVirtual()) + .BecauseOf(because, becauseArgs) + .FailWith($"Expected property {GetDescriptionFor(Subject)} not to be virtual{{reason}}, but it is."); } return new AndConstraint(this); @@ -96,11 +95,11 @@ public AndConstraint BeWritable( if (success) { Execute.Assertion - .ForCondition(Subject.CanWrite) - .BecauseOf(because, becauseArgs) - .FailWith( - "Expected {context:property} {0} to have a setter{reason}.", - Subject); + .ForCondition(Subject.CanWrite) + .BecauseOf(because, becauseArgs) + .FailWith( + "Expected {context:property} {0} to have a setter{reason}.", + Subject); } return new AndConstraint(this); @@ -119,14 +118,15 @@ public AndConstraint BeWritable( /// /// - public AndConstraint /// is not a value. BeWritable(CSharpAccessModifier accessModifier, string because = "", params object[] becauseArgs) + public AndConstraint BeWritable(CSharpAccessModifier accessModifier, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsOutOfRange(accessModifier); bool success = Execute.Assertion - .BecauseOf(because, becauseArgs) - .ForCondition(Subject is not null) - .FailWith($"Expected {Identifier} to be {accessModifier}{{reason}}, but {{context:property}} is ."); + .BecauseOf(because, becauseArgs) + .ForCondition(Subject is not null) + .FailWith($"Expected {Identifier} to be {accessModifier}{{reason}}, but {{context:property}} is ."); if (success) { @@ -159,11 +159,11 @@ public AndConstraint NotBeWritable( if (success) { Execute.Assertion - .ForCondition(!Subject.CanWrite) - .BecauseOf(because, becauseArgs) - .FailWith( - "Expected {context:property} {0} not to have a setter{reason}.", - Subject); + .ForCondition(!Subject.CanWrite) + .BecauseOf(because, becauseArgs) + .FailWith( + "Expected {context:property} {0} not to have a setter{reason}.", + Subject); } return new AndConstraint(this); @@ -189,8 +189,8 @@ public AndConstraint BeReadable(string because = "", par if (success) { Execute.Assertion.ForCondition(Subject.CanRead) - .BecauseOf(because, becauseArgs) - .FailWith("Expected property " + Subject.Name + " to have a getter{reason}, but it does not."); + .BecauseOf(because, becauseArgs) + .FailWith("Expected property " + Subject.Name + " to have a getter{reason}, but it does not."); } return new AndConstraint(this); @@ -209,14 +209,15 @@ public AndConstraint BeReadable(string because = "", par /// /// - public AndConstraint /// is not a value. BeReadable(CSharpAccessModifier accessModifier, string because = "", params object[] becauseArgs) + public AndConstraint BeReadable(CSharpAccessModifier accessModifier, string because = "", + params object[] becauseArgs) { Guard.ThrowIfArgumentIsOutOfRange(accessModifier); bool success = Execute.Assertion - .BecauseOf(because, becauseArgs) - .ForCondition(Subject is not null) - .FailWith($"Expected {Identifier} to be {accessModifier}{{reason}}, but {{context:property}} is ."); + .BecauseOf(because, becauseArgs) + .ForCondition(Subject is not null) + .FailWith($"Expected {Identifier} to be {accessModifier}{{reason}}, but {{context:property}} is ."); if (success) { @@ -249,11 +250,11 @@ public AndConstraint NotBeReadable( if (success) { Execute.Assertion - .ForCondition(!Subject.CanRead) - .BecauseOf(because, becauseArgs) - .FailWith( - "Expected {context:property} {0} not to have a getter{reason}.", - Subject); + .ForCondition(!Subject.CanRead) + .BecauseOf(because, becauseArgs) + .FailWith( + "Expected {context:property} {0} not to have a getter{reason}.", + Subject); } return new AndConstraint(this); @@ -277,16 +278,16 @@ public AndConstraint Return(Type propertyType, Guard.ThrowIfArgumentIsNull(propertyType); bool success = Execute.Assertion - .BecauseOf(because, becauseArgs) - .ForCondition(Subject is not null) - .FailWith("Expected type of property to be {0}{reason}, but {context:property} is .", propertyType); + .BecauseOf(because, becauseArgs) + .ForCondition(Subject is not null) + .FailWith("Expected type of property to be {0}{reason}, but {context:property} is .", propertyType); if (success) { Execute.Assertion.ForCondition(Subject.PropertyType == propertyType) - .BecauseOf(because, becauseArgs) - .FailWith("Expected Type of property " + Subject.Name + " to be {0}{reason}, but it is {1}.", - propertyType, Subject.PropertyType); + .BecauseOf(because, becauseArgs) + .FailWith("Expected Type of property " + Subject.Name + " to be {0}{reason}, but it is {1}.", + propertyType, Subject.PropertyType); } return new AndConstraint(this); @@ -325,16 +326,16 @@ public AndConstraint NotReturn(Type propertyType, string Guard.ThrowIfArgumentIsNull(propertyType); bool success = Execute.Assertion - .BecauseOf(because, becauseArgs) - .ForCondition(Subject is not null) - .FailWith("Expected type of property not to be {0}{reason}, but {context:property} is .", propertyType); + .BecauseOf(because, becauseArgs) + .ForCondition(Subject is not null) + .FailWith("Expected type of property not to be {0}{reason}, but {context:property} is .", propertyType); if (success) { Execute.Assertion - .ForCondition(Subject.PropertyType != propertyType) - .BecauseOf(because, becauseArgs) - .FailWith("Expected Type of property " + Subject.Name + " not to be {0}{reason}, but it is.", propertyType); + .ForCondition(Subject.PropertyType != propertyType) + .BecauseOf(because, becauseArgs) + .FailWith("Expected Type of property " + Subject.Name + " not to be {0}{reason}, but it is.", propertyType); } return new AndConstraint(this); diff --git a/Src/FluentAssertions/Types/PropertyInfoSelector.cs b/Src/FluentAssertions/Types/PropertyInfoSelector.cs index 1fb87c13be..624b302875 100644 --- a/Src/FluentAssertions/Types/PropertyInfoSelector.cs +++ b/Src/FluentAssertions/Types/PropertyInfoSelector.cs @@ -36,7 +36,7 @@ public PropertyInfoSelector(IEnumerable types) selectedProperties = types.SelectMany(t => t .GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance - | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)); + | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)); } /// diff --git a/Src/FluentAssertions/Types/PropertyInfoSelectorAssertions.cs b/Src/FluentAssertions/Types/PropertyInfoSelectorAssertions.cs index bcf5abdd45..ba243a93fc 100644 --- a/Src/FluentAssertions/Types/PropertyInfoSelectorAssertions.cs +++ b/Src/FluentAssertions/Types/PropertyInfoSelectorAssertions.cs @@ -159,7 +159,8 @@ private PropertyInfo[] GetAllVirtualPropertiesFromSelection() /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint BeDecoratedWith(string because = "", params object[] becauseArgs) + public AndConstraint BeDecoratedWith(string because = "", + params object[] becauseArgs) where TAttribute : Attribute { PropertyInfo[] propertiesWithoutAttribute = GetPropertiesWithout(); @@ -185,7 +186,8 @@ public AndConstraint BeDecoratedWith /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint NotBeDecoratedWith(string because = "", params object[] becauseArgs) + public AndConstraint NotBeDecoratedWith(string because = "", + params object[] becauseArgs) where TAttribute : Attribute { PropertyInfo[] propertiesWithAttribute = GetPropertiesWith(); diff --git a/Src/FluentAssertions/Types/TypeAssertions.cs b/Src/FluentAssertions/Types/TypeAssertions.cs index cff6cca7e8..6373caf6e3 100644 --- a/Src/FluentAssertions/Types/TypeAssertions.cs +++ b/Src/FluentAssertions/Types/TypeAssertions.cs @@ -207,7 +207,7 @@ public AndConstraint NotBe(string because = "", par /// public AndConstraint NotBe(Type unexpected, string because = "", params object[] becauseArgs) { - string nameOfUnexpectedType = (unexpected is not null) ? $"[{unexpected.AssemblyQualifiedName}]" : ""; + string nameOfUnexpectedType = unexpected is not null ? $"[{unexpected.AssemblyQualifiedName}]" : ""; Execute.Assertion .BecauseOf(because, becauseArgs) @@ -789,9 +789,9 @@ public AndConstraint NotBeAbstract(string because = "", params o public AndConstraint BeStatic(string because = "", params object[] becauseArgs) { bool success = Execute.Assertion - .BecauseOf(because, becauseArgs) - .ForCondition(Subject is not null) - .FailWith("Expected type to be static{reason}, but {context:type} is ."); + .BecauseOf(because, becauseArgs) + .ForCondition(Subject is not null) + .FailWith("Expected type to be static{reason}, but {context:type} is ."); if (success) { @@ -1541,9 +1541,9 @@ public AndConstraint HaveAccessModifier( Guard.ThrowIfArgumentIsOutOfRange(accessModifier); bool success = Execute.Assertion - .BecauseOf(because, becauseArgs) - .ForCondition(Subject is not null) - .FailWith($"Expected {{context:type}} to be {accessModifier}{{reason}}, but {{context:type}} is ."); + .BecauseOf(because, becauseArgs) + .ForCondition(Subject is not null) + .FailWith($"Expected {{context:type}} to be {accessModifier}{{reason}}, but {{context:type}} is ."); if (success) { diff --git a/Src/FluentAssertions/Types/TypeSelector.cs b/Src/FluentAssertions/Types/TypeSelector.cs index 60c007295e..0946f8fb49 100644 --- a/Src/FluentAssertions/Types/TypeSelector.cs +++ b/Src/FluentAssertions/Types/TypeSelector.cs @@ -63,7 +63,7 @@ public TypeSelector ThatDoNotDeriveFrom() public TypeSelector ThatImplement() { types = types - .Where(t => typeof(TInterface).IsAssignableFrom(t) && (t != typeof(TInterface))) + .Where(t => typeof(TInterface).IsAssignableFrom(t) && t != typeof(TInterface)) .ToList(); return this; @@ -75,7 +75,7 @@ public TypeSelector ThatImplement() public TypeSelector ThatDoNotImplement() { types = types - .Where(t => !typeof(TInterface).IsAssignableFrom(t) && (t != typeof(TInterface))) + .Where(t => !typeof(TInterface).IsAssignableFrom(t) && t != typeof(TInterface)) .ToList(); return this; @@ -315,6 +315,7 @@ public TypeSelector UnwrapTaskTypes() public TypeSelector UnwrapEnumerableTypes() { var unwrappedTypes = new List(); + foreach (Type type in types) { if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) diff --git a/Src/FluentAssertions/Types/TypeSelectorAssertions.cs b/Src/FluentAssertions/Types/TypeSelectorAssertions.cs index ee2162f1f4..7ed6307706 100644 --- a/Src/FluentAssertions/Types/TypeSelectorAssertions.cs +++ b/Src/FluentAssertions/Types/TypeSelectorAssertions.cs @@ -111,7 +111,8 @@ public AndConstraint BeDecoratedWith( /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint BeDecoratedWithOrInherit(string because = "", params object[] becauseArgs) + public AndConstraint BeDecoratedWithOrInherit(string because = "", + params object[] becauseArgs) where TAttribute : Attribute { Type[] typesWithoutAttribute = Subject @@ -245,7 +246,8 @@ public AndConstraint NotBeDecoratedWith( /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint NotBeDecoratedWithOrInherit(string because = "", params object[] becauseArgs) + public AndConstraint NotBeDecoratedWithOrInherit(string because = "", + params object[] becauseArgs) where TAttribute : Attribute { Type[] typesWithAttribute = Subject @@ -318,7 +320,8 @@ public AndConstraint BeSealed(string because = "", param Execute.Assertion.ForCondition(!notSealedTypes.Any()) .BecauseOf(because, becauseArgs) - .FailWith("Expected all types to be sealed{reason}, but the following types are not:{0}{1}.", Environment.NewLine, GetDescriptionsFor(notSealedTypes)); + .FailWith("Expected all types to be sealed{reason}, but the following types are not:{0}{1}.", Environment.NewLine, + GetDescriptionsFor(notSealedTypes)); return new AndConstraint(this); } @@ -339,7 +342,8 @@ public AndConstraint NotBeSealed(string because = "", pa Execute.Assertion.ForCondition(!sealedTypes.Any()) .BecauseOf(because, becauseArgs) - .FailWith("Expected all types not to be sealed{reason}, but the following types are:{0}{1}.", Environment.NewLine, GetDescriptionsFor(sealedTypes)); + .FailWith("Expected all types not to be sealed{reason}, but the following types are:{0}{1}.", Environment.NewLine, + GetDescriptionsFor(sealedTypes)); return new AndConstraint(this); } @@ -357,7 +361,8 @@ public AndConstraint NotBeSealed(string because = "", pa /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint BeInNamespace(string @namespace, string because = "", params object[] becauseArgs) + public AndConstraint BeInNamespace(string @namespace, string because = "", + params object[] becauseArgs) { Type[] typesNotInNamespace = Subject .Where(t => t.Namespace != @namespace) @@ -367,7 +372,7 @@ public AndConstraint BeInNamespace(string @namespace, st .ForCondition(!typesNotInNamespace.Any()) .BecauseOf(because, becauseArgs) .FailWith("Expected all types to be in namespace {0}{reason}," + - " but the following types are in a different namespace:{1}{2}.", + " but the following types are in a different namespace:{1}{2}.", @namespace, Environment.NewLine, GetDescriptionsFor(typesNotInNamespace)); @@ -388,7 +393,8 @@ public AndConstraint BeInNamespace(string @namespace, st /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint NotBeInNamespace(string @namespace, string because = "", params object[] becauseArgs) + public AndConstraint NotBeInNamespace(string @namespace, string because = "", + params object[] becauseArgs) { Type[] typesInNamespace = Subject .Where(t => t.Namespace == @namespace) @@ -398,7 +404,7 @@ public AndConstraint NotBeInNamespace(string @namespace, .ForCondition(!typesInNamespace.Any()) .BecauseOf(because, becauseArgs) .FailWith("Expected no types to be in namespace {0}{reason}," + - " but the following types are in the namespace:{1}{2}.", + " but the following types are in the namespace:{1}{2}.", @namespace, Environment.NewLine, GetDescriptionsFor(typesInNamespace)); @@ -419,7 +425,8 @@ public AndConstraint NotBeInNamespace(string @namespace, /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint BeUnderNamespace(string @namespace, string because = "", params object[] becauseArgs) + public AndConstraint BeUnderNamespace(string @namespace, string because = "", + params object[] becauseArgs) { Type[] typesNotUnderNamespace = Subject .Where(t => !t.IsUnderNamespace(@namespace)) @@ -429,7 +436,7 @@ public AndConstraint BeUnderNamespace(string @namespace, .ForCondition(!typesNotUnderNamespace.Any()) .BecauseOf(because, becauseArgs) .FailWith("Expected the namespaces of all types to start with {0}{reason}," + - " but the namespaces of the following types do not start with it:{1}{2}.", + " but the namespaces of the following types do not start with it:{1}{2}.", @namespace, Environment.NewLine, GetDescriptionsFor(typesNotUnderNamespace)); @@ -451,7 +458,8 @@ public AndConstraint BeUnderNamespace(string @namespace, /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint NotBeUnderNamespace(string @namespace, string because = "", params object[] becauseArgs) + public AndConstraint NotBeUnderNamespace(string @namespace, string because = "", + params object[] becauseArgs) { Type[] typesUnderNamespace = Subject .Where(t => t.IsUnderNamespace(@namespace)) @@ -461,7 +469,7 @@ public AndConstraint NotBeUnderNamespace(string @namespa .ForCondition(!typesUnderNamespace.Any()) .BecauseOf(because, becauseArgs) .FailWith("Expected the namespaces of all types to not start with {0}{reason}," + - " but the namespaces of the following types start with it:{1}{2}.", + " but the namespaces of the following types start with it:{1}{2}.", @namespace, Environment.NewLine, GetDescriptionsFor(typesUnderNamespace)); @@ -482,5 +490,6 @@ private static string GetDescriptionFor(Type type) /// public override bool Equals(object obj) => - throw new NotSupportedException("Equals is not part of Fluent Assertions. Did you mean BeInNamespace() or BeDecoratedWith() instead?"); + throw new NotSupportedException( + "Equals is not part of Fluent Assertions. Did you mean BeInNamespace() or BeDecoratedWith() instead?"); } diff --git a/Src/FluentAssertions/Xml/Equivalency/Node.cs b/Src/FluentAssertions/Xml/Equivalency/Node.cs index 3a3e336e25..2d6e383aee 100644 --- a/Src/FluentAssertions/Xml/Equivalency/Node.cs +++ b/Src/FluentAssertions/Xml/Equivalency/Node.cs @@ -11,7 +11,7 @@ internal sealed class Node private readonly string name; private int count; - public static Node CreateRoot() => new Node(null, null); + public static Node CreateRoot() => new(null, null); private Node(Node parent, string name) { @@ -46,6 +46,7 @@ public string GetXPath() private IEnumerable GetPath() { Node current = this; + while (current.Parent is not null) { yield return current; @@ -58,7 +59,7 @@ private IEnumerable GetPath() public Node Push(string localName) { Node node = children.Find(e => e.name == localName) - ?? AddChildNode(localName); + ?? AddChildNode(localName); node.count++; diff --git a/Src/FluentAssertions/Xml/Equivalency/XmlIterator.cs b/Src/FluentAssertions/Xml/Equivalency/XmlIterator.cs index 38be8e991b..72f665b136 100644 --- a/Src/FluentAssertions/Xml/Equivalency/XmlIterator.cs +++ b/Src/FluentAssertions/Xml/Equivalency/XmlIterator.cs @@ -44,6 +44,7 @@ public void Read() public void MoveToEndElement() { reader.Read(); + if (reader.NodeType != XmlNodeType.EndElement) { // advancing failed diff --git a/Src/FluentAssertions/Xml/Equivalency/XmlReaderValidator.cs b/Src/FluentAssertions/Xml/Equivalency/XmlReaderValidator.cs index d3fffff109..cc89aab3bf 100644 --- a/Src/FluentAssertions/Xml/Equivalency/XmlReaderValidator.cs +++ b/Src/FluentAssertions/Xml/Equivalency/XmlReaderValidator.cs @@ -62,9 +62,11 @@ private Failure Validate() var expectation = expectationIterator.NodeType == XmlNodeType.Text ? $"content \"{expectationIterator.Value}\"" : $"{expectationIterator.NodeType} \"{expectationIterator.LocalName}\""; + var subject = subjectIterator.NodeType == XmlNodeType.Text ? $"content \"{subjectIterator.Value}\"" : $"{subjectIterator.NodeType} \"{subjectIterator.LocalName}\""; + return new Failure( $"Expected {expectation} in {{context:subject}} at {{0}}{{reason}}, but found {subject}.", currentNode.GetXPath()); @@ -78,6 +80,7 @@ private Failure Validate() { case XmlNodeType.Element: failure = ValidateStartElement(); + if (failure is not null) { return failure; @@ -160,7 +163,7 @@ private Failure ValidateAttributes() { AttributeData expectedAttribute = expectedAttributes.SingleOrDefault( ea => ea.NamespaceUri == subjectAttribute.NamespaceUri - && ea.LocalName == subjectAttribute.LocalName); + && ea.LocalName == subjectAttribute.LocalName); if (expectedAttribute is null) { @@ -229,7 +232,7 @@ private Failure ValidateText() private Failure ValidateAgainstNulls() { - if ((expectationReader is null) != (subjectReader is null)) + if (expectationReader is null != subjectReader is null) { return new Failure( "Expected {context:subject} to be equivalent to {0}{reason}, but found {1}.", diff --git a/Src/FluentAssertions/Xml/XDocumentAssertions.cs b/Src/FluentAssertions/Xml/XDocumentAssertions.cs index 76baf7d115..2971c9ec6a 100644 --- a/Src/FluentAssertions/Xml/XDocumentAssertions.cs +++ b/Src/FluentAssertions/Xml/XDocumentAssertions.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Xml; using System.Xml.Linq; - using FluentAssertions.Common; using FluentAssertions.Execution; using FluentAssertions.Primitives; @@ -106,7 +105,8 @@ public AndConstraint BeEquivalentTo(XDocument expected, str /// /// Zero or more objects to format using the placeholders in . /// - public AndConstraint NotBeEquivalentTo(XDocument unexpected, string because = "", params object[] becauseArgs) + public AndConstraint NotBeEquivalentTo(XDocument unexpected, string because = "", + params object[] becauseArgs) { using (XmlReader subjectReader = Subject?.CreateReader()) using (XmlReader otherReader = unexpected?.CreateReader()) @@ -153,11 +153,13 @@ public AndWhichConstraint HaveRoot(string expecte /// Zero or more objects to format using the placeholders in . /// /// - public AndWhichConstraint is . HaveRoot(XName expected, string because = "", params object[] becauseArgs) + public AndWhichConstraint HaveRoot(XName expected, string because = "", + params object[] becauseArgs) { if (Subject is null) { - throw new InvalidOperationException("Cannot assert the document has a root element if the document itself is ."); + throw new InvalidOperationException( + "Cannot assert the document has a root element if the document itself is ."); } Guard.ThrowIfArgumentIsNull(expected, nameof(expected), @@ -166,7 +168,7 @@ public AndWhichConstraint HaveRoot(XName expected XElement root = Subject.Root; Execute.Assertion - .ForCondition((root is not null) && (root.Name == expected)) + .ForCondition(root is not null && root.Name == expected) .BecauseOf(because, becauseArgs) .FailWith( "Expected {context:subject} to have root element {0}{reason}, but found {1}.", @@ -250,7 +252,7 @@ public AndWhichConstraint HaveElement(XName expec } Guard.ThrowIfArgumentIsNull(expected, nameof(expected), - "Cannot assert the document has an element if the expected name is ."); + "Cannot assert the document has an element if the expected name is ."); Execute.Assertion .ForCondition(Subject.Root is not null) @@ -260,6 +262,7 @@ public AndWhichConstraint HaveElement(XName expec expected.ToString()); XElement xElement = Subject.Root.Element(expected); + Execute.Assertion .ForCondition(xElement is not null) .BecauseOf(because, becauseArgs) @@ -293,7 +296,7 @@ public AndWhichConstraint> HaveElemen params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(expected, nameof(expected), - "Cannot assert the document has an element count if the element name is ."); + "Cannot assert the document has an element count if the element name is ."); bool success = Execute.Assertion .ForCondition(Subject is not null) @@ -305,6 +308,7 @@ public AndWhichConstraint> HaveElemen if (success) { var root = Subject.Root; + success = Execute.Assertion .ForCondition(root is not null) .BecauseOf(because, becauseArgs) diff --git a/Src/FluentAssertions/Xml/XElementAssertions.cs b/Src/FluentAssertions/Xml/XElementAssertions.cs index a355804a24..6b0f916716 100644 --- a/Src/FluentAssertions/Xml/XElementAssertions.cs +++ b/Src/FluentAssertions/Xml/XElementAssertions.cs @@ -315,7 +315,7 @@ public AndWhichConstraint> HaveElement params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(expected, nameof(expected), - "Cannot assert the element has an element count if the element name is ."); + "Cannot assert the element has an element count if the element name is ."); bool success = Execute.Assertion .ForCondition(Subject is not null) diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt index 35ba3945ee..bdec61a8fb 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt @@ -192,7 +192,7 @@ namespace FluentAssertions public static System.Action Logger { get; set; } public static string DetermineCallerIdentity() { } } - [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false)] + [System.AttributeUsage(System.AttributeTargets.Method)] public class CustomAssertionAttribute : System.Attribute { public CustomAssertionAttribute() { } @@ -1700,7 +1700,7 @@ namespace FluentAssertions.Formatting public bool CanHandle(object value) { } public void Format(object value, FluentAssertions.Formatting.FormattedObjectGraph formattedGraph, FluentAssertions.Formatting.FormattingContext context, FluentAssertions.Formatting.FormatChild formatChild) { } } - [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false)] + [System.AttributeUsage(System.AttributeTargets.Method)] public class ValueFormatterAttribute : System.Attribute { public ValueFormatterAttribute() { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt index 1d2c37fec9..3d7f0e179e 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt @@ -205,7 +205,7 @@ namespace FluentAssertions public static System.Action Logger { get; set; } public static string DetermineCallerIdentity() { } } - [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false)] + [System.AttributeUsage(System.AttributeTargets.Method)] public class CustomAssertionAttribute : System.Attribute { public CustomAssertionAttribute() { } @@ -1725,7 +1725,7 @@ namespace FluentAssertions.Formatting public bool CanHandle(object value) { } public void Format(object value, FluentAssertions.Formatting.FormattedObjectGraph formattedGraph, FluentAssertions.Formatting.FormattingContext context, FluentAssertions.Formatting.FormatChild formatChild) { } } - [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false)] + [System.AttributeUsage(System.AttributeTargets.Method)] public class ValueFormatterAttribute : System.Attribute { public ValueFormatterAttribute() { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt index fde342567f..b205411ad4 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt @@ -192,7 +192,7 @@ namespace FluentAssertions public static System.Action Logger { get; set; } public static string DetermineCallerIdentity() { } } - [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false)] + [System.AttributeUsage(System.AttributeTargets.Method)] public class CustomAssertionAttribute : System.Attribute { public CustomAssertionAttribute() { } @@ -1700,7 +1700,7 @@ namespace FluentAssertions.Formatting public bool CanHandle(object value) { } public void Format(object value, FluentAssertions.Formatting.FormattedObjectGraph formattedGraph, FluentAssertions.Formatting.FormattingContext context, FluentAssertions.Formatting.FormatChild formatChild) { } } - [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false)] + [System.AttributeUsage(System.AttributeTargets.Method)] public class ValueFormatterAttribute : System.Attribute { public ValueFormatterAttribute() { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt index fde342567f..b205411ad4 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt @@ -192,7 +192,7 @@ namespace FluentAssertions public static System.Action Logger { get; set; } public static string DetermineCallerIdentity() { } } - [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false)] + [System.AttributeUsage(System.AttributeTargets.Method)] public class CustomAssertionAttribute : System.Attribute { public CustomAssertionAttribute() { } @@ -1700,7 +1700,7 @@ namespace FluentAssertions.Formatting public bool CanHandle(object value) { } public void Format(object value, FluentAssertions.Formatting.FormattedObjectGraph formattedGraph, FluentAssertions.Formatting.FormattingContext context, FluentAssertions.Formatting.FormatChild formatChild) { } } - [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false)] + [System.AttributeUsage(System.AttributeTargets.Method)] public class ValueFormatterAttribute : System.Attribute { public ValueFormatterAttribute() { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt index ba3dcd2112..d1d42f2ee8 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt @@ -191,7 +191,7 @@ namespace FluentAssertions public static System.Action Logger { get; set; } public static string DetermineCallerIdentity() { } } - [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false)] + [System.AttributeUsage(System.AttributeTargets.Method)] public class CustomAssertionAttribute : System.Attribute { public CustomAssertionAttribute() { } @@ -1651,7 +1651,7 @@ namespace FluentAssertions.Formatting public bool CanHandle(object value) { } public void Format(object value, FluentAssertions.Formatting.FormattedObjectGraph formattedGraph, FluentAssertions.Formatting.FormattingContext context, FluentAssertions.Formatting.FormatChild formatChild) { } } - [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false)] + [System.AttributeUsage(System.AttributeTargets.Method)] public class ValueFormatterAttribute : System.Attribute { public ValueFormatterAttribute() { } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt index fde342567f..b205411ad4 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt @@ -192,7 +192,7 @@ namespace FluentAssertions public static System.Action Logger { get; set; } public static string DetermineCallerIdentity() { } } - [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false)] + [System.AttributeUsage(System.AttributeTargets.Method)] public class CustomAssertionAttribute : System.Attribute { public CustomAssertionAttribute() { } @@ -1700,7 +1700,7 @@ namespace FluentAssertions.Formatting public bool CanHandle(object value) { } public void Format(object value, FluentAssertions.Formatting.FormattedObjectGraph formattedGraph, FluentAssertions.Formatting.FormattingContext context, FluentAssertions.Formatting.FormatChild formatChild) { } } - [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false)] + [System.AttributeUsage(System.AttributeTargets.Method)] public class ValueFormatterAttribute : System.Attribute { public ValueFormatterAttribute() { } diff --git a/Tests/Benchmarks/CheckIfMemberIsBrowsable.cs b/Tests/Benchmarks/CheckIfMemberIsBrowsable.cs index 004da0bd02..12da2de01f 100644 --- a/Tests/Benchmarks/CheckIfMemberIsBrowsable.cs +++ b/Tests/Benchmarks/CheckIfMemberIsBrowsable.cs @@ -1,6 +1,5 @@ using System.ComponentModel; using System.Reflection; - using BenchmarkDotNet.Attributes; namespace Benchmarks; @@ -12,6 +11,7 @@ public class CheckIfMemberIsBrowsableBenchmarks public bool IsBrowsable { get; set; } public int BrowsableField; + [EditorBrowsable(EditorBrowsableState.Never)] public int NonBrowsableField; diff --git a/Tests/Benchmarks/LargeDataTableEquivalency.cs b/Tests/Benchmarks/LargeDataTableEquivalency.cs index 4937996c67..ff4b0f9455 100644 --- a/Tests/Benchmarks/LargeDataTableEquivalency.cs +++ b/Tests/Benchmarks/LargeDataTableEquivalency.cs @@ -1,11 +1,8 @@ using System; using System.Data; using System.Linq; - using BenchmarkDotNet.Attributes; - using Bogus; - using FluentAssertions; using FluentAssertions.Data; @@ -48,7 +45,7 @@ public void GlobalSetup() private static object GetData(Faker faker, Type columnType) { - return (Type.GetTypeCode(columnType)) switch + return Type.GetTypeCode(columnType) switch { TypeCode.Empty or TypeCode.DBNull => null, TypeCode.Boolean => faker.Random.Bool(), @@ -73,9 +70,13 @@ private static object GetData(Faker faker, Type columnType) private static object GetDefault(Faker faker, Type columnType) { if (columnType == typeof(TimeSpan)) + { return faker.Date.Future() - faker.Date.Future(); + } else if (columnType == typeof(Guid)) + { return faker.Random.Guid(); + } throw new Exception("Unable to populate column of type " + columnType); } diff --git a/Tests/Benchmarks/LargeObjectGraph.cs b/Tests/Benchmarks/LargeObjectGraph.cs index d09741412f..b8adbe0b6b 100644 --- a/Tests/Benchmarks/LargeObjectGraph.cs +++ b/Tests/Benchmarks/LargeObjectGraph.cs @@ -1,7 +1,5 @@ using System; - using BenchmarkDotNet.Attributes; - using FluentAssertions; using FluentAssertions.Primitives; @@ -31,6 +29,6 @@ public void GlobalSetup() } [Benchmark] - public AndConstraint BeEquivalentTo() - => copy1.Should().BeEquivalentTo(copy2, config => config.AllowingInfiniteRecursion()); + public AndConstraint BeEquivalentTo() => + copy1.Should().BeEquivalentTo(copy2, config => config.AllowingInfiniteRecursion()); } diff --git a/Tests/Benchmarks/Program.cs b/Tests/Benchmarks/Program.cs index 18381f1c64..6ff37e86ae 100644 --- a/Tests/Benchmarks/Program.cs +++ b/Tests/Benchmarks/Program.cs @@ -1,8 +1,10 @@ -using BenchmarkDotNet.Columns; +using System.Globalization; +using BenchmarkDotNet.Columns; using BenchmarkDotNet.Configs; using BenchmarkDotNet.Exporters.Csv; using BenchmarkDotNet.Reports; using BenchmarkDotNet.Running; +using Perfolizer.Horology; namespace Benchmarks; @@ -13,10 +15,10 @@ public static void Main() var exporter = new CsvExporter( CsvSeparator.CurrentCulture, new SummaryStyle( - cultureInfo: System.Globalization.CultureInfo.GetCultureInfo("nl-NL"), + cultureInfo: CultureInfo.GetCultureInfo("nl-NL"), printUnitsInHeader: true, printUnitsInContent: false, - timeUnit: Perfolizer.Horology.TimeUnit.Microsecond, + timeUnit: TimeUnit.Microsecond, sizeUnit: SizeUnit.KB )); diff --git a/Tests/Benchmarks/UsersOfGetClosedGenericInterfaces.cs b/Tests/Benchmarks/UsersOfGetClosedGenericInterfaces.cs index 15d2dab088..5b778fa409 100644 --- a/Tests/Benchmarks/UsersOfGetClosedGenericInterfaces.cs +++ b/Tests/Benchmarks/UsersOfGetClosedGenericInterfaces.cs @@ -1,11 +1,10 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; - using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; using Bogus; - using FluentAssertions.Equivalency; using FluentAssertions.Equivalency.Steps; using FluentAssertions.Equivalency.Tracing; @@ -37,7 +36,8 @@ private class Context : IEquivalencyValidationContext public IEquivalencyValidationContext AsCollectionItem(string index) => throw new NotImplementedException(); - public IEquivalencyValidationContext AsDictionaryItem(TKey key) => throw new NotImplementedException(); + public IEquivalencyValidationContext AsDictionaryItem(TKey key) => + throw new NotImplementedException(); public IEquivalencyValidationContext Clone() => throw new NotImplementedException(); } @@ -85,7 +85,7 @@ private class Config : IEquivalencyAssertionOptions public Type DataType { get; set; } [GlobalSetup] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0055:Fix formatting", Justification = "Big long list of one-liners")] + [SuppressMessage("Style", "IDE0055:Fix formatting", Justification = "Big long list of one-liners")] public void GlobalSetup() { dictionaryStep = new GenericDictionaryEquivalencyStep(); @@ -151,24 +151,35 @@ public void GlobalSetup() break; default: + { + if (DataType == typeof(TimeSpan)) + { + values[i] = faker.Date.Future() - faker.Date.Future(); + } + else if (DataType == typeof(Guid)) + { + values[i] = faker.Random.Guid(); + } + else if (DataType == typeof(Dictionary)) { - if (DataType == typeof(TimeSpan)) - values[i] = faker.Date.Future() - faker.Date.Future(); - else if (DataType == typeof(Guid)) - values[i] = faker.Random.Guid(); - else if (DataType == typeof(Dictionary)) - values[i] = new Dictionary() { { faker.Random.Int(), faker.Random.Int() } }; - else if (DataType == typeof(IEnumerable)) - values[i] = new int[] { faker.Random.Int(), faker.Random.Int() }; - else - throw new Exception("Unable to populate data of type " + DataType); - - break; + values[i] = new Dictionary + { { faker.Random.Int(), faker.Random.Int() } }; } + else if (DataType == typeof(IEnumerable)) + { + values[i] = new[] { faker.Random.Int(), faker.Random.Int() }; + } + else + { + throw new Exception("Unable to populate data of type " + DataType); + } + + break; + } } } - context = new Context() + context = new Context { Options = new Config() }; diff --git a/Tests/FluentAssertions.Equivalency.Specs/BasicSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/BasicSpecs.cs index 9c9b8a2c23..a2d2c94c8e 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/BasicSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/BasicSpecs.cs @@ -166,7 +166,7 @@ public class VirtualClass public new virtual bool Equals(object obj) { - return (obj is VirtualClass other) && other.Property == Property; + return obj is VirtualClass other && other.Property == Property; } } diff --git a/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs index dbbfbf5acc..2d489aac88 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs @@ -36,7 +36,7 @@ public SubDummy(int id) public override bool Equals(object obj) { return obj is SubDummy subDummy - && Id == subDummy.Id; + && Id == subDummy.Id; } public override int GetHashCode() @@ -86,8 +86,8 @@ public void CopyTo(Array array, int index) private class MultiEnumerable : IEnumerable, IEnumerable { - private readonly List ints = new List(); - private readonly List longs = new List(); + private readonly List ints = new(); + private readonly List longs = new(); IEnumerator IEnumerable.GetEnumerator() { @@ -175,7 +175,7 @@ public IEnumerable SelectMembers(INode currentNode, IEnumerable> innerRoles = new Dictionary>(); + private readonly Dictionary> innerRoles = new(); public virtual Dictionary> Roles { @@ -199,8 +199,15 @@ public class ExceptionThrowingClass public void When_the_expectation_is_an_array_of_interface_type_it_should_respect_declared_types() { // Arrange - var actual = new IInterface[] { new MyClass() { InterfaceProperty = 1, ClassProperty = 42 } }; - var expected = new IInterface[] { new MyClass() { InterfaceProperty = 1, ClassProperty = 1337 } }; + var actual = new IInterface[] + { + new MyClass { InterfaceProperty = 1, ClassProperty = 42 } + }; + + var expected = new IInterface[] + { + new MyClass { InterfaceProperty = 1, ClassProperty = 1337 } + }; // Act Action act = () => actual.Should().BeEquivalentTo(expected); @@ -213,10 +220,10 @@ public void When_the_expectation_is_an_array_of_interface_type_it_should_respect public void When_the_expectation_has_fewer_dimensions_than_a_multi_dimensional_subject_it_should_fail() { // Arrange - object objectA = new object(); - object objectB = new object(); + object objectA = new(); + object objectB = new(); - var actual = new object[][] { new object[] { objectA, objectB } }; + var actual = new[] { new[] { objectA, objectB } }; var expected = actual[0]; // Act @@ -295,9 +302,9 @@ public void public void When_a_collection_does_not_match_it_should_include_items_in_message() { // Arrange - var subject = new int[] { 1, 2 }; + var subject = new[] { 1, 2 }; - var expectation = new int[] { 3, 2, 1 }; + var expectation = new[] { 3, 2, 1 }; // Act Action action = () => subject.Should().BeEquivalentTo(expectation); @@ -329,12 +336,12 @@ public void When_collection_of_same_count_does_not_match_it_should_include_at_mo public void When_a_nullable_collection_does_not_match_it_should_throw() { // Arrange - var subject = new { Values = (ImmutableArray?)ImmutableArray.Create(1, 2, 3) }; + var subject = new { Values = (ImmutableArray?)ImmutableArray.Create(1, 2, 3) }; // Act Action act = () => subject.Should().BeEquivalentTo(new { - Values = (ImmutableArray?)ImmutableArray.Create(1, 2, 4) + Values = (ImmutableArray?)ImmutableArray.Create(1, 2, 4) }); // Assert @@ -453,11 +460,11 @@ public void When_a_collection_property_contains_objects_with_matching_properties public void When_two_deeply_nested_collections_are_equivalent_while_ignoring_the_order_it_should_not_throw() { // Arrange - var items = new[] { new int[0], new int[] { 42 } }; + var items = new[] { new int[0], new[] { 42 } }; // Act / Assert items.Should().BeEquivalentTo( - new[] { new int[] { 42 }, new int[0] } + new[] { new[] { 42 }, new int[0] } ); } @@ -484,8 +491,8 @@ public void When_a_collection_property_contains_objects_with_mismatching_propert public void When_the_subject_is_a_non_generic_collection_it_should_still_work() { // Arrange - object item = new object(); - object[] array = new[] { item }; + object item = new(); + object[] array = { item }; IList readOnlyList = ArrayList.ReadOnly(array); // Act / Assert @@ -1091,8 +1098,8 @@ public void When_a_strongly_typed_collection_is_declared_as_an_untyped_collection_and_runtime_checking_is_configured_is_should_use_the_runtime_type() { // Arrange - ICollection collection1 = new List { new Car() }; - ICollection collection2 = new List { new Customer() }; + ICollection collection1 = new List { new() }; + ICollection collection2 = new List { new() }; // Act Action act = @@ -1180,6 +1187,7 @@ public void // Arrange const int N = 100000; var subject = new List(N) { "one" }; + for (int i = 1; i < N; i++) { subject.Add("two"); @@ -1208,9 +1216,9 @@ public void When_all_subject_items_are_equivalent_to_expectation_object_it_shoul // Arrange var subject = new List { - new SomeDto { Name = "someDto", Age = 1 }, - new SomeDto { Name = "someDto", Age = 1 }, - new SomeDto { Name = "someDto", Age = 1 } + new() { Name = "someDto", Age = 1 }, + new() { Name = "someDto", Age = 1 }, + new() { Name = "someDto", Age = 1 } }; // Act @@ -1231,18 +1239,18 @@ public void When_all_subject_items_are_equivalent_to_expectation_object_it_shoul // Arrange var subject = new List { - new SomeDto { Name = "someDto", Age = 1 }, - new SomeDto { Name = "someDto", Age = 1 }, - new SomeDto { Name = "someDto", Age = 1 } + new() { Name = "someDto", Age = 1 }, + new() { Name = "someDto", Age = 1 }, + new() { Name = "someDto", Age = 1 } }; // Act Action action = () => subject.Should().AllBeEquivalentTo(new - { - Name = "someDto", - Age = 1, - Birthdate = default(DateTime) - }) + { + Name = "someDto", + Age = 1, + Birthdate = default(DateTime) + }) .And.HaveCount(3); // Assert @@ -1285,6 +1293,7 @@ public void // Arrange const int N = 100000; var subject = new List(N) { 1 }; + for (int i = 1; i < N; i++) { subject.Add(2); @@ -1421,7 +1430,7 @@ public void Can_force_strict_ordering_based_on_the_parent_type_of_an_unordered_c }; // Act - Action action = () => subject.Should().BeEquivalentTo(expectation, options => options + Action action = () => subject.Should().BeEquivalentTo(expectation, options => options .WithStrictOrderingFor(oi => oi.ParentType == expectation[0].GetType())); // Assert @@ -1536,7 +1545,7 @@ public void When_asserting_equivalence_of_generic_collections_it_should_respect_ { // Arrange var collection1 = new Collection { new DerivedCustomerType("123") }; - var collection2 = new Collection { new CustomerType("123") }; + var collection2 = new Collection { new("123") }; // Act Action act = () => collection1.Should().BeEquivalentTo(collection2); @@ -1632,12 +1641,14 @@ public void When_no_collection_item_matches_it_should_report_the_closest_match() // Arrange var subject = new List { - new Customer { Name = "John", Age = 27, Id = 1 }, new Customer { Name = "Jane", Age = 30, Id = 2 } + new() { Name = "John", Age = 27, Id = 1 }, + new() { Name = "Jane", Age = 30, Id = 2 } }; var expectation = new List { - new Customer { Name = "Jane", Age = 30, Id = 2 }, new Customer { Name = "John", Age = 28, Id = 1 } + new() { Name = "Jane", Age = 30, Id = 2 }, + new() { Name = "John", Age = 28, Id = 1 } }; // Act @@ -1878,8 +1889,8 @@ public void When_the_expectation_is_null_it_should_throw() // Arrange var actual = new[,] { - { 1, 2, 3 }, - { 4, 5, 6 } + { 1, 2, 3 }, + { 4, 5, 6 } }; // Act @@ -1978,7 +1989,7 @@ public void When_the_length_of_the_first_dimension_differs_between_the_arrays_it public void When_the_number_of_dimensions_of_the_arrays_are_not_the_same_it_should_throw() { // Arrange - var actual = new[, ,] + var actual = new[,,] { { { 1 }, @@ -2066,11 +2077,15 @@ public void public void When_the_subject_contains_less_items_than_expected_it_should_throw() { // Arrange - var subject = new List { new Customer { Name = "John", Age = 27, Id = 1 } }; + var subject = new List + { + new() { Name = "John", Age = 27, Id = 1 } + }; var expectation = new List { - new Customer { Name = "John", Age = 27, Id = 1 }, new Customer { Name = "Jane", Age = 24, Id = 2 } + new() { Name = "John", Age = 27, Id = 1 }, + new() { Name = "Jane", Age = 24, Id = 2 } }; // Act @@ -2089,10 +2104,14 @@ public void When_the_subject_contains_more_items_than_expected_it_should_throw() // Arrange var subject = new List { - new Customer { Name = "John", Age = 27, Id = 1 }, new Customer { Name = "Jane", Age = 24, Id = 2 } + new() { Name = "John", Age = 27, Id = 1 }, + new() { Name = "Jane", Age = 24, Id = 2 } }; - var expectation = new List { new Customer { Name = "John", Age = 27, Id = 1 } }; + var expectation = new List + { + new() { Name = "John", Age = 27, Id = 1 } + }; // Act Action action = @@ -2110,16 +2129,16 @@ public void When_the_subject_contains_same_number_of_items_and_both_contain_dupl // Arrange var subject = new List { - new Customer { Name = "John", Age = 27, Id = 1 }, - new Customer { Name = "John", Age = 27, Id = 1 }, - new Customer { Name = "Jane", Age = 24, Id = 2 } + new() { Name = "John", Age = 27, Id = 1 }, + new() { Name = "John", Age = 27, Id = 1 }, + new() { Name = "Jane", Age = 24, Id = 2 } }; var expectation = new List { - new Customer { Name = "Jane", Age = 24, Id = 2 }, - new Customer { Name = "John", Age = 27, Id = 1 }, - new Customer { Name = "John", Age = 27, Id = 1 } + new() { Name = "Jane", Age = 24, Id = 2 }, + new() { Name = "John", Age = 27, Id = 1 }, + new() { Name = "John", Age = 27, Id = 1 } }; // Act @@ -2136,12 +2155,14 @@ public void When_the_subject_contains_same_number_of_items_but_expectation_conta // Arrange var subject = new List { - new Customer { Name = "John", Age = 27, Id = 1 }, new Customer { Name = "Jane", Age = 24, Id = 2 } + new() { Name = "John", Age = 27, Id = 1 }, + new() { Name = "Jane", Age = 24, Id = 2 } }; var expectation = new List { - new Customer { Name = "John", Age = 27, Id = 1 }, new Customer { Name = "John", Age = 27, Id = 1 } + new() { Name = "John", Age = 27, Id = 1 }, + new() { Name = "John", Age = 27, Id = 1 } }; // Act @@ -2160,12 +2181,14 @@ public void When_the_subject_contains_same_number_of_items_but_subject_contains_ // Arrange var subject = new List { - new Customer { Name = "John", Age = 27, Id = 1 }, new Customer { Name = "John", Age = 27, Id = 1 } + new() { Name = "John", Age = 27, Id = 1 }, + new() { Name = "John", Age = 27, Id = 1 } }; var expectation = new List { - new Customer { Name = "John", Age = 27, Id = 1 }, new Customer { Name = "Jane", Age = 24, Id = 2 } + new() { Name = "John", Age = 27, Id = 1 }, + new() { Name = "Jane", Age = 24, Id = 2 } }; // Act @@ -2249,12 +2272,14 @@ public void When_two_lists_dont_contain_the_same_structural_equal_objects_it_sho // Arrange var subject = new List { - new Customer { Name = "John", Age = 27, Id = 1 }, new Customer { Name = "Jane", Age = 24, Id = 2 } + new() { Name = "John", Age = 27, Id = 1 }, + new() { Name = "Jane", Age = 24, Id = 2 } }; var expectation = new List { - new Customer { Name = "John", Age = 27, Id = 1 }, new Customer { Name = "Jane", Age = 30, Id = 2 } + new() { Name = "John", Age = 27, Id = 1 }, + new() { Name = "Jane", Age = 30, Id = 2 } }; // Act @@ -2272,12 +2297,14 @@ public void When_two_lists_only_differ_in_excluded_properties_it_should_not_thro // Arrange var subject = new List { - new Customer { Name = "John", Age = 27, Id = 1 }, new Customer { Name = "Jane", Age = 24, Id = 2 } + new() { Name = "John", Age = 27, Id = 1 }, + new() { Name = "Jane", Age = 24, Id = 2 } }; var expectation = new List { - new CustomerDto { Name = "John", Age = 27 }, new CustomerDto { Name = "Jane", Age = 30 } + new() { Name = "John", Age = 27 }, + new() { Name = "Jane", Age = 30 } }; // Act @@ -2426,12 +2453,14 @@ public void When_two_ordered_lists_are_structurally_equivalent_it_should_succeed // Arrange var subject = new List { - new Customer { Name = "John", Age = 27, Id = 1 }, new Customer { Name = "Jane", Age = 24, Id = 2 } + new() { Name = "John", Age = 27, Id = 1 }, + new() { Name = "Jane", Age = 24, Id = 2 } }; var expectation = new List { - new Customer { Name = "John", Age = 27, Id = 1 }, new Customer { Name = "Jane", Age = 24, Id = 2 } + new() { Name = "John", Age = 27, Id = 1 }, + new() { Name = "Jane", Age = 24, Id = 2 } }; // Act @@ -2453,7 +2482,8 @@ public void When_two_unordered_lists_are_structurally_equivalent_and_order_is_st var expectation = new Collection { - new Customer { Name = "Jane", Age = 24, Id = 2 }, new Customer { Name = "John", Age = 27, Id = 1 } + new() { Name = "Jane", Age = 24, Id = 2 }, + new() { Name = "John", Age = 27, Id = 1 } }; // Act @@ -2476,7 +2506,8 @@ public void When_two_unordered_lists_are_structurally_equivalent_and_order_was_r var expectation = new Collection { - new Customer { Name = "Jane", Age = 24, Id = 2 }, new Customer { Name = "John", Age = 27, Id = 1 } + new() { Name = "Jane", Age = 24, Id = 2 }, + new() { Name = "John", Age = 27, Id = 1 } }; // Act @@ -2504,7 +2535,8 @@ public void When_two_unordered_lists_are_structurally_equivalent_and_order_was_r var expectation = new Collection { - new Customer { Name = "Jane", Age = 24, Id = 2 }, new Customer { Name = "John", Age = 27, Id = 1 } + new() { Name = "Jane", Age = 24, Id = 2 }, + new() { Name = "John", Age = 27, Id = 1 } }; // Act @@ -2526,7 +2558,8 @@ public void When_two_unordered_lists_are_structurally_equivalent_it_should_succe var expectation = new Collection { - new Customer { Name = "Jane", Age = 24, Id = 2 }, new Customer { Name = "John", Age = 27, Id = 1 } + new() { Name = "Jane", Age = 24, Id = 2 }, + new() { Name = "John", Age = 27, Id = 1 } }; // Act @@ -2541,8 +2574,8 @@ public void When_two_unordered_lists_are_structurally_equivalent_it_should_succe public void When_two_unordered_lists_contain_empty_different_objects_it_should_throw() { // Arrange - var actual = new object[] { new object() }; - var expected = new object[] { new object() }; + var actual = new object[] { new() }; + var expected = new object[] { new() }; // Act Action act = () => actual.Should().BeEquivalentTo(expected); @@ -2556,7 +2589,7 @@ public void When_two_unordered_lists_contain_null_in_subject_it_should_throw() { // Arrange var actual = new object[] { null }; - var expected = new object[] { new object() }; + var expected = new object[] { new() }; // Act Action act = () => actual.Should().BeEquivalentTo(expected); @@ -2569,7 +2602,7 @@ public void When_two_unordered_lists_contain_null_in_subject_it_should_throw() public void When_two_unordered_lists_contain_null_in_expectation_it_should_throw() { // Arrange - var actual = new object[] { new object() }; + var actual = new object[] { new() }; var expected = new object[] { null }; // Act @@ -2595,8 +2628,9 @@ public void When_two_unordered_lists_contain_null_in_expectation_it_should_throw public void When_an_exception_is_thrown_during_data_access_the_stack_trace_contains_the_original_site() { // Arrange - var genericCollectionA = new List() { new ExceptionThrowingClass() }; - var genericCollectionB = new List() { new ExceptionThrowingClass() }; + var genericCollectionA = new List { new() }; + + var genericCollectionB = new List { new() }; var expectedTargetSite = typeof(ExceptionThrowingClass) .GetProperty(nameof(ExceptionThrowingClass.ExceptionThrowingProperty)).GetMethod; @@ -2616,8 +2650,8 @@ public static IEnumerable ArrayTestData() }; return from x in arrays - from y in arrays - select new object[] { x, y }; + from y in arrays + select new[] { x, y }; } [Fact] @@ -2650,6 +2684,7 @@ ClassWithLotsOfProperties GetObject(int i) var expectation = new List(); var maxAmount = 100; + for (var i = 0; i < maxAmount; i++) { actual.Add(GetObject(i)); @@ -2711,6 +2746,6 @@ public LogbookCode(string key) Key = key; } - public string Key { get; protected set; } + public string Key { get; } } } diff --git a/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs index 4f73f850cc..b7597b2b87 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs @@ -12,13 +12,27 @@ public class CyclicReferencesSpecs public void When_validating_nested_properties_that_have_cyclic_references_it_should_throw() { // Arrange - var cyclicRoot = new CyclicRoot { Text = "Root" }; + var cyclicRoot = new CyclicRoot + { + Text = "Root" + }; - cyclicRoot.Level = new CyclicLevel1 { Text = "Level1", Root = cyclicRoot }; + cyclicRoot.Level = new CyclicLevel1 + { + Text = "Level1", + Root = cyclicRoot + }; - var cyclicRootDto = new CyclicRootDto { Text = "Root" }; + var cyclicRootDto = new CyclicRootDto + { + Text = "Root" + }; - cyclicRootDto.Level = new CyclicLevel1Dto { Text = "Level1", Root = cyclicRootDto }; + cyclicRootDto.Level = new CyclicLevel1Dto + { + Text = "Level1", + Root = cyclicRootDto + }; // Act Action act = () => cyclicRoot.Should().BeEquivalentTo(cyclicRootDto); @@ -33,11 +47,27 @@ public void When_validating_nested_properties_that_have_cyclic_references_it_sho public void When_validating_nested_properties_and_ignoring_cyclic_references_it_should_succeed() { // Arrange - var cyclicRoot = new CyclicRoot { Text = "Root" }; - cyclicRoot.Level = new CyclicLevel1 { Text = "Level1", Root = cyclicRoot }; + var cyclicRoot = new CyclicRoot + { + Text = "Root" + }; + + cyclicRoot.Level = new CyclicLevel1 + { + Text = "Level1", + Root = cyclicRoot + }; + + var cyclicRootDto = new CyclicRootDto + { + Text = "Root" + }; - var cyclicRootDto = new CyclicRootDto { Text = "Root" }; - cyclicRootDto.Level = new CyclicLevel1Dto { Text = "Level1", Root = cyclicRootDto }; + cyclicRootDto.Level = new CyclicLevel1Dto + { + Text = "Level1", + Root = cyclicRootDto + }; // Act Action act = () => @@ -92,13 +122,27 @@ public Child(Parent parent, int stuff = 0) public void When_validating_nested_properties_that_are_null_it_should_not_throw_on_cyclic_references() { // Arrange - var actual = new CyclicRoot { Text = null }; + var actual = new CyclicRoot + { + Text = null + }; - actual.Level = new CyclicLevel1 { Text = null, Root = null }; + actual.Level = new CyclicLevel1 + { + Text = null, + Root = null + }; - var expectation = new CyclicRootDto { Text = null }; + var expectation = new CyclicRootDto + { + Text = null + }; - expectation.Level = new CyclicLevel1Dto { Text = null, Root = null }; + expectation.Level = new CyclicLevel1Dto + { + Text = null, + Root = null + }; // Act Action act = () => actual.Should().BeEquivalentTo(expectation); @@ -111,13 +155,27 @@ public void When_validating_nested_properties_that_are_null_it_should_not_throw_ public void When_the_graph_contains_the_same_value_object_it_should_not_be_treated_as_a_cyclic_reference() { // Arrange - var actual = new CyclicRootWithValueObject { Object = new ValueObject("MyValue") }; + var actual = new CyclicRootWithValueObject + { + Object = new ValueObject("MyValue") + }; - actual.Level = new CyclicLevelWithValueObject { Object = new ValueObject("MyValue"), Root = null }; + actual.Level = new CyclicLevelWithValueObject + { + Object = new ValueObject("MyValue"), + Root = null + }; - var expectation = new CyclicRootWithValueObject { Object = new ValueObject("MyValue") }; + var expectation = new CyclicRootWithValueObject + { + Object = new ValueObject("MyValue") + }; - expectation.Level = new CyclicLevelWithValueObject { Object = new ValueObject("MyValue"), Root = null }; + expectation.Level = new CyclicLevelWithValueObject + { + Object = new ValueObject("MyValue"), + Root = null + }; // Act Action act = () => actual.Should().BeEquivalentTo(expectation); @@ -227,7 +285,12 @@ public void When_an_enumerable_collection_returns_itself_it_should_detect_the_cy // Act var instance1 = new SelfReturningEnumerable(); var instance2 = new SelfReturningEnumerable(); - var actual = new List { instance1, instance2 }; + + var actual = new List + { + instance1, + instance2 + }; // Assert Action act = () => actual.Should().BeEquivalentTo( @@ -277,14 +340,44 @@ public LogbookCode(string key) public void When_the_root_object_is_referenced_from_a_nested_object_it_should_treat_it_as_a_cyclic_reference() { // Arrange - var company1 = new MyCompany { Name = "Company" }; - var user1 = new MyUser { Name = "User", Company = company1 }; - var logo1 = new MyCompanyLogo { Url = "blank", Company = company1, CreatedBy = user1 }; + var company1 = new MyCompany + { + Name = "Company" + }; + + var user1 = new MyUser + { + Name = "User", + Company = company1 + }; + + var logo1 = new MyCompanyLogo + { + Url = "blank", + Company = company1, + CreatedBy = user1 + }; + company1.Logo = logo1; - var company2 = new MyCompany { Name = "Company" }; - var user2 = new MyUser { Name = "User", Company = company2 }; - var logo2 = new MyCompanyLogo { Url = "blank", Company = company2, CreatedBy = user2 }; + var company2 = new MyCompany + { + Name = "Company" + }; + + var user2 = new MyUser + { + Name = "User", + Company = company2 + }; + + var logo2 = new MyCompanyLogo + { + Url = "blank", + Company = company2, + CreatedBy = user2 + }; + company2.Logo = logo2; // Act @@ -298,15 +391,29 @@ public void When_the_root_object_is_referenced_from_a_nested_object_it_should_tr public void Allow_ignoring_cyclic_references_in_value_types_compared_by_members() { // Arrange - var expectation = new ValueTypeCircularDependency() { Title = "First" }; + var expectation = new ValueTypeCircularDependency + { + Title = "First" + }; - var second = new ValueTypeCircularDependency() { Title = "Second", Previous = expectation }; + var second = new ValueTypeCircularDependency + { + Title = "Second", + Previous = expectation + }; expectation.Next = second; - var subject = new ValueTypeCircularDependency() { Title = "First" }; + var subject = new ValueTypeCircularDependency + { + Title = "First" + }; - var secondCopy = new ValueTypeCircularDependency() { Title = "SecondDifferent", Previous = subject }; + var secondCopy = new ValueTypeCircularDependency + { + Title = "SecondDifferent", + Previous = subject + }; subject.Next = secondCopy; @@ -337,7 +444,7 @@ public override bool Equals(object obj) return true; } - return (obj is ValueTypeCircularDependency baseObj) && baseObj.Title == Title; + return obj is ValueTypeCircularDependency baseObj && baseObj.Title == Title; } public override int GetHashCode() diff --git a/Tests/FluentAssertions.Equivalency.Specs/DataColumnSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/DataColumnSpecs.cs index b5bdbbfbb2..0cc18b010b 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/DataColumnSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/DataColumnSpecs.cs @@ -111,6 +111,7 @@ public void When_DataColumn_has_changes_but_is_excluded_as_enumerable_it_should_ // Act & Assert IEnumerable excludedColumns = new[] { dataColumn2 }; + dataColumn1.Should().BeEquivalentTo(dataColumn2, options => options .ExcludingColumns(excludedColumns)); } @@ -131,7 +132,7 @@ public void When_DataColumn_has_changes_but_is_excluded_it_should_succeed_when_c // Act & Assert dataTable1.Should().BeEquivalentTo(dataTable2, options => options .ExcludingColumn(dataTable2.DecimalColumn) - .ExcludingRelated((DataTable dataTable) => dataTable.Constraints)); + .ExcludingRelated(dataTable => dataTable.Constraints)); } [Fact] @@ -149,7 +150,7 @@ public void When_DataColumn_has_changes_but_is_excluded_it_should_succeed_when_c // Act & Assert dataSet1.Should().BeEquivalentTo(dataSet2, options => options .ExcludingColumn(dataTable2.DecimalColumn) - .ExcludingRelated((DataTable dataTable) => dataTable.Constraints)); + .ExcludingRelated(dataTable => dataTable.Constraints)); } [Fact] diff --git a/Tests/FluentAssertions.Equivalency.Specs/DataRelationSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/DataRelationSpecs.cs index c2db671ba1..62ee3276dd 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/DataRelationSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/DataRelationSpecs.cs @@ -42,7 +42,7 @@ public void When_RelationName_does_not_match_and_property_is_excluded_it_should_ dataTable1.Should().BeEquivalentTo( dataTable2, options => options - .ExcludingRelated((DataRelation dataRelation) => dataRelation.RelationName)); + .ExcludingRelated(dataRelation => dataRelation.RelationName)); } [Fact] @@ -80,7 +80,7 @@ public void When_Nested_does_not_match_and_property_is_excluded_it_should_succee dataTable1.Should().BeEquivalentTo( dataTable2, options => options - .ExcludingRelated((DataRelation dataRelation) => dataRelation.Nested)); + .ExcludingRelated(dataRelation => dataRelation.Nested)); } [Fact] @@ -204,9 +204,9 @@ public void When_ParentColumns_do_not_match_and_property_is_excluded_it_should_s dataTable1.Should().BeEquivalentTo(dataTable2, options => options .Excluding(dataTable => dataTable.ChildRelations) .Excluding(dataTable => dataTable.Constraints) - .ExcludingRelated((DataRelation dataRelation) => dataRelation.ParentColumns) - .ExcludingRelated((DataRelation dataRelation) => dataRelation.ParentKeyConstraint) - .ExcludingRelated((DataRelation dataRelation) => dataRelation.ChildKeyConstraint)); + .ExcludingRelated(dataRelation => dataRelation.ParentColumns) + .ExcludingRelated(dataRelation => dataRelation.ParentKeyConstraint) + .ExcludingRelated(dataRelation => dataRelation.ChildKeyConstraint)); } [Fact] @@ -250,9 +250,9 @@ public void When_ChildColumns_do_not_match_and_property_is_excluded_it_should_su dataTable1.Should().BeEquivalentTo(dataTable2, options => options .Excluding(dataTable => dataTable.ParentRelations) .Excluding(dataTable => dataTable.Constraints) - .ExcludingRelated((DataRelation dataRelation) => dataRelation.ChildColumns) - .ExcludingRelated((DataRelation dataRelation) => dataRelation.ParentKeyConstraint) - .ExcludingRelated((DataRelation dataRelation) => dataRelation.ChildKeyConstraint)); + .ExcludingRelated(dataRelation => dataRelation.ChildColumns) + .ExcludingRelated(dataRelation => dataRelation.ParentKeyConstraint) + .ExcludingRelated(dataRelation => dataRelation.ChildKeyConstraint)); } [Fact] diff --git a/Tests/FluentAssertions.Equivalency.Specs/DataRowSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/DataRowSpecs.cs index 0b477aa166..bdac798576 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/DataRowSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/DataRowSpecs.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Data; using System.Linq; - using Xunit; using Xunit.Sdk; @@ -63,7 +62,8 @@ public void When_data_row_is_expected_to_be_null_and_isnt_then_equivalency_test_ } [Fact] - public void When_data_row_subject_is_deleted_and_expectation_is_not_but_the_row_state_is_excluded_equivalency_test_should_succeed() + public void + When_data_row_subject_is_deleted_and_expectation_is_not_but_the_row_state_is_excluded_equivalency_test_should_succeed() { // Arrange var dataSet1 = CreateDummyDataSet(); @@ -83,7 +83,8 @@ public void When_data_row_subject_is_deleted_and_expectation_is_not_but_the_row_ } [Fact] - public void When_data_row_expectation_is_deleted_and_subject_is_not_but_the_row_state_is_excluded_equivalency_test_should_succeed() + public void + When_data_row_expectation_is_deleted_and_subject_is_not_but_the_row_state_is_excluded_equivalency_test_should_succeed() { // Arrange var dataSet1 = CreateDummyDataSet(); @@ -147,11 +148,13 @@ public void When_data_row_is_modified_and_original_data_differs_equivalency_test Action action = () => dataRow1.Should().BeEquivalentTo(dataRow2); // Assert - action.Should().Throw().WithMessage("Expected dataRow1[Decimal, DataRowVersion.Original] to be *, but found *"); + action.Should().Throw() + .WithMessage("Expected dataRow1[Decimal, DataRowVersion.Original] to be *, but found *"); } [Fact] - public void When_data_row_is_modified_and_original_data_differs_but_original_data_is_excluded_then_equivalency_test_should_succeed() + public void + When_data_row_is_modified_and_original_data_differs_but_original_data_is_excluded_then_equivalency_test_should_succeed() { // Arrange var dataSet1 = CreateDummyDataSet(); @@ -196,7 +199,8 @@ public void When_data_row_type_does_not_match_and_mismatched_types_are_not_allow Action action = () => dataTable[0].Should().BeEquivalentTo(dataTableOfMismatchedType[0]); // Assert - action.Should().Throw().WithMessage("Expected dataTable[0] to be of type *TypedDataRow2, but found *TypedDataRow1*"); + action.Should().Throw() + .WithMessage("Expected dataTable[0] to be of type *TypedDataRow2, but found *TypedDataRow1*"); } [Fact] @@ -217,7 +221,8 @@ public void When_data_row_type_does_not_match_but_mismatched_types_are_allowed_t } [Fact] - public void When_one_data_row_has_errors_and_the_other_does_not_and_the_corresponding_property_is_not_excluded_then_equivalency_test_should_fail() + public void + When_one_data_row_has_errors_and_the_other_does_not_and_the_corresponding_property_is_not_excluded_then_equivalency_test_should_fail() { // Arrange var dataSet1 = CreateDummyDataSet(); @@ -237,7 +242,8 @@ public void When_one_data_row_has_errors_and_the_other_does_not_and_the_correspo } [Fact] - public void When_one_data_row_has_errors_and_the_other_does_not_but_the_corresponding_property_is_excluded_then_equivalency_test_should_succeed() + public void + When_one_data_row_has_errors_and_the_other_does_not_but_the_corresponding_property_is_excluded_then_equivalency_test_should_succeed() { // Arrange var dataSet1 = CreateDummyDataSet(); @@ -254,7 +260,8 @@ public void When_one_data_row_has_errors_and_the_other_does_not_but_the_correspo } [Fact] - public void When_the_data_row_state_does_not_match_and_the_corresponding_property_is_not_excluded_equivalency_test_should_fail() + public void + When_the_data_row_state_does_not_match_and_the_corresponding_property_is_not_excluded_equivalency_test_should_fail() { // Arrange var dataSet1 = CreateDummyDataSet(); @@ -277,7 +284,8 @@ public void When_the_data_row_state_does_not_match_and_the_corresponding_propert } [Fact] - public void When_the_data_row_state_does_not_match_but_the_corresponding_property_is_excluded_equivalency_test_should_succeed() + public void + When_the_data_row_state_does_not_match_but_the_corresponding_property_is_excluded_equivalency_test_should_succeed() { // Arrange var dataSet1 = CreateDummyDataSet(); @@ -341,6 +349,7 @@ public void Data_row_is_not_equivalent_to_another_type() // Arrange var table = new DataTable(); var dataRow = table.NewRow(); + var subject = new { DataRow = "foobar" @@ -414,7 +423,8 @@ public void Null_data_row_does_not_have_column() () => dataRow.Should().HaveColumn("Does not matter"); // Assert - action.Should().Throw().WithMessage("Expected dataRow to contain a column named *Does not matter*, but found *"); + action.Should().Throw() + .WithMessage("Expected dataRow to contain a column named *Does not matter*, but found *"); } [Fact] @@ -491,7 +501,8 @@ public void When_data_row_data_has_only_some_of_the_columns_being_asserted_then_ () => dataRow.Should().HaveColumns(subsetOfColumnNamesWithUnicorn); // Assert - action.Should().Throw().WithMessage("Expected table containing dataRow to contain a column named *Unicorn*"); + action.Should().Throw() + .WithMessage("Expected table containing dataRow to contain a column named *Unicorn*"); } [Fact] @@ -512,6 +523,7 @@ public void When_data_row_data_has_none_of_the_columns_being_asserted_then_it_sh () => dataRow.Should().HaveColumns(columnNames); // Assert - action.Should().Throw().WithMessage("Expected table containing dataRow to contain a column named *Unicorn*"); + action.Should().Throw() + .WithMessage("Expected table containing dataRow to contain a column named *Unicorn*"); } } diff --git a/Tests/FluentAssertions.Equivalency.Specs/DataSetSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/DataSetSpecs.cs index 2544c43dad..635c555045 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/DataSetSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/DataSetSpecs.cs @@ -3,7 +3,6 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; - using Xunit; using Xunit.Sdk; @@ -78,7 +77,8 @@ public void When_data_set_type_does_not_match_and_not_allowing_msimatched_types_ Action action = () => dataSet.Should().BeEquivalentTo(dataSetOfMismatchedType); // Assert - action.Should().Throw().WithMessage("Expected dataSet to be of type *TypedDataSetSubclass, but found System.Data.DataSet*"); + action.Should().Throw() + .WithMessage("Expected dataSet to be of type *TypedDataSetSubclass, but found System.Data.DataSet*"); } [Fact] @@ -137,7 +137,8 @@ public void When_data_set_name_does_not_match_but_the_corresponding_property_is_ } [Fact] - public void When_one_data_set_is_configured_to_be_case_sensitive_and_the_other_is_not_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() + public void + When_one_data_set_is_configured_to_be_case_sensitive_and_the_other_is_not_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -153,11 +154,13 @@ public void When_one_data_set_is_configured_to_be_case_sensitive_and_the_other_i Action action = () => dataSet1.Should().BeEquivalentTo(dataSet2); // Assert - action.Should().Throw().WithMessage("Expected dataSet1 to have CaseSensitive value of True, but found False instead*"); + action.Should().Throw() + .WithMessage("Expected dataSet1 to have CaseSensitive value of True, but found False instead*"); } [Fact] - public void When_one_data_set_is_configured_to_be_case_sensitive_and_the_other_is_not_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() + public void + When_one_data_set_is_configured_to_be_case_sensitive_and_the_other_is_not_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -174,7 +177,8 @@ public void When_one_data_set_is_configured_to_be_case_sensitive_and_the_other_i } [Fact] - public void When_one_data_set_is_configured_to_enforce_constraints_and_the_other_is_not_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() + public void + When_one_data_set_is_configured_to_enforce_constraints_and_the_other_is_not_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -190,11 +194,13 @@ public void When_one_data_set_is_configured_to_enforce_constraints_and_the_other Action action = () => dataSet1.Should().BeEquivalentTo(dataSet2); // Assert - action.Should().Throw().WithMessage("Expected dataSet1 to have EnforceConstraints value of False, but found True instead*"); + action.Should().Throw() + .WithMessage("Expected dataSet1 to have EnforceConstraints value of False, but found True instead*"); } [Fact] - public void When_one_data_set_is_configured_to_enforce_constraints_and_the_other_is_not_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() + public void + When_one_data_set_is_configured_to_enforce_constraints_and_the_other_is_not_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -211,7 +217,8 @@ public void When_one_data_set_is_configured_to_enforce_constraints_and_the_other } [Fact] - public void When_one_data_set_has_errors_and_the_other_does_not_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() + public void + When_one_data_set_has_errors_and_the_other_does_not_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -231,7 +238,8 @@ public void When_one_data_set_has_errors_and_the_other_does_not_and_the_correspo } [Fact] - public void When_one_data_set_has_errors_and_the_other_does_not_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() + public void + When_one_data_set_has_errors_and_the_other_does_not_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -249,7 +257,8 @@ public void When_one_data_set_has_errors_and_the_other_does_not_but_the_correspo } [Fact] - public void When_data_sets_have_mismatched_locale_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() + public void + When_data_sets_have_mismatched_locale_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -266,7 +275,8 @@ public void When_data_sets_have_mismatched_locale_and_the_corresponding_property Action action = () => dataSet1.Should().BeEquivalentTo(dataSet2); // Assert - action.Should().Throw().WithMessage("Expected dataSet1 to have Locale value of fr-CA, but found en-US instead*"); + action.Should().Throw() + .WithMessage("Expected dataSet1 to have Locale value of fr-CA, but found en-US instead*"); } [Fact] @@ -288,7 +298,8 @@ public void When_data_set_locale_does_not_match_but_the_corresponding_property_i } [Fact] - public void When_data_set_namespace_does_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() + public void + When_data_set_namespace_does_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -308,7 +319,8 @@ public void When_data_set_namespace_does_not_match_and_the_corresponding_propert } [Fact] - public void When_data_set_namespace_does_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() + public void + When_data_set_namespace_does_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -365,7 +377,8 @@ public void When_data_set_prefix_does_not_match_but_the_corresponding_property_i } [Fact] - public void When_data_set_remoting_format_does_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() + public void + When_data_set_remoting_format_does_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -373,7 +386,7 @@ public void When_data_set_remoting_format_does_not_match_and_the_corresponding_p var typedDataSet2 = new TypedDataSetSubclass(typedDataSet1); typedDataSet2.RemotingFormat = - (typedDataSet2.RemotingFormat == SerializationFormat.Binary) + typedDataSet2.RemotingFormat == SerializationFormat.Binary ? SerializationFormat.Xml : SerializationFormat.Binary; @@ -384,11 +397,14 @@ public void When_data_set_remoting_format_does_not_match_and_the_corresponding_p Action action = () => dataSet1.Should().BeEquivalentTo(dataSet2); // Assert - action.Should().Throw().WithMessage("Expected dataSet1 to have RemotingFormat value of SerializationFormat.Binary*, but found *Xml* instead*"); + action.Should().Throw() + .WithMessage( + "Expected dataSet1 to have RemotingFormat value of SerializationFormat.Binary*, but found *Xml* instead*"); } [Fact] - public void When_data_set_remoting_format_does_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() + public void + When_data_set_remoting_format_does_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -396,7 +412,7 @@ public void When_data_set_remoting_format_does_not_match_but_the_corresponding_p var typedDataSet2 = new TypedDataSetSubclass(typedDataSet1); typedDataSet2.RemotingFormat = - (typedDataSet2.RemotingFormat == SerializationFormat.Binary) + typedDataSet2.RemotingFormat == SerializationFormat.Binary ? SerializationFormat.Xml : SerializationFormat.Binary; @@ -406,12 +422,14 @@ public void When_data_set_remoting_format_does_not_match_but_the_corresponding_p // Act & Assert dataSet1.Should().BeEquivalentTo(dataSet2, options => options .Excluding(dataSet => dataSet.RemotingFormat) - .ExcludingRelated((DataTable dataTable) => dataTable.RemotingFormat)); + .ExcludingRelated(dataTable => dataTable.RemotingFormat)); } [Theory] [MemberData(nameof(AllChangeTypes))] - public void When_data_set_extended_properties_do_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail(ChangeType changeType) + public void + When_data_set_extended_properties_do_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail( + ChangeType changeType) { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -432,7 +450,9 @@ public void When_data_set_extended_properties_do_not_match_and_the_corresponding [Theory] [MemberData(nameof(AllChangeTypes))] - public void When_data_set_extended_properties_do_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed(ChangeType changeType) + public void + When_data_set_extended_properties_do_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed( + ChangeType changeType) { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -451,7 +471,8 @@ public void When_data_set_extended_properties_do_not_match_but_the_corresponding [Theory] [MemberData(nameof(AllChangeTypes))] [SuppressMessage("Style", "IDE0010:Add missing cases", Justification = "All enum values are accounted for.")] - public void When_data_set_relations_do_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail(ChangeType changeType) + public void When_data_set_relations_do_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail( + ChangeType changeType) { // Arrange TypedDataSetSubclass typedDataSet1; @@ -496,7 +517,8 @@ public void When_data_set_relations_do_not_match_and_the_corresponding_property_ [Theory] [MemberData(nameof(AllChangeTypes))] [SuppressMessage("Style", "IDE0010:Add missing cases", Justification = "All enum values are accounted for.")] - public void When_data_set_relations_do_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed(ChangeType changeType) + public void When_data_set_relations_do_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed( + ChangeType changeType) { // Arrange TypedDataSetSubclass typedDataSet1; @@ -534,10 +556,10 @@ public void When_data_set_relations_do_not_match_but_the_corresponding_property_ // Act & Assert dataSet1.Should().BeEquivalentTo(dataSet2, options => options .Excluding(dataSet => dataSet.Relations) - .ExcludingRelated((DataTable dataTable) => dataTable.Constraints) - .ExcludingRelated((DataTable dataTable) => dataTable.ParentRelations) - .ExcludingRelated((DataTable dataTable) => dataTable.ChildRelations) - .ExcludingRelated((DataColumn dataColumn) => dataColumn.Unique)); + .ExcludingRelated(dataTable => dataTable.Constraints) + .ExcludingRelated(dataTable => dataTable.ParentRelations) + .ExcludingRelated(dataTable => dataTable.ChildRelations) + .ExcludingRelated(dataColumn => dataColumn.Unique)); } [Fact] @@ -592,7 +614,9 @@ public void When_data_set_table_count_matches_but_tables_are_different_equivalen Action action = () => dataSet1.Should().BeEquivalentTo(dataSet2); // Assert - action.Should().Throw().WithMessage("Expected dataSet1.Relations[0].ExtendedProperties* to reference column *ForeignRowID* in table *Different*, but found a reference to *ForeignRowID* in table *TypedDataTable2* instead*"); + action.Should().Throw() + .WithMessage( + "Expected dataSet1.Relations[0].ExtendedProperties* to reference column *ForeignRowID* in table *Different*, but found a reference to *ForeignRowID* in table *TypedDataTable2* instead*"); } [Fact] @@ -612,7 +636,9 @@ public void When_data_set_tables_contain_different_data_equivalence_test_should_ Action action = () => dataSet1.Should().BeEquivalentTo(dataSet2); // Assert - action.Should().Throw().WithMessage("Expected dataSet1[TypedDataTable2].Rows[0] to have RowState value of *Modified*, but found *Unchanged* instead*"); + action.Should().Throw() + .WithMessage( + "Expected dataSet1[TypedDataTable2].Rows[0] to have RowState value of *Modified*, but found *Unchanged* instead*"); } [Fact] @@ -773,7 +799,8 @@ public void When_data_set_has_some_of_the_expected_tables_but_not_all_then_asser () => dataSet.Should().HaveTables(tableNames); // Assert - action.Should().Throw().WithMessage("Expected dataSet to contain a table named *Unicorn*, but it does not."); + action.Should().Throw() + .WithMessage("Expected dataSet to contain a table named *Unicorn*, but it does not."); } [Fact] @@ -789,6 +816,7 @@ public void When_data_set_has_none_of_the_expected_tables_then_asserting_that_it () => dataSet.Should().HaveTables(nonExistentTableNames); // Assert - action.Should().Throw().WithMessage("Expected dataSet to contain a table named *Unicorn*, but it does not."); + action.Should().Throw() + .WithMessage("Expected dataSet to contain a table named *Unicorn*, but it does not."); } } diff --git a/Tests/FluentAssertions.Equivalency.Specs/DataSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/DataSpecs.cs index 4f35c029bd..f9b08f075b 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/DataSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/DataSpecs.cs @@ -17,6 +17,7 @@ public class DataSpecs public int Dummy { get; set; } #region Subject Types + /* NB: TypedDataTable1 and TypedDataTable2 intentionally have the same schema. This allows testing of @@ -71,8 +72,10 @@ public int? ForeignRowID } } - [SuppressMessage("Microsoft.StyleCop.CSharp.Naming", "SA1306", Justification = "DataColumn accessors are named after the columns.")] - [SuppressMessage("Microsoft.StyleCop.CSharp.Naming", "SA1516", Justification = "DataColumn accessors are grouped in a block of lines.")] + [SuppressMessage("Microsoft.StyleCop.CSharp.Naming", "SA1306", + Justification = "DataColumn accessors are named after the columns.")] + [SuppressMessage("Microsoft.StyleCop.CSharp.Naming", "SA1516", + Justification = "DataColumn accessors are grouped in a block of lines.")] public class TypedDataTable1 : TypedTableBase { public TypedDataTable1() @@ -161,8 +164,10 @@ public int? ForeignRowID } } - [SuppressMessage("Microsoft.StyleCop.CSharp.Naming", "SA1306", Justification = "DataColumn accessors are named after the columns.")] - [SuppressMessage("Microsoft.StyleCop.CSharp.Naming", "SA1516", Justification = "DataColumn accessors are grouped in a block of lines.")] + [SuppressMessage("Microsoft.StyleCop.CSharp.Naming", "SA1306", + Justification = "DataColumn accessors are named after the columns.")] + [SuppressMessage("Microsoft.StyleCop.CSharp.Naming", "SA1516", + Justification = "DataColumn accessors are grouped in a block of lines.")] public class TypedDataTable2 : TypedTableBase { public TypedDataTable2() @@ -204,7 +209,8 @@ public TypedDataRow2 this[int index] public DataColumn ForeignRowIDColumn => Columns["ForeignRowID"]; } - [SuppressMessage("Microsoft.StyleCop.CSharp.Naming", "SA1516", Justification = "DataTable accessors are grouped in a block of lines.")] + [SuppressMessage("Microsoft.StyleCop.CSharp.Naming", "SA1516", + Justification = "DataTable accessors are grouped in a block of lines.")] public class TypedDataSet : DataSet { public override SchemaSerializationMode SchemaSerializationMode { get; set; } @@ -299,8 +305,8 @@ public DataSet ToUntypedDataSet() foreach (var constraint in typedTable.Constraints.Cast()) { if (!Relations.Cast().Any(rel => - (rel.ChildKeyConstraint == constraint) || - (rel.ParentKeyConstraint == constraint))) + rel.ChildKeyConstraint == constraint || + rel.ParentKeyConstraint == constraint)) { if (constraint is UniqueConstraint uniqueConstraint) { @@ -331,8 +337,10 @@ public DataSet ToUntypedDataSet() // NB: In the context of the unit test, this is assuming that there is only one column in a relation. var dataRelation = new DataRelation( relation.RelationName, - parentColumn: dataSet.Tables[relation.ParentTable.TableName].Columns[relation.ParentColumns.Single().ColumnName], - childColumn: dataSet.Tables[relation.ChildTable.TableName].Columns[relation.ChildColumns.Single().ColumnName]); + parentColumn: dataSet.Tables[relation.ParentTable.TableName] + .Columns[relation.ParentColumns.Single().ColumnName], + childColumn: dataSet.Tables[relation.ChildTable.TableName] + .Columns[relation.ChildColumns.Single().ColumnName]); foreach (var property in relation.ExtendedProperties.Cast()) { @@ -365,12 +373,12 @@ public TypedDataSetSubclass(TypedDataSet copyFrom, bool swapTableOrder = false, SchemaSerializationMode = copyFrom.SchemaSerializationMode; CopyTable( - @from: copyFrom.TypedDataTable1, + from: copyFrom.TypedDataTable1, to: TypedDataTable1, randomizeRowOrder); CopyTable( - @from: copyFrom.TypedDataTable2, + from: copyFrom.TypedDataTable2, to: TypedDataTable2, randomizeRowOrder); @@ -384,8 +392,10 @@ public TypedDataSetSubclass(TypedDataSet copyFrom, bool swapTableOrder = false, // NB: In the context of the unit test, this is assuming that there is only one column in a relation. var relation = new DataRelation( copyFromRelation.RelationName, - parentColumn: Tables[copyFromRelation.ParentTable.TableName].Columns[copyFromRelation.ParentColumns.Single().ColumnName], - childColumn: Tables[copyFromRelation.ChildTable.TableName].Columns[copyFromRelation.ChildColumns.Single().ColumnName]); + parentColumn: Tables[copyFromRelation.ParentTable.TableName] + .Columns[copyFromRelation.ParentColumns.Single().ColumnName], + childColumn: Tables[copyFromRelation.ChildTable.TableName] + .Columns[copyFromRelation.ChildColumns.Single().ColumnName]); foreach (var property in copyFromRelation.ExtendedProperties.Cast()) { @@ -429,11 +439,13 @@ private void CopyTable(TDataTable from, TDataTable to, boo } } } + #endregion - private static readonly Random Random = new Random(); + private static readonly Random Random = new(); - internal static TDataSet CreateDummyDataSet(bool identicalTables = false, bool includeDummyData = true, bool includeRelation = true) + internal static TDataSet CreateDummyDataSet(bool identicalTables = false, bool includeDummyData = true, + bool includeRelation = true) where TDataSet : TypedDataSet, new() { var ret = new TDataSet(); @@ -497,7 +509,8 @@ internal static TDataSet CreateDummyDataSet(bool identicalTables = fal protected static void AddRelation(TypedDataSet dataSet) { - var relation = new DataRelation("TestRelation", dataSet.TypedDataTable1.RowIDColumn, dataSet.TypedDataTable2.ForeignRowIDColumn); + var relation = new DataRelation("TestRelation", dataSet.TypedDataTable1.RowIDColumn, + dataSet.TypedDataTable2.ForeignRowIDColumn); AddExtendedProperties(relation.ExtendedProperties); @@ -540,7 +553,8 @@ private static void InsertDummyRow(DataTable table, DataRow foreignRow = null) table.Rows.Add(row); } - [SuppressMessage("Style", "IDE0010:Add missing cases", Justification = "TypedDataTable test types have a limited set of columns.")] + [SuppressMessage("Style", "IDE0010:Add missing cases", + Justification = "TypedDataTable test types have a limited set of columns.")] private static object GetDummyValueOfType(Type dataType) { switch (Type.GetTypeCode(dataType)) @@ -548,7 +562,8 @@ private static object GetDummyValueOfType(Type dataType) case TypeCode.Int32: return Random.Next(); case TypeCode.DateTime: - return DateTime.MinValue.AddTicks((Random.Next() & 0x7FFFFFFF) * 1469337835L).AddTicks((Random.Next() & 0x7FFFFFFF) * 1469337835L / 2147483648); + return DateTime.MinValue.AddTicks((Random.Next() & 0x7FFFFFFF) * 1469337835L) + .AddTicks(((Random.Next() & 0x7FFFFFFF) * 1469337835L) / 2147483648); case TypeCode.Decimal: return new decimal(Random.NextDouble()); case TypeCode.String: @@ -571,11 +586,11 @@ public enum ChangeType Removed, } - public static IEnumerable AllChangeTypes - => Enum.GetValues(typeof(ChangeType)).Cast().Select(t => new object[] { t }); + public static IEnumerable AllChangeTypes => + Enum.GetValues(typeof(ChangeType)).Cast().Select(t => new object[] { t }); - public static IEnumerable AllChangeTypesWithAcceptChangesValues - => Enum.GetValues(typeof(ChangeType)).Cast().Join( + public static IEnumerable AllChangeTypesWithAcceptChangesValues => + Enum.GetValues(typeof(ChangeType)).Cast().Join( new[] { true, false }, changeType => true, acceptChanges => true, @@ -625,6 +640,7 @@ protected static void ApplyChange(ConstraintCollection constraints, DataColumn c new UniqueConstraint( "Test", columnForNewConstraint)); + break; case ChangeType.Changed: constraints[1].ConstraintName += "different"; diff --git a/Tests/FluentAssertions.Equivalency.Specs/DataTableSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/DataTableSpecs.cs index b6888648d7..d64fe33739 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/DataTableSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/DataTableSpecs.cs @@ -63,7 +63,8 @@ public void When_data_table_is_expected_to_be_null_and_isnt_equivalence_test_sho } [Fact] - public void When_data_table_type_does_not_match_and_assertion_is_not_configured_to_allow_mismatched_types_equivalence_test_should_fail() + public void + When_data_table_type_does_not_match_and_assertion_is_not_configured_to_allow_mismatched_types_equivalence_test_should_fail() { // Arrange var typedDataSet = CreateDummyDataSet(identicalTables: true); @@ -76,11 +77,13 @@ public void When_data_table_type_does_not_match_and_assertion_is_not_configured_ Action action = () => dataTable.Should().BeEquivalentTo(dataTableOfMismatchedType); // Assert - action.Should().Throw().WithMessage("Expected dataTable to be of type *TypedDataTable1*, but found *System.Data.DataTable*"); + action.Should().Throw() + .WithMessage("Expected dataTable to be of type *TypedDataTable1*, but found *System.Data.DataTable*"); } [Fact] - public void When_data_table_type_does_not_match_but_assertion_is_configured_to_allow_mismatched_types_equivalence_test_should_succeed() + public void + When_data_table_type_does_not_match_but_assertion_is_configured_to_allow_mismatched_types_equivalence_test_should_succeed() { // Arrange var typedDataSet = CreateDummyDataSet(identicalTables: true); @@ -109,7 +112,8 @@ public void When_data_table_name_does_not_match_and_the_corresponding_property_i Action action = () => dataTable1.Should().BeEquivalentTo(dataTable2); // Assert - action.Should().Throw().WithMessage("Expected dataTable1 to have TableName *different*, but found *TypedDataTable1* instead*"); + action.Should().Throw() + .WithMessage("Expected dataTable1 to have TableName *different*, but found *TypedDataTable1* instead*"); } [Fact] @@ -128,13 +132,14 @@ public void When_data_table_name_does_not_match_but_the_corresponding_property_i dataTable1.Should().BeEquivalentTo( dataTable2, options => options - .Excluding(dataTable => dataTable.TableName) - .ExcludingRelated((DataColumn dataColumn) => dataColumn.Table) - .ExcludingRelated((Constraint constraint) => constraint.Table)); + .Excluding(dataTable => dataTable.TableName) + .ExcludingRelated((DataColumn dataColumn) => dataColumn.Table) + .ExcludingRelated((Constraint constraint) => constraint.Table)); } [Fact] - public void When_data_table_case_sensitivity_does_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() + public void + When_data_table_case_sensitivity_does_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -150,11 +155,13 @@ public void When_data_table_case_sensitivity_does_not_match_and_the_correspondin Action action = () => dataTable1.Should().BeEquivalentTo(dataTable2); // Assert - action.Should().Throw().WithMessage("Expected dataTable1 to have CaseSensitive value of True, but found False instead*"); + action.Should().Throw() + .WithMessage("Expected dataTable1 to have CaseSensitive value of True, but found False instead*"); } [Fact] - public void When_data_table_case_sensitivity_does_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() + public void + When_data_table_case_sensitivity_does_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -171,7 +178,8 @@ public void When_data_table_case_sensitivity_does_not_match_but_the_correspondin } [Fact] - public void When_data_table_display_expression_does_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() + public void + When_data_table_display_expression_does_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -191,7 +199,8 @@ public void When_data_table_display_expression_does_not_match_and_the_correspond } [Fact] - public void When_data_table_display_expression_does_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() + public void + When_data_table_display_expression_does_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -208,7 +217,8 @@ public void When_data_table_display_expression_does_not_match_but_the_correspond } [Fact] - public void When_one_data_table_has_errors_and_the_other_does_not_and_the_property_that_indicates_the_presence_of_errors_is_not_excluded_equivalence_test_should_fail() + public void + When_one_data_table_has_errors_and_the_other_does_not_and_the_property_that_indicates_the_presence_of_errors_is_not_excluded_equivalence_test_should_fail() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -228,7 +238,8 @@ public void When_one_data_table_has_errors_and_the_other_does_not_and_the_proper } [Fact] - public void When_one_data_table_has_errors_and_the_other_does_not_but_the_property_that_indicates_the_presence_of_errors_is_excluded_equivalence_test_should_succeed() + public void + When_one_data_table_has_errors_and_the_other_does_not_but_the_property_that_indicates_the_presence_of_errors_is_excluded_equivalence_test_should_succeed() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -247,7 +258,8 @@ public void When_one_data_table_has_errors_and_the_other_does_not_but_the_proper } [Fact] - public void When_data_table_locale_does_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() + public void + When_data_table_locale_does_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -264,7 +276,8 @@ public void When_data_table_locale_does_not_match_and_the_corresponding_property Action action = () => dataTable1.Should().BeEquivalentTo(dataTable2); // Assert - action.Should().Throw().WithMessage("Expected dataTable1 to have Locale value of *fr-CA*, but found *en-US* instead*"); + action.Should().Throw() + .WithMessage("Expected dataTable1 to have Locale value of *fr-CA*, but found *en-US* instead*"); } [Fact] @@ -286,7 +299,8 @@ public void When_data_table_locale_does_not_match_but_the_corresponding_property } [Fact] - public void When_data_table_namespace_does_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() + public void + When_data_table_namespace_does_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -302,11 +316,13 @@ public void When_data_table_namespace_does_not_match_and_the_corresponding_prope Action action = () => dataTable1.Should().BeEquivalentTo(dataTable2); // Assert - action.Should().Throw().WithMessage("Expected dataTable1 to have Namespace value of *different*, but found *"); + action.Should().Throw() + .WithMessage("Expected dataTable1 to have Namespace value of *different*, but found *"); } [Fact] - public void When_data_table_namespace_does_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() + public void + When_data_table_namespace_does_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -325,7 +341,8 @@ public void When_data_table_namespace_does_not_match_but_the_corresponding_prope } [Fact] - public void When_data_table_prefix_does_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() + public void + When_data_table_prefix_does_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -341,7 +358,8 @@ public void When_data_table_prefix_does_not_match_and_the_corresponding_property Action action = () => dataTable1.Should().BeEquivalentTo(dataTable2); // Assert - action.Should().Throw().WithMessage("Expected dataTable1 to have Prefix value of *different*, but found * instead*"); + action.Should().Throw() + .WithMessage("Expected dataTable1 to have Prefix value of *different*, but found * instead*"); } [Fact] @@ -362,7 +380,8 @@ public void When_data_table_prefix_does_not_match_but_the_corresponding_property } [Fact] - public void When_data_table_remoting_format_does_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() + public void + When_data_table_remoting_format_does_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -370,9 +389,9 @@ public void When_data_table_remoting_format_does_not_match_and_the_corresponding var typedDataSet2 = new TypedDataSetSubclass(typedDataSet1); typedDataSet2.RemotingFormat = - (typedDataSet2.RemotingFormat == SerializationFormat.Binary) - ? SerializationFormat.Xml - : SerializationFormat.Binary; + typedDataSet2.RemotingFormat == SerializationFormat.Binary + ? SerializationFormat.Xml + : SerializationFormat.Binary; var dataTable1 = typedDataSet1.ToUntypedDataSet().Tables["TypedDataTable1"]; var dataTable2 = typedDataSet2.ToUntypedDataSet().Tables["TypedDataTable1"]; @@ -381,11 +400,13 @@ public void When_data_table_remoting_format_does_not_match_and_the_corresponding Action action = () => dataTable1.Should().BeEquivalentTo(dataTable2); // Assert - action.Should().Throw().WithMessage("Expected dataTable1 to have RemotingFormat value of *Binary*, but found *Xml* instead*"); + action.Should().Throw() + .WithMessage("Expected dataTable1 to have RemotingFormat value of *Binary*, but found *Xml* instead*"); } [Fact] - public void When_data_table_remoting_format_does_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() + public void + When_data_table_remoting_format_does_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -393,9 +414,9 @@ public void When_data_table_remoting_format_does_not_match_but_the_corresponding var typedDataSet2 = new TypedDataSetSubclass(typedDataSet1); typedDataSet2.RemotingFormat = - (typedDataSet2.RemotingFormat == SerializationFormat.Binary) - ? SerializationFormat.Xml - : SerializationFormat.Binary; + typedDataSet2.RemotingFormat == SerializationFormat.Binary + ? SerializationFormat.Xml + : SerializationFormat.Binary; var dataTable1 = typedDataSet1.ToUntypedDataSet().Tables["TypedDataTable1"]; var dataTable2 = typedDataSet2.ToUntypedDataSet().Tables["TypedDataTable1"]; @@ -408,7 +429,8 @@ public void When_data_table_remoting_format_does_not_match_but_the_corresponding [Theory] [MemberData(nameof(AllChangeTypes))] - public void When_data_table_columns_do_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail(ChangeType changeType) + public void When_data_table_columns_do_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail( + ChangeType changeType) { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -429,7 +451,8 @@ public void When_data_table_columns_do_not_match_and_the_corresponding_property_ [Theory] [MemberData(nameof(AllChangeTypes))] - public void When_data_table_columns_do_not_match_but_columns_and_rows_are_excluded_equivalence_test_should_succeed(ChangeType changeType) + public void When_data_table_columns_do_not_match_but_columns_and_rows_are_excluded_equivalence_test_should_succeed( + ChangeType changeType) { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -449,7 +472,9 @@ public void When_data_table_columns_do_not_match_but_columns_and_rows_are_exclud [Theory] [MemberData(nameof(AllChangeTypes))] - public void When_data_table_extended_properties_do_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail(ChangeType changeType) + public void + When_data_table_extended_properties_do_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail( + ChangeType changeType) { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -470,7 +495,9 @@ public void When_data_table_extended_properties_do_not_match_and_the_correspondi [Theory] [MemberData(nameof(AllChangeTypes))] - public void When_data_table_extended_properties_do_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed(ChangeType changeType) + public void + When_data_table_extended_properties_do_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed( + ChangeType changeType) { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -487,7 +514,8 @@ public void When_data_table_extended_properties_do_not_match_but_the_correspondi } [Fact] - public void When_data_table_primary_key_does_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() + public void + When_data_table_primary_key_does_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -509,11 +537,14 @@ public void When_data_table_primary_key_does_not_match_and_the_corresponding_pro .Excluding(dataTable => dataTable.Constraints)); // Assert - action.Should().Throw().WithMessage("Expected property dataTable1.PrimaryKey to be a collection with * item(s), but *contains * item(s) less than*"); + action.Should().Throw() + .WithMessage( + "Expected property dataTable1.PrimaryKey to be a collection with * item(s), but *contains * item(s) less than*"); } [Fact] - public void When_data_table_primary_key_does_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() + public void + When_data_table_primary_key_does_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -546,7 +577,8 @@ public enum NumberOfColumnsInConstraintDifference [Theory] [InlineData(NumberOfColumnsInConstraintDifference.SingleColumn)] [InlineData(NumberOfColumnsInConstraintDifference.MultipleColumns)] - public void When_columns_for_constraint_in_data_table_do_not_match_message_should_list_all_columns_involved(NumberOfColumnsInConstraintDifference difference) + public void When_columns_for_constraint_in_data_table_do_not_match_message_should_list_all_columns_involved( + NumberOfColumnsInConstraintDifference difference) { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -580,6 +612,7 @@ public void When_columns_for_constraint_in_data_table_do_not_match_message_shoul var missingColumnNames = dataTable2ColumnsForConstraint.Select(col => col.ColumnName) .Except(dataTable1ColumnsForConstraint.Select(col => col.ColumnName)); + var extraColumnNames = dataTable1ColumnsForConstraint.Select(col => col.ColumnName) .Except(dataTable2ColumnsForConstraint.Select(col => col.ColumnName)); @@ -598,7 +631,9 @@ public void When_columns_for_constraint_in_data_table_do_not_match_message_shoul [Theory] [MemberData(nameof(AllChangeTypes))] - public void When_data_table_constraints_do_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail(ChangeType changeType) + public void + When_data_table_constraints_do_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail( + ChangeType changeType) { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -612,8 +647,8 @@ public void When_data_table_constraints_do_not_match_and_the_corresponding_prope string expectedExceptionPattern = changeType == ChangeType.Changed - ? "Found unexpected constraint named *Constraint2* in property dataTable1.Constraints*" - : "Expected property dataTable1.Columns[*].Unique to be *, but found *"; + ? "Found unexpected constraint named *Constraint2* in property dataTable1.Constraints*" + : "Expected property dataTable1.Columns[*].Unique to be *, but found *"; // Act Action action = () => dataTable1.Should().BeEquivalentTo(dataTable2); @@ -624,7 +659,9 @@ public void When_data_table_constraints_do_not_match_and_the_corresponding_prope [Theory] [MemberData(nameof(AllChangeTypes))] - public void When_data_table_constraints_do_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed(ChangeType changeType) + public void + When_data_table_constraints_do_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed( + ChangeType changeType) { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -639,12 +676,13 @@ public void When_data_table_constraints_do_not_match_but_the_corresponding_prope // Act & Assert dataTable1.Should().BeEquivalentTo(dataTable2, options => options .Excluding(dataTable => dataTable.Constraints) - .ExcludingRelated((DataColumn dataColumn) => dataColumn.Unique)); + .ExcludingRelated(dataColumn => dataColumn.Unique)); } [Theory] [MemberData(nameof(AllChangeTypesWithAcceptChangesValues))] - public void When_data_table_rows_do_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail(ChangeType changeType, bool acceptChanges) + public void When_data_table_rows_do_not_match_and_the_corresponding_property_is_not_excluded_equivalence_test_should_fail( + ChangeType changeType, bool acceptChanges) { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -667,8 +705,8 @@ public void When_data_table_rows_do_not_match_and_the_corresponding_property_is_ { exceptionPattern = acceptChanges - ? "Expected dataTable1.Rows[1][String] to be *different* with a length of *, but * has a length of *, differs near *" - : "Expected dataTable1.Rows[1] to have RowState value of *Modified*, but found *Unchanged* instead*"; + ? "Expected dataTable1.Rows[1][String] to be *different* with a length of *, but * has a length of *, differs near *" + : "Expected dataTable1.Rows[1] to have RowState value of *Modified*, but found *Unchanged* instead*"; } else { @@ -685,7 +723,8 @@ public void When_data_table_rows_do_not_match_and_the_corresponding_property_is_ [Theory] [MemberData(nameof(AllChangeTypesWithAcceptChangesValues))] - public void When_data_table_rows_do_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed(ChangeType changeType, bool acceptChanges) + public void When_data_table_rows_do_not_match_but_the_corresponding_property_is_excluded_equivalence_test_should_succeed( + ChangeType changeType, bool acceptChanges) { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -707,7 +746,8 @@ public void When_data_table_rows_do_not_match_but_the_corresponding_property_is_ } [Fact] - public void When_data_table_data_matches_in_different_order_and_the_row_match_mode_is_by_primary_key_equivalence_test_should_succeed() + public void + When_data_table_data_matches_in_different_order_and_the_row_match_mode_is_by_primary_key_equivalence_test_should_succeed() { // Arrange var typedDataSet1 = CreateDummyDataSet(); @@ -851,7 +891,8 @@ public void When_data_table_does_not_have_expected_column_it_should_fail() () => dataTable.Should().HaveColumn("Unicorn"); // Assert - action.Should().Throw().WithMessage("Expected dataTable to contain a column named *Unicorn*, but it does not."); + action.Should().Throw() + .WithMessage("Expected dataTable to contain a column named *Unicorn*, but it does not."); } [Fact] @@ -902,7 +943,8 @@ public void When_data_table_has_only_some_expected_columns_then_asserting_that_i () => dataTable.Should().HaveColumns(columnNames); // Assert - action.Should().Throw().WithMessage("Expected dataTable to contain a column named *Unicorn*, but it does not."); + action.Should().Throw() + .WithMessage("Expected dataTable to contain a column named *Unicorn*, but it does not."); } [Fact] @@ -920,6 +962,7 @@ public void When_data_table_has_none_of_the_expected_columns_then_asserting_that () => dataTable.Should().HaveColumns(nonExistingColumnNames); // Assert - action.Should().Throw().WithMessage("Expected dataTable to contain a column named *Unicorn*, but it does not."); + action.Should().Throw() + .WithMessage("Expected dataTable to contain a column named *Unicorn*, but it does not."); } } diff --git a/Tests/FluentAssertions.Equivalency.Specs/DictionarySpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/DictionarySpecs.cs index f7a364f95d..f84c4b9e09 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/DictionarySpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/DictionarySpecs.cs @@ -75,7 +75,7 @@ public object this[object key] private class GenericDictionaryNotImplementingIDictionary : IDictionary { - private readonly Dictionary dictionary = new Dictionary(); + private readonly Dictionary dictionary = new(); IEnumerator IEnumerable.GetEnumerator() { @@ -234,7 +234,7 @@ private int Parse(string key) public class UserRolesLookupElement { - private readonly Dictionary> innerRoles = new Dictionary>(); + private readonly Dictionary> innerRoles = new(); public virtual Dictionary> Roles { @@ -305,7 +305,7 @@ public void When_a_dictionary_does_not_implement_the_dictionary_interface_it_sho }; ICollection> collection = - new List> { new KeyValuePair("hi", 1) }; + new List> { new("hi", 1) }; // Act Action act = () => dictionary.Should().BeEquivalentTo(collection); @@ -320,14 +320,14 @@ public void When_a_read_only_dictionary_matches_the_expectation_it_should_succee // Arrange IReadOnlyDictionary> dictionary = new ReadOnlyDictionary>( - new Dictionary>() - { - ["Key2"] = new[] { "Value2" }, - ["Key1"] = new[] { "Value1" } - }); + new Dictionary> + { + ["Key2"] = new[] { "Value2" }, + ["Key1"] = new[] { "Value1" } + }); // Act - Action act = () => dictionary.Should().BeEquivalentTo(new Dictionary>() + Action act = () => dictionary.Should().BeEquivalentTo(new Dictionary> { ["Key1"] = new[] { "Value1" }, ["Key2"] = new[] { "Value2" } @@ -343,14 +343,14 @@ public void When_a_read_only_dictionary_does_not_match_the_expectation_it_should // Arrange IReadOnlyDictionary> dictionary = new ReadOnlyDictionary>( - new Dictionary>() - { - ["Key2"] = new[] { "Value2" }, - ["Key1"] = new[] { "Value1" } - }); + new Dictionary> + { + ["Key2"] = new[] { "Value2" }, + ["Key1"] = new[] { "Value1" } + }); // Act - Action act = () => dictionary.Should().BeEquivalentTo(new Dictionary>() + Action act = () => dictionary.Should().BeEquivalentTo(new Dictionary> { ["Key2"] = new[] { "Value3" }, ["Key1"] = new[] { "Value1" } @@ -365,7 +365,7 @@ public void When_a_dictionary_is_compared_to_null_it_should_not_throw_a_NullRefe { // Arrange Dictionary subject = null; - Dictionary expectation = new Dictionary(); + Dictionary expectation = new(); // Act Action act = () => subject.Should().BeEquivalentTo(expectation, "because we do expect a valid dictionary"); @@ -393,8 +393,9 @@ public void When_a_null_dictionary_is_compared_to_null_it_should_not_throw() public void When_a_dictionary_is_compared_to_a_dictionary_it_should_allow_chaining() { // Arrange - Dictionary subject = new Dictionary { [42] = 1337 }; - Dictionary expectation = new Dictionary { [42] = 1337 }; + Dictionary subject = new() { [42] = 1337 }; + + Dictionary expectation = new() { [42] = 1337 }; // Act Action act = () => subject.Should().BeEquivalentTo(expectation) @@ -408,8 +409,9 @@ public void When_a_dictionary_is_compared_to_a_dictionary_it_should_allow_chaini public void When_a_dictionary_is_compared_to_a_dictionary_with_a_config_it_should_allow_chaining() { // Arrange - Dictionary subject = new Dictionary { [42] = 1337 }; - Dictionary expectation = new Dictionary { [42] = 1337 }; + Dictionary subject = new() { [42] = 1337 }; + + Dictionary expectation = new() { [42] = 1337 }; // Act Action act = () => subject.Should().BeEquivalentTo(expectation, opt => opt) @@ -455,7 +457,7 @@ public void When_a_collection_of_key_value_pairs_is_equivalent_to_the_dictionary var collection = new List> { new("hi", 1) }; // Act / Assert - Action act = () => collection.Should().BeEquivalentTo(new Dictionary() + Action act = () => collection.Should().BeEquivalentTo(new Dictionary { { "hi", 2 } }); @@ -575,7 +577,7 @@ public void public void When_asserting_equivalence_of_dictionaries_it_should_respect_the_declared_type() { // Arrange - var actual = new Dictionary { [0] = new CustomerType("123") }; + var actual = new Dictionary { [0] = new("123") }; var expectation = new Dictionary { [0] = new DerivedCustomerType("123") }; // Act @@ -605,7 +607,7 @@ public void When_asserting_equivalence_of_generic_dictionaries_and_configured_to_use_runtime_properties_it_should_respect_the_runtime_type() { // Arrange - var actual = new Dictionary { [0] = new CustomerType("123") }; + var actual = new Dictionary { [0] = new("123") }; var expectation = new Dictionary { [0] = new DerivedCustomerType("123") }; // Act @@ -662,7 +664,8 @@ public void When_the_subjects_key_type_is_not_compatible_with_the_expected_key_t // Assert act.Should().Throw() - .WithMessage("Expected actual to be a dictionary or collection of key-value pairs that is keyed to type System.String*"); + .WithMessage( + "Expected actual to be a dictionary or collection of key-value pairs that is keyed to type System.String*"); } [Fact] @@ -709,7 +712,7 @@ public void When_asserting_the_equivalence_of_generic_dictionaries_it_should_res [0] = new DerivedCustomerType("123") }; - var expectation = new Dictionary { [0] = new CustomerType("123") }; + var expectation = new Dictionary { [0] = new("123") }; // Act Action act = () => actual.Should().BeEquivalentTo(expectation); @@ -812,7 +815,8 @@ public void When_the_other_property_is_not_a_dictionary_it_should_throw() // Assert act.Should().Throw() - .WithMessage("Expected property subject.Customers to be a dictionary or collection of key-value pairs that is keyed to type System.String*"); + .WithMessage( + "Expected property subject.Customers to be a dictionary or collection of key-value pairs that is keyed to type System.String*"); } [Fact] @@ -849,6 +853,7 @@ public void When_subject_dictionary_asserted_to_be_equivalent_have_less_elements { ["greeting"] = "hello" }; + var dictionary2 = new Dictionary { ["greeting"] = "hello", @@ -864,7 +869,8 @@ public void When_subject_dictionary_asserted_to_be_equivalent_have_less_elements } [Fact] - public void When_subject_dictionary_with_class_keys_asserted_to_be_equivalent_have_less_elements_other_dictionary_derived_class_keys_fails_describing_missing_keys() + public void + When_subject_dictionary_with_class_keys_asserted_to_be_equivalent_have_less_elements_other_dictionary_derived_class_keys_fails_describing_missing_keys() { // Arrange var dictionary1 = new Dictionary @@ -894,6 +900,7 @@ public void When_subject_dictionary_asserted_to_be_equivalent_have_more_elements { ["greeting"] = "hello" }; + var subject = new Dictionary { ["greeting"] = "hello", @@ -905,11 +912,13 @@ public void When_subject_dictionary_asserted_to_be_equivalent_have_more_elements // Assert action.Should().Throw() - .WithMessage("Expected subject*to be a dictionary with 1 item(s) because we expect one pair, but*additional key(s) {\"farewell\"}*"); + .WithMessage( + "Expected subject*to be a dictionary with 1 item(s) because we expect one pair, but*additional key(s) {\"farewell\"}*"); } [Fact] - public void When_subject_dictionary_with_class_keys_asserted_to_be_equivalent_and_other_dictionary_derived_class_keys_fails_because_of_types_incompatibility() + public void + When_subject_dictionary_with_class_keys_asserted_to_be_equivalent_and_other_dictionary_derived_class_keys_fails_because_of_types_incompatibility() { // Arrange var dictionary1 = new Dictionary @@ -928,17 +937,20 @@ [new SomeDerivedKeyClass(2)] = "hello" // Assert action.Should().Throw() - .WithMessage("Expected dictionary2 to be a dictionary or collection of key-value pairs that is keyed to type FluentAssertions.Equivalency.Specs.DictionarySpecs+SomeBaseKeyClass.*"); + .WithMessage( + "Expected dictionary2 to be a dictionary or collection of key-value pairs that is keyed to type FluentAssertions.Equivalency.Specs.DictionarySpecs+SomeBaseKeyClass.*"); } [Fact] - public void When_subject_dictionary_asserted_to_be_equivalent_have_less_elements_but_some_missing_and_some_additional_elements_fails_describing_missing_and_additional_keys() + public void + When_subject_dictionary_asserted_to_be_equivalent_have_less_elements_but_some_missing_and_some_additional_elements_fails_describing_missing_and_additional_keys() { // Arrange var dictionary1 = new Dictionary { ["GREETING"] = "hello" }; + var dictionary2 = new Dictionary { ["greeting"] = "hello", @@ -950,17 +962,20 @@ public void When_subject_dictionary_asserted_to_be_equivalent_have_less_elements // Assert action.Should().Throw() - .WithMessage("Expected*to be a dictionary with 2 item(s), but*misses key(s)*{\"greeting\", \"farewell\"}*additional key(s) {\"GREETING\"}*"); + .WithMessage( + "Expected*to be a dictionary with 2 item(s), but*misses key(s)*{\"greeting\", \"farewell\"}*additional key(s) {\"GREETING\"}*"); } [Fact] - public void When_subject_dictionary_asserted_to_be_equivalent_have_more_elements_but_some_missing_and_some_additional_elements_fails_describing_missing_and_additional_keys() + public void + When_subject_dictionary_asserted_to_be_equivalent_have_more_elements_but_some_missing_and_some_additional_elements_fails_describing_missing_and_additional_keys() { // Arrange var dictionary1 = new Dictionary { ["GREETING"] = "hello" }; + var dictionary2 = new Dictionary { ["greeting"] = "hello", @@ -972,7 +987,8 @@ public void When_subject_dictionary_asserted_to_be_equivalent_have_more_elements // Assert action.Should().Throw() - .WithMessage("Expected*to be a dictionary with 1 item(s), but*misses key(s) {\"GREETING\"}*additional key(s) {\"greeting\", \"farewell\"}*"); + .WithMessage( + "Expected*to be a dictionary with 1 item(s), but*misses key(s) {\"GREETING\"}*additional key(s) {\"greeting\", \"farewell\"}*"); } [Fact] diff --git a/Tests/FluentAssertions.Equivalency.Specs/EnumSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/EnumSpecs.cs index 51c1454cfa..4a80b384ba 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/EnumSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/EnumSpecs.cs @@ -100,7 +100,9 @@ public void When_asserting_members_from_different_enum_types_are_equivalent_by_s { // Arrange var subject = new ClassWithEnumOne { Enum = EnumOne.Two }; - var expectation = new ClassWithEnumThree() { Enum = EnumThree.Two }; + + var expectation = new ClassWithEnumThree + { Enum = EnumThree.Two }; // Act Action act = () => subject.Should().BeEquivalentTo(expectation, config => config.ComparingEnumsByName()); diff --git a/Tests/FluentAssertions.Equivalency.Specs/ExtensibilitySpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/ExtensibilitySpecs.cs index 34ce4a3fc5..3eff096405 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/ExtensibilitySpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/ExtensibilitySpecs.cs @@ -143,13 +143,14 @@ internal class ForeignKeyMatchingRule : IMemberMatchingRule public IMember Match(IMember expectedMember, object subject, INode parent, IEquivalencyAssertionOptions options) { string name = expectedMember.Name; + if (name.EndsWith("Id", StringComparison.Ordinal)) { name = name.Replace("Id", ""); } PropertyInfo runtimeProperty = subject.GetType().GetRuntimeProperty(name); - return (runtimeProperty is not null) ? new Property(runtimeProperty, parent) : null; + return runtimeProperty is not null ? new Property(runtimeProperty, parent) : null; } } @@ -321,7 +322,7 @@ public void When_property_of_other_is_null_the_failure_message_should_not_compla act.Should().Throw() .Which.Message.Should() .Contain("Expected property subject.Id to be , but found \"foo\"") - .And.NotContain("from expectation"); + .And.NotContain("from expectation"); } [Fact] @@ -348,7 +349,7 @@ public void When_property_of_subject_is_null_the_failure_message_should_not_comp act.Should().Throw() .Which.Message.Should() .Contain("Expected property subject.Id to be \"bar\", but found ") - .And.NotContain("from subject"); + .And.NotContain("from subject"); } [Fact] @@ -407,7 +408,7 @@ public void When_an_assertion_is_overridden_for_a_predicate_it_should_use_the_pr var expectation = new { - Date = 14.July(2012).At(13, 0, 0) + Date = 14.July(2012).At(13, 0) }; // Act @@ -434,10 +435,10 @@ public void When_an_assertion_is_overridden_for_all_types_it_should_use_the_prov var expectation = new { - Date = 21.July(2012).At(11, 9, 0), + Date = 21.July(2012).At(11, 9), Nested = new { - NestedDate = 14.July(2012).At(13, 0, 0) + NestedDate = 14.July(2012).At(13, 0) } }; @@ -624,7 +625,8 @@ public void When_multiple_steps_are_added_they_should_be_evaluated_first_to_last private class AlwaysFailOnDateTimesEquivalencyStep : IEquivalencyStep { - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { if (comparands.Expectation is DateTime) { @@ -637,7 +639,8 @@ public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationCon private class RelaxingDateTimeEquivalencyStep : IEquivalencyStep { - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { if (comparands.Expectation is DateTime time) { @@ -690,7 +693,8 @@ public void When_using_a_nested_equivalency_api_in_a_custom_assertion_rule_it_sh // Act Action act = () => subject.Should().BeEquivalentTo(expectation, options => options - .Using(ctx => ctx.Subject.Should().BeEquivalentTo(ctx.Expectation, nestedOptions => nestedOptions.Excluding(x => x.Property2))) + .Using(ctx => + ctx.Subject.Should().BeEquivalentTo(ctx.Expectation, nestedOptions => nestedOptions.Excluding(x => x.Property2))) .WhenTypeIs()); // Assert @@ -806,7 +810,8 @@ public void When_multiple_equivalency_steps_are_added_they_should_be_executed_in private class ThrowExceptionEquivalencyStep : IEquivalencyStep where TException : Exception, new() { - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { throw new TException(); } @@ -814,7 +819,8 @@ public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationCon private class AlwaysHandleEquivalencyStep : IEquivalencyStep { - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { return EquivalencyResult.AssertionCompleted; } @@ -822,7 +828,8 @@ public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationCon private class NeverHandleEquivalencyStep : IEquivalencyStep { - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { return EquivalencyResult.ContinueWithNext; } @@ -830,7 +837,8 @@ public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationCon private class EqualityEquivalencyStep : IEquivalencyStep { - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { comparands.Subject.Should().Be(comparands.Expectation, context.Reason.FormattedMessage, context.Reason.Arguments); return EquivalencyResult.AssertionCompleted; @@ -846,7 +854,8 @@ public DoEquivalencyStep(Action doAction) this.doAction = doAction; } - public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) + public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, + IEquivalencyValidator nestedValidator) { doAction(); return EquivalencyResult.AssertionCompleted; diff --git a/Tests/FluentAssertions.Equivalency.Specs/MemberConversionSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/MemberConversionSpecs.cs index 3b5cc5c350..c5896a6a29 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/MemberConversionSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/MemberConversionSpecs.cs @@ -144,7 +144,7 @@ public void When_declaring_equivalent_a_convertable_object_that_is_equivalent_on { // Arrange string str = "This is a test"; - CustomConvertible obj = new CustomConvertible(str); + CustomConvertible obj = new(str); // Act Action act = () => obj.Should().BeEquivalentTo(str, options => options.WithAutoConversion()); diff --git a/Tests/FluentAssertions.Equivalency.Specs/MemberLessObjectsSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/MemberLessObjectsSpecs.cs index 3ed2adc303..688bfa5884 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/MemberLessObjectsSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/MemberLessObjectsSpecs.cs @@ -40,7 +40,7 @@ public void When_asserting_instances_of_Object_are_equivalent_it_should_fail() public void When_asserting_instance_of_object_is_equivalent_to_null_it_should_fail_with_a_descriptive_message() { // Arrange - object actual = new object(); + object actual = new(); object expected = null; // Act @@ -56,7 +56,7 @@ public void When_asserting_null_is_equivalent_to_instance_of_object_it_should_fa { // Arrange object actual = null; - object expected = new object(); + object expected = new(); // Act Action act = () => actual.Should().BeEquivalentTo(expected); diff --git a/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs index f1ad0b2239..228d6ba86f 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs @@ -213,7 +213,7 @@ public void A_nested_class_without_properties_inside_a_collection_is_fine() // Arrange var sut = new List { - new BaseClassPointingToClassWithoutProperties + new() { Name = "theName" } @@ -233,7 +233,7 @@ internal class BaseClassPointingToClassWithoutProperties { public string Name { get; set; } - public ClassWithoutProperty ClassWithoutProperty { get; } = new ClassWithoutProperty(); + public ClassWithoutProperty ClassWithoutProperty { get; } = new(); } internal class ClassWithoutProperty @@ -404,11 +404,11 @@ public void When_including_a_property_using_an_expression_it_should_evaluate_it_ // Arrange var list1 = new List { - new CustomType + new() { Name = "A" }, - new CustomType + new() { Name = "B" } @@ -416,11 +416,11 @@ public void When_including_a_property_using_an_expression_it_should_evaluate_it_ var list2 = new List { - new CustomType + new() { Name = "C" }, - new CustomType + new() { Name = "D" } @@ -793,8 +793,8 @@ public void When_members_are_excluded_by_the_access_modifier_of_the_getter_using // Act Action act = () => subject.Should().BeEquivalentTo(expected, config => config.Excluding(ctx => ctx.WhichGetterHas(CSharpAccessModifier.Internal) || - ctx.WhichGetterHas(CSharpAccessModifier.ProtectedInternal) || - ctx.WhichGetterHas(CSharpAccessModifier.PrivateProtected))); + ctx.WhichGetterHas(CSharpAccessModifier.ProtectedInternal) || + ctx.WhichGetterHas(CSharpAccessModifier.PrivateProtected))); // Assert act.Should().NotThrow(); @@ -813,9 +813,9 @@ public void When_members_are_excluded_by_the_access_modifier_of_the_setter_using // Act Action act = () => subject.Should().BeEquivalentTo(expected, config => config.Excluding(ctx => ctx.WhichSetterHas(CSharpAccessModifier.Internal) || - ctx.WhichSetterHas(CSharpAccessModifier.ProtectedInternal) || - ctx.WhichSetterHas(CSharpAccessModifier.Private) || - ctx.WhichSetterHas(CSharpAccessModifier.PrivateProtected))); + ctx.WhichSetterHas(CSharpAccessModifier.ProtectedInternal) || + ctx.WhichSetterHas(CSharpAccessModifier.Private) || + ctx.WhichSetterHas(CSharpAccessModifier.PrivateProtected))); // Assert act.Should().NotThrow(); @@ -872,11 +872,11 @@ public void When_excluding_properties_via_non_array_indexers_it_should_exclude_t }.ToList(), Dictionary = new Dictionary { - ["Foo"] = new ClassWithOnlyAProperty + ["Foo"] = new() { Value = 1 }, - ["Bar"] = new ClassWithOnlyAProperty + ["Bar"] = new() { Value = 2 } @@ -900,11 +900,11 @@ public void When_excluding_properties_via_non_array_indexers_it_should_exclude_t }.ToList(), Dictionary = new Dictionary { - ["Foo"] = new ClassWithOnlyAProperty + ["Foo"] = new() { Value = 1 }, - ["Bar"] = new ClassWithOnlyAProperty + ["Bar"] = new() { Value = 3 } @@ -943,11 +943,11 @@ public void When_excluding_properties_via_non_array_indexers_it_should_not_exclu }.ToList(), Dictionary = new Dictionary { - ["Foo"] = new ClassWithOnlyAProperty + ["Foo"] = new() { Value = 1 }, - ["Bar"] = new ClassWithOnlyAProperty + ["Bar"] = new() { Value = 2 } @@ -971,11 +971,11 @@ public void When_excluding_properties_via_non_array_indexers_it_should_not_exclu }.ToList(), Dictionary = new Dictionary { - ["Foo"] = new ClassWithOnlyAProperty + ["Foo"] = new() { Value = 6 }, - ["Bar"] = new ClassWithOnlyAProperty + ["Bar"] = new() { Value = 3 } diff --git a/Tests/FluentAssertions.Equivalency.Specs/TestTypes.cs b/Tests/FluentAssertions.Equivalency.Specs/TestTypes.cs index 3f21c5ad67..1d0a87476e 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/TestTypes.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/TestTypes.cs @@ -1,6 +1,11 @@ using System; using System.Collections.Generic; +// ReSharper disable NotAccessedField.Global +// ReSharper disable NotAccessedField.Local +// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global +// ReSharper disable UnusedMember.Global +// ReSharper disable AutoPropertyCanBeMadeGetOnly.Local #pragma warning disable SA1649 namespace FluentAssertions.Equivalency.Specs; @@ -22,7 +27,7 @@ public enum EnumLong : long public class ClassOne { - public ClassTwo RefOne { get; set; } = new ClassTwo(); + public ClassTwo RefOne { get; set; } = new(); public int ValOne { get; set; } = 1; } @@ -182,11 +187,15 @@ internal class ClassWithSomeFieldsAndProperties internal class ClassWithCctor { - static ClassWithCctor() { } + // ReSharper disable once EmptyConstructor + static ClassWithCctor() + { + } } internal class ClassWithCctorAndNonDefaultConstructor { + // ReSharper disable once EmptyConstructor static ClassWithCctorAndNonDefaultConstructor() { } public ClassWithCctorAndNonDefaultConstructor(int _) { } @@ -267,11 +276,11 @@ public CustomerType(string code) Code = code; } - public string Code { get; private set; } + public string Code { get; } public override bool Equals(object obj) { - return (obj is CustomerType other) && Code == other.Code; + return obj is CustomerType other && Code == other.Code; } public override int GetHashCode() @@ -286,7 +295,7 @@ public override int GetHashCode() return true; } - if ((a is null) || (b is null)) + if (a is null || b is null) { return false; } diff --git a/Tests/FluentAssertions.Equivalency.Specs/TupleSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/TupleSpecs.cs index afeda3c6ec..229af8373e 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/TupleSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/TupleSpecs.cs @@ -24,8 +24,8 @@ public void When_a_nested_member_is_a_tuple_it_should_compare_its_property_for_e public void When_a_tuple_is_compared_it_should_compare_its_components() { // Arrange - var actual = new Tuple("Hello", true, new int[] { 3, 2, 1 }); - var expected = new Tuple("Hello", true, new int[] { 1, 2, 3 }); + var actual = new Tuple("Hello", true, new[] { 3, 2, 1 }); + var expected = new Tuple("Hello", true, new[] { 1, 2, 3 }); // Act Action act = () => actual.Should().BeEquivalentTo(expected); diff --git a/Tests/FluentAssertions.Equivalency.Specs/TypedDataSetSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/TypedDataSetSpecs.cs index 53649b85ad..b3ad964315 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/TypedDataSetSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/TypedDataSetSpecs.cs @@ -237,6 +237,7 @@ public void When_HasErrors_does_not_match_and_property_is_excluded_as_list_it_sh // Act & Assert IEnumerable excludedTables = new[] { "TypedDataTable1" }; + dataSet1.Should().BeEquivalentTo(dataSet2, config => config.Excluding(dataSet => dataSet.HasErrors).ExcludingTables(excludedTables)); } @@ -346,7 +347,7 @@ public void When_RemotingFormat_does_not_match_and_property_is_not_excluded_it_s var dataSet2 = new TypedDataSetSubclass(dataSet1); dataSet2.RemotingFormat = - (dataSet2.RemotingFormat == SerializationFormat.Binary) + dataSet2.RemotingFormat == SerializationFormat.Binary ? SerializationFormat.Xml : SerializationFormat.Binary; @@ -366,14 +367,14 @@ public void When_RemotingFormat_does_not_match_and_property_is_excluded_it_shoul var dataSet2 = new TypedDataSetSubclass(dataSet1); dataSet2.RemotingFormat = - (dataSet2.RemotingFormat == SerializationFormat.Binary) + dataSet2.RemotingFormat == SerializationFormat.Binary ? SerializationFormat.Xml : SerializationFormat.Binary; // Act & Assert dataSet1.Should().BeEquivalentTo(dataSet2, options => options .Excluding(dataSet => dataSet.RemotingFormat) - .ExcludingRelated((DataTable dataTable) => dataTable.RemotingFormat)); + .ExcludingRelated(dataTable => dataTable.RemotingFormat)); } [Fact] @@ -385,7 +386,7 @@ public void When_SchemaSerializationMode_does_not_match_and_property_is_not_excl var dataSet2 = new TypedDataSetSubclass(dataSet1); dataSet2.SchemaSerializationMode = - (dataSet2.SchemaSerializationMode == SchemaSerializationMode.ExcludeSchema) + dataSet2.SchemaSerializationMode == SchemaSerializationMode.ExcludeSchema ? SchemaSerializationMode.IncludeSchema : SchemaSerializationMode.ExcludeSchema; @@ -405,7 +406,7 @@ public void When_SchemaSerializationMode_does_not_match_and_property_is_excluded var dataSet2 = new TypedDataSetSubclass(dataSet1); dataSet2.SchemaSerializationMode = - (dataSet2.SchemaSerializationMode == SchemaSerializationMode.ExcludeSchema) + dataSet2.SchemaSerializationMode == SchemaSerializationMode.ExcludeSchema ? SchemaSerializationMode.IncludeSchema : SchemaSerializationMode.ExcludeSchema; @@ -506,8 +507,8 @@ public void When_Relations_does_not_match_and_property_is_excluded_it_should_suc // Act & Assert dataSet1.Should().BeEquivalentTo(dataSet2, options => options .Excluding(dataSet => dataSet.Relations) - .ExcludingRelated((DataTable dataTable) => dataTable.ParentRelations) - .ExcludingRelated((DataTable dataTable) => dataTable.ChildRelations)); + .ExcludingRelated(dataTable => dataTable.ParentRelations) + .ExcludingRelated(dataTable => dataTable.ChildRelations)); } [Fact] diff --git a/Tests/FluentAssertions.Equivalency.Specs/TypedDataTableSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/TypedDataTableSpecs.cs index 2ecc1d3eb7..c084d9f02e 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/TypedDataTableSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/TypedDataTableSpecs.cs @@ -157,9 +157,9 @@ public void When_TableName_does_not_match_and_property_is_excluded_it_should_suc dataTable1.Should().BeEquivalentTo( dataTable2, options => options - .Excluding(dataTable => dataTable.TableName) - .ExcludingRelated((DataColumn dataColumn) => dataColumn.Table) - .ExcludingRelated((Constraint constraint) => constraint.Table)); + .Excluding(dataTable => dataTable.TableName) + .ExcludingRelated((DataColumn dataColumn) => dataColumn.Table) + .ExcludingRelated((Constraint constraint) => constraint.Table)); } [Fact] @@ -397,9 +397,9 @@ public void When_RemotingFormat_does_not_match_and_property_is_not_excluded_it_s var dataSet2 = new TypedDataSetSubclass(dataSet1); dataSet2.RemotingFormat = - (dataSet2.RemotingFormat == SerializationFormat.Binary) - ? SerializationFormat.Xml - : SerializationFormat.Binary; + dataSet2.RemotingFormat == SerializationFormat.Binary + ? SerializationFormat.Xml + : SerializationFormat.Binary; var dataTable1 = dataSet1.TypedDataTable1; var dataTable2 = dataSet2.TypedDataTable1; @@ -420,9 +420,9 @@ public void When_RemotingFormat_does_not_match_and_property_is_excluded_it_shoul var dataSet2 = new TypedDataSetSubclass(dataSet1); dataSet2.RemotingFormat = - (dataSet2.RemotingFormat == SerializationFormat.Binary) - ? SerializationFormat.Xml - : SerializationFormat.Binary; + dataSet2.RemotingFormat == SerializationFormat.Binary + ? SerializationFormat.Xml + : SerializationFormat.Binary; var dataTable1 = dataSet1.TypedDataTable1; var dataTable2 = dataSet2.TypedDataTable1; @@ -597,7 +597,7 @@ public void When_Constraints_do_not_match_and_property_is_excluded_it_should_suc // Act & Assert dataTable1.Should().BeEquivalentTo(dataTable2, options => options .Excluding(dataTable => dataTable.Constraints) - .ExcludingRelated((DataColumn dataColumn) => dataColumn.Unique)); + .ExcludingRelated(dataColumn => dataColumn.Unique)); } [Theory] diff --git a/Tests/FluentAssertions.Equivalency.Specs/XmlSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/XmlSpecs.cs index 8d13350e78..f299b2e9a3 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/XmlSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/XmlSpecs.cs @@ -8,7 +8,8 @@ namespace FluentAssertions.Equivalency.Specs; public class XmlSpecs { [Fact] - public void When_asserting_a_xml_selfclosing_document_is_equivalent_to_a_different_xml_document_with_same_structure_it_should_succeed() + public void + When_asserting_a_xml_selfclosing_document_is_equivalent_to_a_different_xml_document_with_same_structure_it_should_succeed() { // Arrange var subject = new @@ -125,6 +126,6 @@ public void When_asserting_an_xml_attribute_is_equal_to_a_different_xml_attribut // Assert act.Should().Throw().WithMessage( - $"Expected property subject.Attribute to be name2=\"value\" because we want to test the failure message, but found name=\"value\"*"); + "Expected property subject.Attribute to be name2=\"value\" because we want to test the failure message, but found name=\"value\"*"); } } diff --git a/Tests/FluentAssertions.Specs/AssertionExtensions.cs b/Tests/FluentAssertions.Specs/AssertionExtensions.cs index 89473dfda7..1e8936c211 100644 --- a/Tests/FluentAssertions.Specs/AssertionExtensions.cs +++ b/Tests/FluentAssertions.Specs/AssertionExtensions.cs @@ -35,7 +35,6 @@ public static TaskCompletionSourceAssertions Should(this TaskCompletionSou } #if NET6_0_OR_GREATER - public static TaskCompletionSourceAssertions Should(this TaskCompletionSource tcs, IClock clock) { return new TaskCompletionSourceAssertions(tcs, clock); diff --git a/Tests/FluentAssertions.Specs/AssertionExtensionsSpecs.cs b/Tests/FluentAssertions.Specs/AssertionExtensionsSpecs.cs index 03e64c7eb3..0b71d3a8b4 100644 --- a/Tests/FluentAssertions.Specs/AssertionExtensionsSpecs.cs +++ b/Tests/FluentAssertions.Specs/AssertionExtensionsSpecs.cs @@ -33,6 +33,7 @@ private static bool OverridesEquals(Type t) { MethodInfo equals = t.GetMethod("Equals", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public, null, new[] { typeof(object) }, null); + return equals is not null; } @@ -151,8 +152,8 @@ public void Should_methods_have_a_matching_overload_to_guard_against_chaining_an // Assert fakeOverloads.Should().BeEquivalentTo(realOverloads, opt => opt - .Using(ctx => ctx.Subject.Name.Should().Be(ctx.Expectation.Name)) - .WhenTypeIs(), + .Using(ctx => ctx.Subject.Name.Should().Be(ctx.Expectation.Name)) + .WhenTypeIs(), "AssertionExtensions.cs should have a guard overload of Should calling InvalidShouldCall()"); } diff --git a/Tests/FluentAssertions.Specs/AssertionOptionsSpecs.cs b/Tests/FluentAssertions.Specs/AssertionOptionsSpecs.cs index 5e7aaf4429..7e8af5a9c9 100644 --- a/Tests/FluentAssertions.Specs/AssertionOptionsSpecs.cs +++ b/Tests/FluentAssertions.Specs/AssertionOptionsSpecs.cs @@ -16,8 +16,10 @@ public class AssertionOptionsSpecs { // Due to tests that call AssertionOptions [CollectionDefinition("AssertionOptionsSpecs", DisableParallelization = true)] - public class AssertionOptionsSpecsDefinition { } - + public class AssertionOptionsSpecsDefinition + { + } + public abstract class Given_temporary_global_assertion_options : GivenWhenThen { protected override void Dispose(bool disposing) @@ -52,6 +54,7 @@ public When_concurrently_getting_equality_strategy() When(() => { IEquivalencyAssertionOptions equivalencyAssertionOptions = new EquivalencyAssertionOptions(); + return () => Parallel.For(0, 10_000, new ParallelOptions { MaxDegreeOfParallelism = 8 }, _ => equivalencyAssertionOptions.GetEqualityStrategy(typeof(IEnumerable)) ); @@ -116,7 +119,9 @@ public When_modifying_global_value_type_settings_a_previous_assertion_should_not [Fact] public void It_should_try_to_compare_the_classes_by_value_semantics_and_thus_throw() { - Action act = () => new MyClass { Value = 1 }.Should().BeEquivalentTo(new MyClass { Value = 1 }); + MyClass myClass = new() { Value = 1 }; + + Action act = () => myClass.Should().BeEquivalentTo(new MyClass { Value = 1 }); act.Should().Throw(); } @@ -141,7 +146,7 @@ public When_modifying_record_settings_globally() [Fact] public void It_should_use_the_global_settings_for_comparing_records() { - new Position(123).Should().BeEquivalentTo(new Position(123)); + new Position(123).Should().BeEquivalentTo(new Position(123)); } private record Position @@ -156,8 +161,7 @@ public Position(int value) } [Collection("AssertionOptionsSpecs")] - public class When_assertion_doubles_should_always_allow_small_deviations : - Given_temporary_global_assertion_options + public class When_assertion_doubles_should_always_allow_small_deviations : Given_temporary_global_assertion_options { public When_assertion_doubles_should_always_allow_small_deviations() { diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.AllSatisfy.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.AllSatisfy.cs index 28e4dc7554..83ab3250d8 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.AllSatisfy.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.AllSatisfy.cs @@ -56,9 +56,8 @@ public void An_empty_collection_should_throw() var collection = Enumerable.Empty(); // Act - Action act = () - => collection.Should() - .AllSatisfy(x => x.Should().Be(1), "because we want to test the failure {0}", "message"); + Action act = () => + collection.Should().AllSatisfy(x => x.Should().Be(1), "because we want to test the failure {0}", "message"); // Assert act.Should() @@ -93,6 +92,7 @@ public void Any_items_not_satisfying_inspector_should_throw() customer => { customer.Age.Should().BeLessThan(21); + customer.Items.Should() .AllSatisfy(item => item.Should().Be(3)); }, @@ -113,7 +113,7 @@ public void Any_items_not_satisfying_inspector_should_throw() *Expected item to be 3, but found 2 *At index 1: *Expected customer.Age to be less than 21, but found 22 (difference of 1)" - ); + ); } [Fact] diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeEmpty.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeEmpty.cs index 2f5c7411fc..e8fa188b34 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeEmpty.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeEmpty.cs @@ -194,7 +194,7 @@ private class InfiniteEnumerator : IEnumerator public void Reset() { } - public object Current => new object(); + public object Current => new(); object IEnumerator.Current => Current; diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeEquivalentTo.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeEquivalentTo.cs index 2f4cb231a8..b640358a17 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeEquivalentTo.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeEquivalentTo.cs @@ -129,7 +129,8 @@ public void When_asserting_collections_to_be_equivalent_but_subject_collection_i // Act Action act = - () => collection.Should().BeEquivalentTo(collection1, "because we want to test the behaviour with a null subject"); + () => collection.Should() + .BeEquivalentTo(collection1, "because we want to test the behaviour with a null subject"); // Assert act.Should().Throw().WithMessage( @@ -286,8 +287,8 @@ public void When_a_collections_is_equivalent_to_an_approximate_copy_it_should_th // Act Action act = () => collection.Should().NotBeEquivalentTo(collection1, opt => opt - .Using(ctx => ctx.Subject.Should().BeApproximately(ctx.Expectation, 0.5)) - .WhenTypeIs(), + .Using(ctx => ctx.Subject.Should().BeApproximately(ctx.Expectation, 0.5)) + .WhenTypeIs(), "because we want to test the failure {0}", "message"); // Assert @@ -300,7 +301,7 @@ public void When_asserting_collections_not_to_be_equivalent_with_options_but_sub { // Arrange int[] actual = null; - int[] expectation = new[] { 1, 2, 3 }; + int[] expectation = { 1, 2, 3 }; // Act Action act = () => diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeInAscendingOrder.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeInAscendingOrder.cs index 78f5887480..92d4b176be 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeInAscendingOrder.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeInAscendingOrder.cs @@ -44,7 +44,8 @@ public void When_asserting_the_items_in_an_ascendingly_ordered_collection_are_or } [Fact] - public void When_asserting_the_items_in_an_ascendingly_ordered_collection_are_ordered_ascending_using_the_given_comparer_it_should_succeed() + public void + When_asserting_the_items_in_an_ascendingly_ordered_collection_are_ordered_ascending_using_the_given_comparer_it_should_succeed() { // Arrange var collection = new[] { 1, 2, 2, 3 }; @@ -69,7 +70,8 @@ public void When_asserting_the_items_in_an_unordered_collection_are_ordered_asce } [Fact] - public void When_asserting_the_items_in_an_unordered_collection_are_ordered_ascending_using_the_given_comparer_it_should_throw() + public void + When_asserting_the_items_in_an_unordered_collection_are_ordered_ascending_using_the_given_comparer_it_should_throw() { // Arrange var collection = new[] { 1, 6, 12, 15, 12, 17, 26 }; @@ -126,7 +128,7 @@ public void When_asserting_empty_collection_by_property_expression_ordered_in_as public void When_asserting_single_element_collection_with_no_parameters_ordered_in_ascending_it_should_succeed() { // Arrange - var collection = new int[] { 42 }; + var collection = new[] { 42 }; // Act Action act = () => collection.Should().BeInAscendingOrder(); @@ -141,7 +143,7 @@ public void When_asserting_single_element_collection_by_property_expression_orde // Arrange var collection = new SomeClass[] { - new SomeClass { Text = "a", Number = 1 } + new() { Text = "a", Number = 1 } }; // Act @@ -152,7 +154,8 @@ public void When_asserting_single_element_collection_by_property_expression_orde } [Fact] - public void When_asserting_the_items_in_an_unordered_collection_are_ordered_ascending_using_the_specified_property_it_should_throw() + public void + When_asserting_the_items_in_an_unordered_collection_are_ordered_ascending_using_the_specified_property_it_should_throw() { // Arrange var collection = new[] @@ -171,7 +174,8 @@ public void When_asserting_the_items_in_an_unordered_collection_are_ordered_asce } [Fact] - public void When_asserting_the_items_in_an_unordered_collection_are_ordered_ascending_using_the_specified_property_and_the_given_comparer_it_should_throw() + public void + When_asserting_the_items_in_an_unordered_collection_are_ordered_ascending_using_the_specified_property_and_the_given_comparer_it_should_throw() { // Arrange var collection = new[] @@ -182,7 +186,8 @@ public void When_asserting_the_items_in_an_unordered_collection_are_ordered_asce }; // Act - Action act = () => collection.Should().BeInAscendingOrder(o => o.Text, StringComparer.OrdinalIgnoreCase, "it should be sorted"); + Action act = () => + collection.Should().BeInAscendingOrder(o => o.Text, StringComparer.OrdinalIgnoreCase, "it should be sorted"); // Assert act.Should().Throw() @@ -190,7 +195,8 @@ public void When_asserting_the_items_in_an_unordered_collection_are_ordered_asce } [Fact] - public void When_asserting_the_items_in_an_ascendingly_ordered_collection_are_ordered_ascending_using_the_specified_property_it_should_succeed() + public void + When_asserting_the_items_in_an_ascendingly_ordered_collection_are_ordered_ascending_using_the_specified_property_it_should_succeed() { // Arrange var collection = new[] @@ -208,7 +214,8 @@ public void When_asserting_the_items_in_an_ascendingly_ordered_collection_are_or } [Fact] - public void When_asserting_the_items_in_an_ascendingly_ordered_collection_are_ordered_ascending_using_the_specified_property_and_the_given_comparer_it_should_succeed() + public void + When_asserting_the_items_in_an_ascendingly_ordered_collection_are_ordered_ascending_using_the_specified_property_and_the_given_comparer_it_should_succeed() { // Arrange var collection = new[] @@ -301,7 +308,8 @@ public void When_strings_are_not_in_ascending_order_according_to_a_custom_lambda string[] strings = { "dennis", "roy", "thomas" }; // Act - Action act = () => strings.Should().BeInAscendingOrder((sut, exp) => sut.Last().CompareTo(exp.Last()), "of {0}", "reasons"); + Action act = () => + strings.Should().BeInAscendingOrder((sut, exp) => sut.Last().CompareTo(exp.Last()), "of {0}", "reasons"); // Assert act.Should() @@ -338,7 +346,8 @@ public void When_asserting_the_items_in_a_null_collection_are_ordered_using_the_ } [Fact] - public void When_asserting_the_items_in_a_null_collection_are_ordered_using_the_specified_property_and_the_given_comparer_it_should_throw() + public void + When_asserting_the_items_in_a_null_collection_are_ordered_using_the_specified_property_and_the_given_comparer_it_should_throw() { // Arrange const IEnumerable collection = null; @@ -423,7 +432,8 @@ public void When_asserting_the_items_in_an_unordered_collection_are_not_in_ascen } [Fact] - public void When_asserting_the_items_in_an_unordered_collection_are_not_in_ascending_order_using_the_given_comparer_it_should_succeed() + public void + When_asserting_the_items_in_an_unordered_collection_are_not_in_ascending_order_using_the_given_comparer_it_should_succeed() { // Arrange var collection = new[] { 1, 5, 3 }; @@ -448,13 +458,15 @@ public void When_asserting_the_items_in_an_ascendingly_ordered_collection_are_no } [Fact] - public void When_asserting_the_items_in_an_ascendingly_ordered_collection_are_not_in_ascending_order_using_the_given_comparer_it_should_throw() + public void + When_asserting_the_items_in_an_ascendingly_ordered_collection_are_not_in_ascending_order_using_the_given_comparer_it_should_throw() { // Arrange var collection = new[] { 1, 2, 2, 3 }; // Act - Action action = () => collection.Should().NotBeInAscendingOrder(Comparer.Default, "because numbers are not ordered"); + Action action = () => + collection.Should().NotBeInAscendingOrder(Comparer.Default, "because numbers are not ordered"); // Assert action.Should().Throw() @@ -494,7 +506,7 @@ public void When_asserting_empty_collection_with_no_parameters_not_be_ordered_in public void When_asserting_single_element_collection_with_no_parameters_not_be_ordered_in_ascending_it_should_throw() { // Arrange - var collection = new int[] { 42 }; + var collection = new[] { 42 }; // Act Action act = () => collection.Should().NotBeInAscendingOrder(); @@ -505,12 +517,13 @@ public void When_asserting_single_element_collection_with_no_parameters_not_be_o } [Fact] - public void When_asserting_single_element_collection_by_property_expression_to_not_be_ordered_in_ascending_it_should_throw() + public void + When_asserting_single_element_collection_by_property_expression_to_not_be_ordered_in_ascending_it_should_throw() { // Arrange var collection = new SomeClass[] { - new SomeClass { Text = "a", Number = 1 } + new() { Text = "a", Number = 1 } }; // Act @@ -521,7 +534,8 @@ public void When_asserting_single_element_collection_by_property_expression_to_n } [Fact] - public void When_asserting_the_items_in_a_ascending_ordered_collection_are_not_ordered_ascending_using_the_given_comparer_it_should_throw() + public void + When_asserting_the_items_in_a_ascending_ordered_collection_are_not_ordered_ascending_using_the_given_comparer_it_should_throw() { // Arrange var collection = new[] { 1, 2, 3 }; @@ -535,7 +549,8 @@ public void When_asserting_the_items_in_a_ascending_ordered_collection_are_not_o } [Fact] - public void When_asserting_the_items_not_in_an_ascendingly_ordered_collection_are_not_ordered_ascending_using_the_given_comparer_it_should_succeed() + public void + When_asserting_the_items_not_in_an_ascendingly_ordered_collection_are_not_ordered_ascending_using_the_given_comparer_it_should_succeed() { // Arrange var collection = new[] { 3, 2, 1 }; @@ -548,7 +563,8 @@ public void When_asserting_the_items_not_in_an_ascendingly_ordered_collection_ar } [Fact] - public void When_asserting_the_items_in_a_ascending_ordered_collection_are_not_ordered_ascending_using_the_specified_property_it_should_throw() + public void + When_asserting_the_items_in_a_ascending_ordered_collection_are_not_ordered_ascending_using_the_specified_property_it_should_throw() { // Arrange var collection = new[] @@ -567,7 +583,8 @@ public void When_asserting_the_items_in_a_ascending_ordered_collection_are_not_o } [Fact] - public void When_asserting_the_items_in_an_ordered_collection_are_not_ordered_ascending_using_the_specified_property_and_the_given_comparer_it_should_throw() + public void + When_asserting_the_items_in_an_ordered_collection_are_not_ordered_ascending_using_the_specified_property_and_the_given_comparer_it_should_throw() { // Arrange var collection = new[] @@ -578,7 +595,9 @@ public void When_asserting_the_items_in_an_ordered_collection_are_not_ordered_as }; // Act - Action act = () => collection.Should().NotBeInAscendingOrder(o => o.Text, StringComparer.OrdinalIgnoreCase, "it should not be sorted"); + Action act = () => + collection.Should() + .NotBeInAscendingOrder(o => o.Text, StringComparer.OrdinalIgnoreCase, "it should not be sorted"); // Assert act.Should().Throw() @@ -586,7 +605,8 @@ public void When_asserting_the_items_in_an_ordered_collection_are_not_ordered_as } [Fact] - public void When_asserting_the_items_not_in_an_ascendingly_ordered_collection_are_not_ordered_ascending_using_the_specified_property_it_should_succeed() + public void + When_asserting_the_items_not_in_an_ascendingly_ordered_collection_are_not_ordered_ascending_using_the_specified_property_it_should_succeed() { // Arrange var collection = new[] @@ -604,7 +624,8 @@ public void When_asserting_the_items_not_in_an_ascendingly_ordered_collection_ar } [Fact] - public void When_asserting_the_items_not_in_an_ascendingly_ordered_collection_are_not_ordered_ascending_using_the_specified_property_and_the_given_comparer_it_should_succeed() + public void + When_asserting_the_items_not_in_an_ascendingly_ordered_collection_are_not_ordered_ascending_using_the_specified_property_and_the_given_comparer_it_should_succeed() { // Arrange var collection = new[] @@ -697,7 +718,8 @@ public void When_strings_are_unexpectedly_in_ascending_order_according_to_a_cust string[] strings = { "barbara", "dennis", "roy" }; // Act - Action act = () => strings.Should().NotBeInAscendingOrder((sut, exp) => sut.Last().CompareTo(exp.Last()), "of {0}", "reasons"); + Action act = () => + strings.Should().NotBeInAscendingOrder((sut, exp) => sut.Last().CompareTo(exp.Last()), "of {0}", "reasons"); // Assert act.Should() @@ -742,7 +764,8 @@ public void When_asserting_the_items_in_a_null_collection_are_not_ordered_using_ } [Fact] - public void When_asserting_the_items_in_a_null_collection_are_not_ordered_using_the_specified_property_and_the_given_comparer_it_should_throw() + public void + When_asserting_the_items_in_a_null_collection_are_not_ordered_using_the_specified_property_and_the_given_comparer_it_should_throw() { // Arrange const IEnumerable collection = null; @@ -784,7 +807,8 @@ public void When_asserting_the_items_in_a_collection_are_not_ordered_and_the_giv } [Fact] - public void When_asserting_the_items_in_ay_collection_are_not_ordered_using_an_invalid_property_expression_it_should_throw() + public void + When_asserting_the_items_in_ay_collection_are_not_ordered_using_an_invalid_property_expression_it_should_throw() { // Arrange var collection = Enumerable.Empty(); diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeInDescendingOrder.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeInDescendingOrder.cs index 4773f3c44f..702fb674c0 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeInDescendingOrder.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeInDescendingOrder.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using FluentAssertions.Execution; using Xunit; using Xunit.Sdk; @@ -69,7 +68,7 @@ public void When_asserting_empty_collection_with_no_parameters_ordered_in_descen public void When_asserting_single_element_collection_with_no_parameters_ordered_in_descending_it_should_succeed() { // Arrange - var collection = new int[] { 42 }; + var collection = new[] { 42 }; // Act Action act = () => collection.Should().BeInDescendingOrder(); @@ -84,7 +83,7 @@ public void When_asserting_single_element_collection_by_property_expression_orde // Arrange var collection = new SomeClass[] { - new SomeClass { Text = "a", Number = 1 } + new() { Text = "a", Number = 1 } }; // Act @@ -95,13 +94,15 @@ public void When_asserting_single_element_collection_by_property_expression_orde } [Fact] - public void When_asserting_the_items_in_an_unordered_collection_are_ordered_descending_using_the_given_comparer_it_should_throw() + public void + When_asserting_the_items_in_an_unordered_collection_are_ordered_descending_using_the_given_comparer_it_should_throw() { // Arrange var collection = new[] { "z", "x", "y" }; // Act - Action action = () => collection.Should().BeInDescendingOrder(Comparer.Default, "because letters are ordered"); + Action action = () => + collection.Should().BeInDescendingOrder(Comparer.Default, "because letters are ordered"); // Assert action.Should().Throw() @@ -110,7 +111,8 @@ public void When_asserting_the_items_in_an_unordered_collection_are_ordered_desc } [Fact] - public void When_asserting_the_items_in_an_descendingly_ordered_collection_are_ordered_descending_using_the_given_comparer_it_should_succeed() + public void + When_asserting_the_items_in_an_descendingly_ordered_collection_are_ordered_descending_using_the_given_comparer_it_should_succeed() { // Arrange var collection = new[] { "z", "y", "x" }; @@ -120,7 +122,8 @@ public void When_asserting_the_items_in_an_descendingly_ordered_collection_are_o } [Fact] - public void When_asserting_the_items_in_an_unordered_collection_are_ordered_descending_using_the_specified_property_it_should_throw() + public void + When_asserting_the_items_in_an_unordered_collection_are_ordered_descending_using_the_specified_property_it_should_throw() { // Arrange var collection = new[] @@ -139,7 +142,8 @@ public void When_asserting_the_items_in_an_unordered_collection_are_ordered_desc } [Fact] - public void When_asserting_the_items_in_an_unordered_collection_are_ordered_descending_using_the_specified_property_and_the_given_comparer_it_should_throw() + public void + When_asserting_the_items_in_an_unordered_collection_are_ordered_descending_using_the_specified_property_and_the_given_comparer_it_should_throw() { // Arrange var collection = new[] @@ -150,7 +154,8 @@ public void When_asserting_the_items_in_an_unordered_collection_are_ordered_desc }; // Act - Action act = () => collection.Should().BeInDescendingOrder(o => o.Text, StringComparer.OrdinalIgnoreCase, "it should be sorted"); + Action act = () => + collection.Should().BeInDescendingOrder(o => o.Text, StringComparer.OrdinalIgnoreCase, "it should be sorted"); // Assert act.Should().Throw() @@ -158,7 +163,8 @@ public void When_asserting_the_items_in_an_unordered_collection_are_ordered_desc } [Fact] - public void When_asserting_the_items_in_an_descendingly_ordered_collection_are_ordered_descending_using_the_specified_property_it_should_succeed() + public void + When_asserting_the_items_in_an_descendingly_ordered_collection_are_ordered_descending_using_the_specified_property_it_should_succeed() { // Arrange var collection = new[] @@ -176,7 +182,8 @@ public void When_asserting_the_items_in_an_descendingly_ordered_collection_are_o } [Fact] - public void When_asserting_the_items_in_an_descendingly_ordered_collection_are_ordered_descending_using_the_specified_property_and_the_given_comparer_it_should_succeed() + public void + When_asserting_the_items_in_an_descendingly_ordered_collection_are_ordered_descending_using_the_specified_property_and_the_given_comparer_it_should_succeed() { // Arrange var collection = new[] @@ -269,7 +276,8 @@ public void When_strings_are_not_in_descending_order_based_on_a_custom_lambda_it string[] strings = { "dennis", "roy", "barbara" }; // Act - Action act = () => strings.Should().BeInDescendingOrder((sut, exp) => sut.Last().CompareTo(exp.Last()), "of {0}", "reasons"); + Action act = () => + strings.Should().BeInDescendingOrder((sut, exp) => sut.Last().CompareTo(exp.Last()), "of {0}", "reasons"); // Assert act.Should() @@ -291,7 +299,8 @@ public void When_asserting_the_items_in_an_unordered_collection_are_not_in_desce } [Fact] - public void When_asserting_the_items_in_an_unordered_collection_are_not_in_descending_order_using_the_given_comparer_it_should_succeed() + public void + When_asserting_the_items_in_an_unordered_collection_are_not_in_descending_order_using_the_given_comparer_it_should_succeed() { // Arrange var collection = new[] { "x", "y", "x" }; @@ -316,13 +325,15 @@ public void When_asserting_the_items_in_a_descending_ordered_collection_are_not_ } [Fact] - public void When_asserting_the_items_in_a_descending_ordered_collection_are_not_in_descending_order_using_the_given_comparer_it_should_throw() + public void + When_asserting_the_items_in_a_descending_ordered_collection_are_not_in_descending_order_using_the_given_comparer_it_should_throw() { // Arrange var collection = new[] { "c", "b", "a" }; // Act - Action action = () => collection.Should().NotBeInDescendingOrder(Comparer.Default, "because numbers are not ordered"); + Action action = () => + collection.Should().NotBeInDescendingOrder(Comparer.Default, "because numbers are not ordered"); // Assert action.Should().Throw() @@ -362,7 +373,7 @@ public void When_asserting_empty_collection_with_no_parameters_not_be_ordered_in public void When_asserting_single_element_collection_with_no_parameters_not_be_ordered_in_descending_it_should_throw() { // Arrange - var collection = new int[] { 42 }; + var collection = new[] { 42 }; // Act Action act = () => collection.Should().NotBeInDescendingOrder(); @@ -373,12 +384,13 @@ public void When_asserting_single_element_collection_with_no_parameters_not_be_o } [Fact] - public void When_asserting_single_element_collection_by_property_expression_to_not_be_ordered_in_descending_it_should_throw() + public void + When_asserting_single_element_collection_by_property_expression_to_not_be_ordered_in_descending_it_should_throw() { // Arrange var collection = new SomeClass[] { - new SomeClass { Text = "a", Number = 1 } + new() { Text = "a", Number = 1 } }; // Act @@ -389,7 +401,8 @@ public void When_asserting_single_element_collection_by_property_expression_to_n } [Fact] - public void When_asserting_the_items_in_a_descending_ordered_collection_are_not_ordered_descending_using_the_given_comparer_it_should_throw() + public void + When_asserting_the_items_in_a_descending_ordered_collection_are_not_ordered_descending_using_the_given_comparer_it_should_throw() { // Arrange var collection = new[] { 3, 2, 1 }; @@ -403,7 +416,8 @@ public void When_asserting_the_items_in_a_descending_ordered_collection_are_not_ } [Fact] - public void When_asserting_the_items_not_in_an_descendingly_ordered_collection_are_not_ordered_descending_using_the_given_comparer_it_should_succeed() + public void + When_asserting_the_items_not_in_an_descendingly_ordered_collection_are_not_ordered_descending_using_the_given_comparer_it_should_succeed() { // Arrange var collection = new[] { 1, 2, 3 }; @@ -416,7 +430,8 @@ public void When_asserting_the_items_not_in_an_descendingly_ordered_collection_a } [Fact] - public void When_asserting_the_items_in_a_descending_ordered_collection_are_not_ordered_descending_using_the_specified_property_it_should_throw() + public void + When_asserting_the_items_in_a_descending_ordered_collection_are_not_ordered_descending_using_the_specified_property_it_should_throw() { // Arrange var collection = new[] @@ -435,7 +450,8 @@ public void When_asserting_the_items_in_a_descending_ordered_collection_are_not_ } [Fact] - public void When_asserting_the_items_in_an_ordered_collection_are_not_ordered_descending_using_the_specified_property_and_the_given_comparer_it_should_throw() + public void + When_asserting_the_items_in_an_ordered_collection_are_not_ordered_descending_using_the_specified_property_and_the_given_comparer_it_should_throw() { // Arrange var collection = new[] @@ -446,7 +462,9 @@ public void When_asserting_the_items_in_an_ordered_collection_are_not_ordered_de }; // Act - Action act = () => collection.Should().NotBeInDescendingOrder(o => o.Text, StringComparer.OrdinalIgnoreCase, "it should not be sorted"); + Action act = () => + collection.Should() + .NotBeInDescendingOrder(o => o.Text, StringComparer.OrdinalIgnoreCase, "it should not be sorted"); // Assert act.Should().Throw() @@ -454,7 +472,8 @@ public void When_asserting_the_items_in_an_ordered_collection_are_not_ordered_de } [Fact] - public void When_asserting_the_items_not_in_an_descendingly_ordered_collection_are_not_ordered_descending_using_the_specified_property_it_should_succeed() + public void + When_asserting_the_items_not_in_an_descendingly_ordered_collection_are_not_ordered_descending_using_the_specified_property_it_should_succeed() { // Arrange var collection = new[] @@ -472,7 +491,8 @@ public void When_asserting_the_items_not_in_an_descendingly_ordered_collection_a } [Fact] - public void When_asserting_the_items_not_in_an_descendingly_ordered_collection_are_not_ordered_descending_using_the_specified_property_and_the_given_comparer_it_should_succeed() + public void + When_asserting_the_items_not_in_an_descendingly_ordered_collection_are_not_ordered_descending_using_the_specified_property_and_the_given_comparer_it_should_succeed() { // Arrange var collection = new[] @@ -565,7 +585,8 @@ public void When_strings_are_unexpectedly_in_descending_order_based_on_a_custom_ string[] strings = { "roy", "dennis", "barbara" }; // Act - Action act = () => strings.Should().NotBeInDescendingOrder((sut, exp) => sut.Last().CompareTo(exp.Last()), "of {0}", "reasons"); + Action act = () => + strings.Should().NotBeInDescendingOrder((sut, exp) => sut.Last().CompareTo(exp.Last()), "of {0}", "reasons"); // Assert act.Should() diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeSubsetOf.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeSubsetOf.cs index b3f92e9a6a..5c4deecc10 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeSubsetOf.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeSubsetOf.cs @@ -36,7 +36,7 @@ public void When_collection_is_not_a_subset_of_another_it_should_throw_with_the_ // Assert act.Should().Throw().WithMessage( "Expected subset to be a subset of {1, 2, 4, 5} because we want to test the failure message, " + - "but items {3, 6} are not part of the superset."); + "but items {3, 6} are not part of the superset."); } [Fact] diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.Contain.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.Contain.cs index be5a20c965..fba270d0b8 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.Contain.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.Contain.cs @@ -94,7 +94,8 @@ public void When_a_collection_does_not_contain_a_single_element_collection_it_sh } [Fact] - public void When_a_collection_does_not_contain_other_collection_with_assertion_scope_it_should_throw_with_clear_explanation() + public void + When_a_collection_does_not_contain_other_collection_with_assertion_scope_it_should_throw_with_clear_explanation() { // Arrange var collection = new[] { 1, 2, 3 }; @@ -461,7 +462,8 @@ public void When_asserting_collection_does_not_contain_a_list_of_items_against_n } [Fact] - public void When_asserting_collection_doesnt_contain_values_according_to_predicate_but_collection_is_null_it_should_throw() + public void + When_asserting_collection_doesnt_contain_values_according_to_predicate_but_collection_is_null_it_should_throw() { // Arrange const IEnumerable strings = null; diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainEquivalentOf.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainEquivalentOf.cs index 3040804311..44fbdec445 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainEquivalentOf.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainEquivalentOf.cs @@ -49,25 +49,27 @@ public void When_character_collection_does_contain_equivalent_it_should_succeed( public void When_string_collection_does_contain_same_string_with_other_case_it_should_throw() { // Arrange - string[] collection = new[] { "a", "b", "c" }; + string[] collection = { "a", "b", "c" }; string item = "C"; // Act Action act = () => collection.Should().ContainEquivalentOf(item); // Assert - act.Should().Throw().WithMessage("Expected collection {\"a\", \"b\", \"c\"} to contain equivalent of \"C\".*"); + act.Should().Throw() + .WithMessage("Expected collection {\"a\", \"b\", \"c\"} to contain equivalent of \"C\".*"); } [Fact] public void When_string_collection_does_contain_same_string_it_should_throw_with_a_useful_message() { // Arrange - string[] collection = new[] { "a" }; + string[] collection = { "a" }; string item = "b"; // Act - Action act = () => collection.Should().ContainEquivalentOf(item, "because we want to test the failure {0}", "message"); + Action act = () => + collection.Should().ContainEquivalentOf(item, "because we want to test the failure {0}", "message"); // Assert act.Should().Throw() @@ -166,6 +168,7 @@ public void When_collection_does_not_contain_equivalent_because_of_second_proper Age = 18 } }; + var item = new Customer { Name = "John", Age = 20 }; // Act @@ -192,6 +195,7 @@ public void When_collection_does_contain_equivalent_by_including_single_property Age = 18 } }; + var item = new Customer { Name = "John", Age = 20 }; // Act / Assert @@ -262,11 +266,13 @@ public void When_collection_contains_object_equal_to_another_it_should_throw() var collection = new[] { 0, 1 }; // Act - Action act = () => collection.Should().NotContainEquivalentOf(item, "because we want to test the failure {0}", "message"); + Action act = () => + collection.Should().NotContainEquivalentOf(item, "because we want to test the failure {0}", "message"); // Assert - act.Should().Throw().WithMessage("Expected collection {0, 1} not to contain*because we want to test the failure message, " + - "but found one at index 1.*With configuration*"); + act.Should().Throw().WithMessage( + "Expected collection {0, 1} not to contain*because we want to test the failure message, " + + "but found one at index 1.*With configuration*"); } [Fact] @@ -277,11 +283,13 @@ public void When_collection_contains_several_objects_equal_to_another_it_should_ var collection = new[] { 0, 1, 1 }; // Act - Action act = () => collection.Should().NotContainEquivalentOf(item, "because we want to test the failure {0}", "message"); + Action act = () => + collection.Should().NotContainEquivalentOf(item, "because we want to test the failure {0}", "message"); // Assert - act.Should().Throw().WithMessage("Expected collection {0, 1, 1} not to contain*because we want to test the failure message, " + - "but found several at indices {1, 2}.*With configuration*"); + act.Should().Throw().WithMessage( + "Expected collection {0, 1, 1} not to contain*because we want to test the failure message, " + + "but found several at indices {1, 2}.*With configuration*"); } [Fact] @@ -370,6 +378,7 @@ public void When_asserting_collection_to_not_contain_equivalent_it_should_respec Age = 18 } }; + var item = new Customer { Name = "John", Age = 20 }; // Act @@ -399,7 +408,7 @@ public void When_asserting_collection_to_not_contain_equivalent_it_should_allow_ // Assert act.Should().Throw().WithMessage("Expected collection*not to contain*first message*but*.\n" + - "Expected*4 item(s)*because*second message*but*."); + "Expected*4 item(s)*because*second message*but*."); } } } diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainInConsecutiveOrder.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainInConsecutiveOrder.cs index 362a0eda2d..788e6865cf 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainInConsecutiveOrder.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainInConsecutiveOrder.cs @@ -33,7 +33,8 @@ public void When_the_second_collection_contains_just_1_item_included_in_the_firs } [Fact] - public void When_the_first_collection_contains_a_partial_duplicate_sequence_at_the_start_without_affecting_the_explicit_order_it_should_not_throw() + public void + When_the_first_collection_contains_a_partial_duplicate_sequence_at_the_start_without_affecting_the_explicit_order_it_should_not_throw() { // Arrange var collection = new[] { 1, 2, 1, 2, 3, 2 }; @@ -69,7 +70,7 @@ public void When_collection_contains_null_value_it_should_not_throw() var collection = new object[] { 1, null, 2, "string" }; // Act / Assert - collection.Should().ContainInConsecutiveOrder(new object[] { 1, null, 2, "string" }); + collection.Should().ContainInConsecutiveOrder(1, null, 2, "string"); } [Fact] @@ -148,7 +149,7 @@ public void When_a_collection_does_not_contain_an_ordered_item_it_should_throw_w // Assert act.Should().Throw().WithMessage( "Expected collection {1, 2, 3} to contain items {4, 1} in order because we failed, " + - "but 4 (index 0) did not appear (in the right consecutive order)."); + "but 4 (index 0) did not appear (in the right consecutive order)."); } [Fact] @@ -172,7 +173,9 @@ public void When_asserting_collection_contains_some_values_in_order_but_collecti Action act = () => { using var _ = new AssertionScope(); - collection.Should().ContainInConsecutiveOrder(new[] { 4 }, "because we're checking how it reacts to a null subject"); + + collection.Should() + .ContainInConsecutiveOrder(new[] { 4 }, "because we're checking how it reacts to a null subject"); }; // Assert @@ -263,7 +266,8 @@ public void When_asserting_collection_does_not_contain_some_values_in_order_but_ Action act = () => collection.Should().NotContainInConsecutiveOrder(4); // Assert - act.Should().Throw().WithMessage("Cannot verify absence of ordered containment in a collection."); + act.Should().Throw() + .WithMessage("Cannot verify absence of ordered containment in a collection."); } [Fact] diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainInOrder.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainInOrder.cs index aebb9e1e47..2ad07202f5 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainInOrder.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainInOrder.cs @@ -29,7 +29,7 @@ public void When_collection_contains_null_value_it_should_not_throw() var collection = new object[] { 1, null, 2, "string" }; // Act / Assert - collection.Should().ContainInOrder(new object[] { 1, null, "string" }); + collection.Should().ContainInOrder(1, null, "string"); } [Fact] @@ -86,7 +86,7 @@ public void When_a_collection_does_not_contain_an_ordered_item_it_should_throw_w // Assert act.Should().Throw().WithMessage( "Expected collection {1, 2, 3} to contain items {4, 1} in order because we failed, " + - "but 4 (index 0) did not appear (in the right order)."); + "but 4 (index 0) did not appear (in the right order)."); } [Fact] @@ -119,14 +119,14 @@ public void When_passing_in_null_while_checking_for_ordered_containment_it_shoul public void Collections_contain_the_empty_sequence() { // Assert - new[] { 1 }.Should().ContainInOrder(new int[0]); + new[] { 1 }.Should().ContainInOrder(); } [Fact] public void Collections_do_not_not_contain_the_empty_sequence() { // Assert - new[] { 1 }.Should().NotContainInOrder(new int[0]); + new[] { 1 }.Should().NotContainInOrder(); } [Fact] @@ -200,7 +200,8 @@ public void When_asserting_collection_does_not_contain_some_values_in_order_but_ Action act = () => collection.Should().NotContainInOrder(4); // Assert - act.Should().Throw().WithMessage("Cannot verify absence of ordered containment in a collection."); + act.Should().Throw() + .WithMessage("Cannot verify absence of ordered containment in a collection."); } [Fact] diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainItemsAssignableTo.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainItemsAssignableTo.cs index cbafc711d0..8faa500717 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainItemsAssignableTo.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainItemsAssignableTo.cs @@ -28,10 +28,10 @@ public void Should_succeed_when_asserting_collection_with_items_of_different_typ { // Arrange var collection = new List - { - 1, - "2" - }; + { + 1, + "2" + }; // Act / Assert collection.Should().ContainItemsAssignableTo(); @@ -65,7 +65,9 @@ public void When_a_collection_is_empty_an_exception_should_be_thrown() Action act = () => collection.Should().ContainItemsAssignableTo(); // Assert - act.Should().Throw().WithMessage("Expected collection to contain at least one element assignable to type \"System.Int32\", but found {empty}."); + act.Should().Throw() + .WithMessage( + "Expected collection to contain at least one element assignable to type \"System.Int32\", but found {empty}."); } [Fact] @@ -76,7 +78,8 @@ public void Should_throw_exception_when_asserting_collection_for_missing_item_ty Action act = () => collection.Should().ContainItemsAssignableTo(); act.Should().Throw() - .WithMessage("Expected collection to contain at least one element assignable to type \"System.Int32\", but found {System.String, System.Decimal}."); + .WithMessage( + "Expected collection to contain at least one element assignable to type \"System.Int32\", but found {System.String, System.Decimal}."); } } } diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainSingle.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainSingle.cs index 6e1b0f0877..c64c1c21bb 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainSingle.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.ContainSingle.cs @@ -53,7 +53,7 @@ public void When_asserting_an_empty_collection_contains_a_single_item_matching_a // Assert string expectedMessage = - $"Expected collection to contain a single item matching (item == 2), but the collection is empty."; + "Expected collection to contain a single item matching (item == 2), but the collection is empty."; act.Should().Throw().WithMessage(expectedMessage); } @@ -74,7 +74,7 @@ public void When_asserting_a_null_collection_contains_a_single_item_matching_a_p // Assert string expectedMessage = - $"Expected collection to contain a single item matching (item == 2), but found ."; + "Expected collection to contain a single item matching (item == 2), but found ."; act.Should().Throw().WithMessage(expectedMessage); } @@ -91,7 +91,7 @@ public void When_non_empty_collection_does_not_contain_a_single_item_matching_a_ // Assert string expectedMessage = - $"Expected collection to contain a single item matching (item == 2), but no such item was found."; + "Expected collection to contain a single item matching (item == 2), but no such item was found."; act.Should().Throw().WithMessage(expectedMessage); } @@ -108,7 +108,7 @@ public void When_non_empty_collection_contains_more_than_a_single_item_matching_ // Assert string expectedMessage = - $"Expected collection to contain a single item matching (item == 2), but 3 such items were found."; + "Expected collection to contain a single item matching (item == 2), but 3 such items were found."; act.Should().Throw().WithMessage(expectedMessage); } @@ -178,7 +178,8 @@ public void When_asserting_an_empty_collection_contains_a_single_item_it_should_ // Assert act.Should().Throw() - .WithMessage("Expected collection to contain a single item because more is not allowed, but the collection is empty."); + .WithMessage( + "Expected collection to contain a single item because more is not allowed, but the collection is empty."); } [Fact] @@ -285,6 +286,6 @@ public void When_an_assertion_fails_on_ContainSingle_succeeding_message_should_b // Assert act.Should().Throw() .WithMessage("Expected*to contain a single item, but the collection is empty*" + - "Expected*to contain a single item, but the collection is empty*"); + "Expected*to contain a single item, but the collection is empty*"); } } diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.EndWith.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.EndWith.cs index dd3d287606..c29465afe3 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.EndWith.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.EndWith.cs @@ -83,13 +83,15 @@ public void When_collection_does_not_end_with_a_null_sequence_using_a_comparer_i } [Fact] - public void When_collection_does_not_end_with_a_specific_element_in_a_sequence_using_custom_equality_comparison_it_should_throw() + public void + When_collection_does_not_end_with_a_specific_element_in_a_sequence_using_custom_equality_comparison_it_should_throw() { // Arrange var collection = new[] { "john", "bill", "jane", "mike" }; // Act - Action act = () => collection.Should().EndWith(new[] { "bill", "ryan", "mike" }, (s1, s2) => string.Equals(s1, s2, StringComparison.Ordinal), "of some reason"); + Action act = () => collection.Should().EndWith(new[] { "bill", "ryan", "mike" }, + (s1, s2) => string.Equals(s1, s2, StringComparison.Ordinal), "of some reason"); // Assert act.Should().Throw().WithMessage( @@ -123,13 +125,15 @@ public void When_collection_ends_with_the_specific_sequence_of_elements_it_shoul } [Fact] - public void When_collection_ends_with_the_specific_sequence_of_elements_using_custom_equality_comparison_it_should_not_throw() + public void + When_collection_ends_with_the_specific_sequence_of_elements_using_custom_equality_comparison_it_should_not_throw() { // Arrange var collection = new[] { "john", "bill", "jane", "mike" }; // Act - Action act = () => collection.Should().EndWith(new[] { "JaNe", "mIkE" }, (s1, s2) => string.Equals(s1, s2, StringComparison.OrdinalIgnoreCase)); + Action act = () => collection.Should().EndWith(new[] { "JaNe", "mIkE" }, + (s1, s2) => string.Equals(s1, s2, StringComparison.OrdinalIgnoreCase)); // Assert act.Should().NotThrow(); @@ -162,13 +166,15 @@ public void When_collection_ends_with_the_specific_sequence_with_null_elements_i } [Fact] - public void When_collection_ends_with_the_specific_sequence_with_null_elements_using_custom_equality_comparison_it_should_not_throw() + public void + When_collection_ends_with_the_specific_sequence_with_null_elements_using_custom_equality_comparison_it_should_not_throw() { // Arrange var collection = new[] { "john", "bill", "jane", null, "mike", null }; // Act - Action act = () => collection.Should().EndWith(new[] { "JaNe", null, "mIkE", null }, (s1, s2) => string.Equals(s1, s2, StringComparison.OrdinalIgnoreCase)); + Action act = () => collection.Should().EndWith(new[] { "JaNe", null, "mIkE", null }, + (s1, s2) => string.Equals(s1, s2, StringComparison.OrdinalIgnoreCase)); // Assert act.Should().NotThrow(); diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.Equal.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.Equal.cs index 0efc74f927..0f87d4b6fa 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.Equal.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.Equal.cs @@ -77,7 +77,8 @@ public void When_two_collections_are_not_equal_because_one_item_differs_it_shoul } [Fact] - public void When_two_collections_are_not_equal_because_the_actual_collection_contains_more_items_it_should_throw_using_the_reason() + public void + When_two_collections_are_not_equal_because_the_actual_collection_contains_more_items_it_should_throw_using_the_reason() { // Arrange var collection1 = new[] { 1, 2, 3 }; @@ -92,7 +93,8 @@ public void When_two_collections_are_not_equal_because_the_actual_collection_con } [Fact] - public void When_two_collections_are_not_equal_because_the_actual_collection_contains_less_items_it_should_throw_using_the_reason() + public void + When_two_collections_are_not_equal_because_the_actual_collection_contains_less_items_it_should_throw_using_the_reason() { // Arrange var collection1 = new[] { 1, 2, 3 }; @@ -129,7 +131,8 @@ public void When_asserting_collections_to_be_equal_but_subject_collection_is_nul var collection1 = new[] { 1, 2, 3 }; // Act - Action act = () => collection.Should().Equal(collection1, "because we want to test the behaviour with a null subject"); + Action act = () => + collection.Should().Equal(collection1, "because we want to test the behaviour with a null subject"); // Assert act.Should().Throw().WithMessage( @@ -144,7 +147,8 @@ public void When_asserting_collections_to_be_equal_but_expected_collection_is_nu int[] collection1 = null; // Act - Action act = () => collection.Should().Equal(collection1, "because we want to test the behaviour with a null subject"); + Action act = () => + collection.Should().Equal(collection1, "because we want to test the behaviour with a null subject"); // Assert act.Should().Throw() @@ -187,6 +191,7 @@ public void When_all_items_match_according_to_a_predicate_it_should_succeed() { // Arrange var actual = new List { "ONE", "TWO", "THREE", "FOUR" }; + var expected = new[] { new { Value = "One" }, @@ -208,6 +213,7 @@ public void When_any_item_does_not_match_according_to_a_predicate_it_should_thro { // Arrange var actual = new List { "ONE", "TWO", "THREE", "FOUR" }; + var expected = new[] { new { Value = "One" }, @@ -311,7 +317,8 @@ public void When_asserting_different_collections_to_not_be_equal_it_should_enume } [Fact] - public void When_asserting_equality_with_a_collection_built_from_params_arguments_that_are_assignable_to_the_subjects_type_parameter_it_should_succeed_by_treating_the_arguments_as_of_that_type() + public void + When_asserting_equality_with_a_collection_built_from_params_arguments_that_are_assignable_to_the_subjects_type_parameter_it_should_succeed_by_treating_the_arguments_as_of_that_type() { // Arrange byte[] byteArray = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }; @@ -411,7 +418,8 @@ public void When_asserting_collections_not_to_be_equal_but_both_collections_refe var collection2 = collection1; // Act - Action act = () => collection1.Should().NotEqual(collection2, "because we want to test the behaviour with same objects"); + Action act = () => + collection1.Should().NotEqual(collection2, "because we want to test the behaviour with same objects"); // Assert act.Should().Throw().WithMessage( diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCount.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCount.cs index 55ed2067e4..1b08a6d9b0 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCount.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCount.cs @@ -36,7 +36,8 @@ public void Should_fail_when_asserting_collection_has_a_count_that_is_different_ } [Fact] - public void When_collection_has_a_count_that_is_different_from_the_number_of_items_it_should_fail_with_descriptive_message_() + public void + When_collection_has_a_count_that_is_different_from_the_number_of_items_it_should_fail_with_descriptive_message_() { // Arrange var collection = new[] { 1, 2, 3 }; @@ -46,7 +47,8 @@ public void When_collection_has_a_count_that_is_different_from_the_number_of_ite // Assert action.Should().Throw() - .WithMessage("Expected collection to contain 4 item(s) because we want to test the failure message, but found 3: {1, 2, 3}."); + .WithMessage( + "Expected collection to contain 4 item(s) because we want to test the failure message, but found 3: {1, 2, 3}."); } [Fact] @@ -148,7 +150,7 @@ public void When_collection_count_is_matched_against_a_predicate_it_should_not_t var collection = new[] { 1, 2, 3 }; // Act - Action act = () => collection.Should().HaveCount(c => c % 2 == 1); + Action act = () => collection.Should().HaveCount(c => (c % 2) == 1); // Assert act.Should().NotThrow(); @@ -161,7 +163,7 @@ public void When_collection_count_is_matched_against_a_predicate_it_should_throw var collection = new[] { 1, 2, 3 }; // Act - Action act = () => collection.Should().HaveCount(c => c % 2 == 0); + Action act = () => collection.Should().HaveCount(c => (c % 2) == 0); // Assert act.Should().Throw(); @@ -248,7 +250,8 @@ public void When_collection_count_is_same_than_and_collection_is_null_it_should_ }; // Assert - act.Should().Throw().WithMessage("*not contain*1*we want to test the behaviour with a null subject*found *"); + act.Should().Throw() + .WithMessage("*not contain*1*we want to test the behaviour with a null subject*found *"); } } } diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCountGreaterThan.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCountGreaterThan.cs index 8b07311574..ee4f8b9b85 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCountGreaterThan.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCountGreaterThan.cs @@ -43,11 +43,13 @@ public void When_collection_has_a_count_greater_than_the_number_of_items_it_shou var collection = new[] { 1, 2, 3 }; // Act - Action action = () => collection.Should().HaveCountGreaterThan(3, "because we want to test the failure {0}", "message"); + Action action = () => + collection.Should().HaveCountGreaterThan(3, "because we want to test the failure {0}", "message"); // Assert action.Should().Throw() - .WithMessage("Expected collection to contain more than 3 item(s) because we want to test the failure message, but found 3: {1, 2, 3}."); + .WithMessage( + "Expected collection to contain more than 3 item(s) because we want to test the failure message, but found 3: {1, 2, 3}."); } [Fact] @@ -64,7 +66,8 @@ public void When_collection_count_is_greater_than_and_collection_is_null_it_shou }; // Assert - act.Should().Throw().WithMessage("*more than*1*we want to test the behaviour with a null subject*found *"); + act.Should().Throw() + .WithMessage("*more than*1*we want to test the behaviour with a null subject*found *"); } } } diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCountGreaterThanOrEqualTo.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCountGreaterThanOrEqualTo.cs index 27a30f2b47..a6bd1f0e3d 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCountGreaterThanOrEqualTo.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCountGreaterThanOrEqualTo.cs @@ -36,17 +36,20 @@ public void Should_fail_when_asserting_collection_has_a_count_greater_than_or_eq } [Fact] - public void When_collection_has_a_count_greater_than_or_equal_to_the_number_of_items_it_should_fail_with_descriptive_message_() + public void + When_collection_has_a_count_greater_than_or_equal_to_the_number_of_items_it_should_fail_with_descriptive_message_() { // Arrange var collection = new[] { 1, 2, 3 }; // Act - Action action = () => collection.Should().HaveCountGreaterThanOrEqualTo(4, "because we want to test the failure {0}", "message"); + Action action = () => + collection.Should().HaveCountGreaterThanOrEqualTo(4, "because we want to test the failure {0}", "message"); // Assert action.Should().Throw() - .WithMessage("Expected collection to contain at least 4 item(s) because we want to test the failure message, but found 3: {1, 2, 3}."); + .WithMessage( + "Expected collection to contain at least 4 item(s) because we want to test the failure message, but found 3: {1, 2, 3}."); } [Fact] @@ -63,7 +66,8 @@ public void When_collection_count_is_greater_than_or_equal_to_and_collection_is_ }; // Assert - act.Should().Throw().WithMessage("*at least*1*we want to test the behaviour with a null subject*found *"); + act.Should().Throw() + .WithMessage("*at least*1*we want to test the behaviour with a null subject*found *"); } } } diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCountLessThan.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCountLessThan.cs index d19a3d0f2c..190002e44a 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCountLessThan.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCountLessThan.cs @@ -46,7 +46,8 @@ public void When_collection_has_a_count_less_than_the_number_of_items_it_should_ // Assert action.Should().Throw() - .WithMessage("Expected collection to contain fewer than 3 item(s) because we want to test the failure message, but found 3: {1, 2, 3}."); + .WithMessage( + "Expected collection to contain fewer than 3 item(s) because we want to test the failure message, but found 3: {1, 2, 3}."); } [Fact] @@ -63,7 +64,8 @@ public void When_collection_count_is_less_than_and_collection_is_null_it_should_ }; // Assert - act.Should().Throw().WithMessage("*fewer than*1*we want to test the behaviour with a null subject*found *"); + act.Should().Throw() + .WithMessage("*fewer than*1*we want to test the behaviour with a null subject*found *"); } } } diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCountLessThanOrEqualTo.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCountLessThanOrEqualTo.cs index 0ee5a7572b..3ce98f3d43 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCountLessThanOrEqualTo.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveCountLessThanOrEqualTo.cs @@ -36,17 +36,20 @@ public void Should_fail_when_asserting_collection_has_a_count_less_than_or_equal } [Fact] - public void When_collection_has_a_count_less_than_or_equal_to_the_number_of_items_it_should_fail_with_descriptive_message_() + public void + When_collection_has_a_count_less_than_or_equal_to_the_number_of_items_it_should_fail_with_descriptive_message_() { // Arrange var collection = new[] { 1, 2, 3 }; // Act - Action action = () => collection.Should().HaveCountLessThanOrEqualTo(2, "because we want to test the failure {0}", "message"); + Action action = () => + collection.Should().HaveCountLessThanOrEqualTo(2, "because we want to test the failure {0}", "message"); // Assert action.Should().Throw() - .WithMessage("Expected collection to contain at most 2 item(s) because we want to test the failure message, but found 3: {1, 2, 3}."); + .WithMessage( + "Expected collection to contain at most 2 item(s) because we want to test the failure message, but found 3: {1, 2, 3}."); } [Fact] @@ -63,7 +66,8 @@ public void When_collection_count_is_less_than_or_equal_to_and_collection_is_nul }; // Assert - act.Should().Throw().WithMessage("*at most*1*we want to test the behaviour with a null subject*found *"); + act.Should().Throw() + .WithMessage("*at most*1*we want to test the behaviour with a null subject*found *"); } } } diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveSameCount.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveSameCount.cs index a21e14db1f..43a3947f6f 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveSameCount.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.HaveSameCount.cs @@ -166,7 +166,8 @@ public void When_asserting_collections_to_not_have_same_count_against_an_other_n } [Fact] - public void When_asserting_collections_to_not_have_same_count_but_both_collections_references_the_same_object_it_should_throw() + public void + When_asserting_collections_to_not_have_same_count_but_both_collections_references_the_same_object_it_should_throw() { // Arrange var collection = new[] { 1, 2, 3 }; diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.OnlyHaveUniqueItems.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.OnlyHaveUniqueItems.cs index 99526e92ca..f658ff8553 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.OnlyHaveUniqueItems.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.OnlyHaveUniqueItems.cs @@ -202,7 +202,8 @@ public void When_a_collection_contains_multiple_duplicates_on_different_properti } [Fact] - public void When_asserting_with_a_predicate_a_collection_to_only_have_unique_items_but_collection_is_null_it_should_throw() + public void + When_asserting_with_a_predicate_a_collection_to_only_have_unique_items_but_collection_is_null_it_should_throw() { // Arrange IEnumerable collection = null; diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.Satisfy.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.Satisfy.cs index 0c4e5647d7..0a8be1f50c 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.Satisfy.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.Satisfy.cs @@ -19,7 +19,7 @@ public class Satisfy public void When_collection_element_at_each_position_matches_predicate_at_same_position_should_not_throw() { // Arrange - var collection = new int[] { 1, 2, 3 }; + var collection = new[] { 1, 2, 3 }; // Act Action act = () => collection.Should().Satisfy( @@ -35,7 +35,7 @@ public void When_collection_element_at_each_position_matches_predicate_at_same_p public void When_collection_element_at_each_position_matches_predicate_at_reverse_position_should_not_throw() { // Arrange - var collection = new int[] { 1, 2, 3 }; + var collection = new[] { 1, 2, 3 }; // Act Action act = () => collection.Should().Satisfy( @@ -51,7 +51,7 @@ public void When_collection_element_at_each_position_matches_predicate_at_revers public void When_one_element_does_not_have_matching_predicate_Satisfy_should_throw() { // Arrange - var collection = new int[] { 1, 2 }; + var collection = new[] { 1, 2 }; // Act Action act = () => collection.Should().Satisfy( @@ -61,16 +61,17 @@ public void When_one_element_does_not_have_matching_predicate_Satisfy_should_thr // Assert act.Should().Throw().WithMessage( -@"Expected collection to satisfy all predicates, but: + @"Expected collection to satisfy all predicates, but: *The following predicates did not have matching elements: *(element == 3)"); } [Fact] - public void When_some_predicates_have_multiple_matching_elements_and_most_restricitve_predicates_are_last_should_not_throw() + public void + When_some_predicates_have_multiple_matching_elements_and_most_restricitve_predicates_are_last_should_not_throw() { // Arrange - var collection = new int[] { 1, 2, 3, 4 }; + var collection = new[] { 1, 2, 3, 4 }; // Act Action act = () => collection.Should().Satisfy( @@ -84,10 +85,11 @@ public void When_some_predicates_have_multiple_matching_elements_and_most_restri } [Fact] - public void When_some_predicates_have_multiple_matching_elements_and_most_restricitve_predicates_are_first_should_not_throw() + public void + When_some_predicates_have_multiple_matching_elements_and_most_restricitve_predicates_are_first_should_not_throw() { // Arrange - var collection = new int[] { 1, 2, 3, 4 }; + var collection = new[] { 1, 2, 3, 4 }; // Act Action act = () => collection.Should().Satisfy( @@ -104,7 +106,7 @@ public void When_some_predicates_have_multiple_matching_elements_and_most_restri public void When_second_predicate_matches_first_and_last_element_and_solution_exists_should_not_throw() { // Arrange - var collection = new int[] { 1, 2, 3 }; + var collection = new[] { 1, 2, 3 }; // Act Action act = () => collection.Should().Satisfy( @@ -117,7 +119,8 @@ public void When_second_predicate_matches_first_and_last_element_and_solution_ex } [Fact] - public void When_assertion_fails_then_failure_message_must_contain_predicates_without_matching_elements_and_elements_without_matching_predicates() + public void + When_assertion_fails_then_failure_message_must_contain_predicates_without_matching_elements_and_elements_without_matching_predicates() { // Arrange IEnumerable collection = new[] @@ -132,15 +135,15 @@ public void When_assertion_fails_then_failure_message_must_contain_predicates_wi Action act = () => collection.Should().Satisfy( new Expression>[] { - element => element.Text == "four" && element.Number == 4, - element => element.Text == "two" && element.Number == 2, + element => element.Text == "four" && element.Number == 4, + element => element.Text == "two" && element.Number == 2, }, because: "we want to test formatting ({0})", becauseArgs: "args"); // Assert act.Should().Throw().WithMessage( -@"Expected collection to satisfy all predicates because we want to test formatting (args), but: + @"Expected collection to satisfy all predicates because we want to test formatting (args), but: *The following predicates did not have matching elements: *(element.Text == ""two"") AndAlso (element.Number == 2) *The following elements did not match any predicate: @@ -187,6 +190,7 @@ public void When_asserting_collection_which_is_null_should_throw() Action act = () => { using var _ = new AssertionScope(); + collection.Should().Satisfy( new Expression>[] { @@ -235,7 +239,7 @@ public void When_elements_are_integers_assertion_fails_then_failure_message_must // Assert act.Should().Throw().WithMessage( -@"Expected collection to satisfy all predicates, but: + @"Expected collection to satisfy all predicates, but: *The following elements did not match any predicate: *Index: 0, Element: 1 *Index: 2, Element: 3"); diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.SatisfyRespectively.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.SatisfyRespectively.cs index 2f59f2a5e8..a905e8a8e6 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.SatisfyRespectively.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.SatisfyRespectively.cs @@ -52,6 +52,7 @@ public void When_collection_which_is_asserting_against_inspectors_is_null_it_sho Action act = () => { using var _ = new AssertionScope(); + collection.Should().SatisfyRespectively( new Action[] { x => x.Should().Be(1) }, "because we want to test the failure {0}", "message"); }; @@ -110,18 +111,19 @@ public void When_asserting_collection_does_not_satisfy_any_inspector_it_should_t Action act = () => customers.Should().SatisfyRespectively( new Action[] { - customer => - { - customer.Age.Should().BeLessThan(21); - customer.Items.Should().SatisfyRespectively( - item => item.Should().Be(2), - item => item.Should().Be(1)); - }, - customer => - { - customer.Age.Should().BeLessThan(22); - customer.Items.Should().SatisfyRespectively(item => item.Should().Be(2)); - } + customer => + { + customer.Age.Should().BeLessThan(21); + + customer.Items.Should().SatisfyRespectively( + item => item.Should().Be(2), + item => item.Should().Be(1)); + }, + customer => + { + customer.Age.Should().BeLessThan(22); + customer.Items.Should().SatisfyRespectively(item => item.Should().Be(2)); + } }, "because we want to test {0}", "nested assertions"); // Assert @@ -188,7 +190,7 @@ public void When_inspectors_count_does_not_equal_asserting_collection_length_it_ private class Customer { - private string PrivateProperty { get; set; } + private string PrivateProperty { get; } protected string ProtectedProperty { get; set; } diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.StartWith.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.StartWith.cs index 13522b01fd..d39342f3d1 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.StartWith.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.StartWith.cs @@ -70,13 +70,15 @@ public void When_collection_does_not_start_with_a_specific_element_in_a_sequence } [Fact] - public void When_collection_does_not_start_with_a_specific_element_in_a_sequence_using_custom_equality_comparison_it_should_throw() + public void + When_collection_does_not_start_with_a_specific_element_in_a_sequence_using_custom_equality_comparison_it_should_throw() { // Arrange var collection = new[] { "john", "bill", "jane", "mike" }; // Act - Action act = () => collection.Should().StartWith(new[] { "john", "ryan", "jane" }, (s1, s2) => string.Equals(s1, s2, StringComparison.Ordinal), "of some reason"); + Action act = () => collection.Should().StartWith(new[] { "john", "ryan", "jane" }, + (s1, s2) => string.Equals(s1, s2, StringComparison.Ordinal), "of some reason"); // Assert act.Should().Throw().WithMessage( @@ -110,13 +112,15 @@ public void When_collection_starts_with_the_specific_sequence_of_elements_it_sho } [Fact] - public void When_collection_starts_with_the_specific_sequence_of_elements_using_custom_equality_comparison_it_should_not_throw() + public void + When_collection_starts_with_the_specific_sequence_of_elements_using_custom_equality_comparison_it_should_not_throw() { // Arrange var collection = new[] { "john", "bill", "jane", "mike" }; // Act - Action act = () => collection.Should().StartWith(new[] { "JoHn", "bIlL" }, (s1, s2) => string.Equals(s1, s2, StringComparison.OrdinalIgnoreCase)); + Action act = () => collection.Should().StartWith(new[] { "JoHn", "bIlL" }, + (s1, s2) => string.Equals(s1, s2, StringComparison.OrdinalIgnoreCase)); // Assert act.Should().NotThrow(); @@ -175,13 +179,15 @@ public void When_collection_starts_with_the_specific_sequence_with_null_elements } [Fact] - public void When_collection_starts_with_the_specific_sequence_with_null_elements_using_custom_equality_comparison_it_should_not_throw() + public void + When_collection_starts_with_the_specific_sequence_with_null_elements_using_custom_equality_comparison_it_should_not_throw() { // Arrange var collection = new[] { null, "john", null, "bill", "jane", "mike" }; // Act - Action act = () => collection.Should().StartWith(new[] { null, "JoHn", null, "bIlL" }, (s1, s2) => string.Equals(s1, s2, StringComparison.OrdinalIgnoreCase)); + Action act = () => collection.Should().StartWith(new[] { null, "JoHn", null, "bIlL" }, + (s1, s2) => string.Equals(s1, s2, StringComparison.OrdinalIgnoreCase)); // Assert act.Should().NotThrow(); diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.cs index 9703c7f91f..cfc7921940 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.cs @@ -75,7 +75,8 @@ public void When_the_collection_is_not_ordered_according_to_the_subsequent_ascen } [Fact] - public void When_the_collection_is_ordered_according_to_the_subsequent_ascending_assertion_with_comparer_it_should_succeed() + public void + When_the_collection_is_ordered_according_to_the_subsequent_ascending_assertion_with_comparer_it_should_succeed() { // Arrange var collection = new[] @@ -166,7 +167,8 @@ public void When_the_collection_is_not_ordered_according_to_the_subsequent_desce } [Fact] - public void When_the_collection_is_ordered_according_to_the_subsequent_descending_assertion_with_comparer_it_should_succeed() + public void + When_the_collection_is_ordered_according_to_the_subsequent_descending_assertion_with_comparer_it_should_succeed() { // Arrange var collection = new[] @@ -316,7 +318,6 @@ public IEnumerator GetEnumerator() internal class TrackingEnumerator : IEnumerator { private readonly int[] values; - private int loopCount; private int index; public TrackingEnumerator(int[] values) @@ -326,14 +327,11 @@ public TrackingEnumerator(int[] values) this.values = values; } - public int LoopCount - { - get { return loopCount; } - } + public int LoopCount { get; private set; } public void IncreaseEnumerationCount() { - loopCount++; + LoopCount++; } public bool MoveNext() diff --git a/Tests/FluentAssertions.Specs/Collections/Data/DataColumnCollectionAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Collections/Data/DataColumnCollectionAssertionSpecs.cs index 7a18ceed74..e59f3e6979 100644 --- a/Tests/FluentAssertions.Specs/Collections/Data/DataColumnCollectionAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Collections/Data/DataColumnCollectionAssertionSpecs.cs @@ -2,11 +2,6 @@ using System.Collections.Generic; using System.Data; using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using FluentAssertions.Execution; - using Xunit; using Xunit.Sdk; @@ -17,7 +12,7 @@ public static class DataColumnCollectionAssertionSpecs public class BeSameAs { [Fact] - public void When_references_are_the_same_it_should_succeed() + public void Succeeds_for_references_to_the_same_object() { // Arrange var dataTable = new DataTable("Test"); @@ -30,7 +25,7 @@ public void When_references_are_the_same_it_should_succeed() } [Fact] - public void When_references_are_different_it_should_fail() + public void Throws_for_different_references() { // Arrange var dataTable1 = new DataTable("Test1"); diff --git a/Tests/FluentAssertions.Specs/Collections/Data/DataRowCollectionAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Collections/Data/DataRowCollectionAssertionSpecs.cs index a12d7beaf3..6780b8a2c5 100644 --- a/Tests/FluentAssertions.Specs/Collections/Data/DataRowCollectionAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Collections/Data/DataRowCollectionAssertionSpecs.cs @@ -1,13 +1,7 @@ using System; using System.Collections.Generic; using System.Data; -using System.Globalization; using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using FluentAssertions.Execution; - using Xunit; using Xunit.Sdk; @@ -456,9 +450,14 @@ public void When_collection_contains_equivalent_row_it_should_succeed() dataTable.Columns.Add("Flag", typeof(bool)); dataTable.Columns.Add("Timestamp", typeof(DateTime)); - dataTable.Rows.Add(new Guid("6f460c1a-755d-d8e4-ad67-65d5f519dbc8"), "1851925803", 2137491580, true, new DateTime(638898932425580731)); - dataTable.Rows.Add(new Guid("8286d046-9740-a3e4-95cf-ff46699c73c4"), "607156385", 1321446349, true, new DateTime(641752306337096884)); - dataTable.Rows.Add(new Guid("95c69371-b924-6fe3-7c38-98b7dd200bc1"), "1509870614", 505401118, true, new DateTime(623130841631129390)); + dataTable.Rows.Add(new Guid("6f460c1a-755d-d8e4-ad67-65d5f519dbc8"), "1851925803", 2137491580, true, + new DateTime(638898932425580731)); + + dataTable.Rows.Add(new Guid("8286d046-9740-a3e4-95cf-ff46699c73c4"), "607156385", 1321446349, true, + new DateTime(641752306337096884)); + + dataTable.Rows.Add(new Guid("95c69371-b924-6fe3-7c38-98b7dd200bc1"), "1509870614", 505401118, true, + new DateTime(623130841631129390)); var subjectTable = new DataTable(); @@ -468,7 +467,8 @@ public void When_collection_contains_equivalent_row_it_should_succeed() subjectTable.Columns.Add("Flag", typeof(bool)); subjectTable.Columns.Add("Timestamp", typeof(DateTime)); - subjectTable.Rows.Add(new Guid("95c69371-b924-6fe3-7c38-98b7dd200bc1"), "1509870614", 505401118, true, new DateTime(623130841631129390)); + subjectTable.Rows.Add(new Guid("95c69371-b924-6fe3-7c38-98b7dd200bc1"), "1509870614", 505401118, true, + new DateTime(623130841631129390)); var subjectRow = subjectTable.Rows[0]; @@ -488,9 +488,14 @@ public void When_collection_does_not_contain_equivalent_row_it_should_fail() dataTable.Columns.Add("Flag", typeof(bool)); dataTable.Columns.Add("Timestamp", typeof(DateTime)); - dataTable.Rows.Add(new Guid("8286d046-9740-a3e4-95cf-ff46699c73c4"), "607156385", 1321446349, true, new DateTime(641752306337096884)); - dataTable.Rows.Add(new Guid("95c69371-b924-6fe3-7c38-98b7dd200bc1"), "1509870614", 505401118, true, new DateTime(623130841631129390)); - dataTable.Rows.Add(new Guid("a905569d-db07-3ae3-63a0-322750a4a3bd"), "265101196", 1836839534, true, new DateTime(625984215542645543)); + dataTable.Rows.Add(new Guid("8286d046-9740-a3e4-95cf-ff46699c73c4"), "607156385", 1321446349, true, + new DateTime(641752306337096884)); + + dataTable.Rows.Add(new Guid("95c69371-b924-6fe3-7c38-98b7dd200bc1"), "1509870614", 505401118, true, + new DateTime(623130841631129390)); + + dataTable.Rows.Add(new Guid("a905569d-db07-3ae3-63a0-322750a4a3bd"), "265101196", 1836839534, true, + new DateTime(625984215542645543)); var subjectTable = new DataTable(); @@ -500,7 +505,8 @@ public void When_collection_does_not_contain_equivalent_row_it_should_fail() subjectTable.Columns.Add("Flag", typeof(bool)); subjectTable.Columns.Add("Timestamp", typeof(DateTime)); - subjectTable.Rows.Add(new Guid("bc4519c8-fdeb-06e2-4a08-cc98c4273aba"), "1167815425", 1020794303, true, new DateTime(628837589454161696)); + subjectTable.Rows.Add(new Guid("bc4519c8-fdeb-06e2-4a08-cc98c4273aba"), "1167815425", 1020794303, true, + new DateTime(628837589454161696)); var subjectRow = subjectTable.Rows[0]; @@ -546,9 +552,14 @@ public void When_collection_contains_equivalent_row_it_should_fail() dataTable.Columns.Add("Flag", typeof(bool)); dataTable.Columns.Add("Timestamp", typeof(DateTime)); - dataTable.Rows.Add(new Guid("8286d046-9740-a3e4-95cf-ff46699c73c4"), "607156385", 1321446349, true, new DateTime(641752306337096884)); - dataTable.Rows.Add(new Guid("95c69371-b924-6fe3-7c38-98b7dd200bc1"), "1509870614", 505401118, true, new DateTime(623130841631129390)); - dataTable.Rows.Add(new Guid("a905569d-db07-3ae3-63a0-322750a4a3bd"), "265101196", 1836839534, true, new DateTime(625984215542645543)); + dataTable.Rows.Add(new Guid("8286d046-9740-a3e4-95cf-ff46699c73c4"), "607156385", 1321446349, true, + new DateTime(641752306337096884)); + + dataTable.Rows.Add(new Guid("95c69371-b924-6fe3-7c38-98b7dd200bc1"), "1509870614", 505401118, true, + new DateTime(623130841631129390)); + + dataTable.Rows.Add(new Guid("a905569d-db07-3ae3-63a0-322750a4a3bd"), "265101196", 1836839534, true, + new DateTime(625984215542645543)); var subjectTable = new DataTable(); @@ -558,7 +569,8 @@ public void When_collection_contains_equivalent_row_it_should_fail() subjectTable.Columns.Add("Flag", typeof(bool)); subjectTable.Columns.Add("Timestamp", typeof(DateTime)); - subjectTable.Rows.Add(new Guid("95c69371-b924-6fe3-7c38-98b7dd200bc1"), "1509870614", 505401118, true, new DateTime(623130841631129390)); + subjectTable.Rows.Add(new Guid("95c69371-b924-6fe3-7c38-98b7dd200bc1"), "1509870614", 505401118, true, + new DateTime(623130841631129390)); var subjectRow = subjectTable.Rows[0]; @@ -584,9 +596,14 @@ public void When_collection_does_not_contain_equivalent_row_it_should_succeed() dataTable.Columns.Add("Flag", typeof(bool)); dataTable.Columns.Add("Timestamp", typeof(DateTime)); - dataTable.Rows.Add(new Guid("8286d046-9740-a3e4-95cf-ff46699c73c4"), "607156385", 1321446349, true, new DateTime(641752306337096884)); - dataTable.Rows.Add(new Guid("95c69371-b924-6fe3-7c38-98b7dd200bc1"), "1509870614", 505401118, true, new DateTime(623130841631129390)); - dataTable.Rows.Add(new Guid("a905569d-db07-3ae3-63a0-322750a4a3bd"), "265101196", 1836839534, true, new DateTime(625984215542645543)); + dataTable.Rows.Add(new Guid("8286d046-9740-a3e4-95cf-ff46699c73c4"), "607156385", 1321446349, true, + new DateTime(641752306337096884)); + + dataTable.Rows.Add(new Guid("95c69371-b924-6fe3-7c38-98b7dd200bc1"), "1509870614", 505401118, true, + new DateTime(623130841631129390)); + + dataTable.Rows.Add(new Guid("a905569d-db07-3ae3-63a0-322750a4a3bd"), "265101196", 1836839534, true, + new DateTime(625984215542645543)); var subjectTable = new DataTable(); @@ -596,7 +613,8 @@ public void When_collection_does_not_contain_equivalent_row_it_should_succeed() subjectTable.Columns.Add("Flag", typeof(bool)); subjectTable.Columns.Add("Timestamp", typeof(DateTime)); - subjectTable.Rows.Add(new Guid("bc4519c8-fdeb-06e2-4a08-cc98c4273aba"), "1167815425", 1020794303, true, new DateTime(628837589454161696)); + subjectTable.Rows.Add(new Guid("bc4519c8-fdeb-06e2-4a08-cc98c4273aba"), "1167815425", 1020794303, true, + new DateTime(628837589454161696)); var subjectRow = subjectTable.Rows[0]; diff --git a/Tests/FluentAssertions.Specs/Collections/Data/DataTableCollectionAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Collections/Data/DataTableCollectionAssertionSpecs.cs index ca0d9debff..c33decc33b 100644 --- a/Tests/FluentAssertions.Specs/Collections/Data/DataTableCollectionAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Collections/Data/DataTableCollectionAssertionSpecs.cs @@ -2,11 +2,6 @@ using System.Collections.Generic; using System.Data; using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using FluentAssertions.Execution; - using Xunit; using Xunit.Sdk; @@ -513,7 +508,7 @@ public void When_collection_is_compared_with_typed_collection_with_same_number_o // Act Action action = () => genericDataTableCollection.Should().NotHaveSameCount(secondDataSet.Tables, - because: "we {0}", "care"); + because: "we {0}", "care"); // Assert action.Should().Throw().WithMessage( diff --git a/Tests/FluentAssertions.Specs/Collections/GenericCollectionAssertionOfStringSpecs.AllSatisfy.cs b/Tests/FluentAssertions.Specs/Collections/GenericCollectionAssertionOfStringSpecs.AllSatisfy.cs index 3b8b9bca12..aefdfd2f3d 100644 --- a/Tests/FluentAssertions.Specs/Collections/GenericCollectionAssertionOfStringSpecs.AllSatisfy.cs +++ b/Tests/FluentAssertions.Specs/Collections/GenericCollectionAssertionOfStringSpecs.AllSatisfy.cs @@ -15,7 +15,7 @@ public class AllSatisfy public void All_items_satisfying_inspector_should_succeed() { // Arrange - string[] collection = new[] { "John", "John" }; + string[] collection = { "John", "John" }; // Act / Assert collection.Should().AllSatisfy(value => value.Should().Be("John")); @@ -25,7 +25,7 @@ public void All_items_satisfying_inspector_should_succeed() public void Any_items_not_satisfying_inspector_should_throw() { // Arrange - string[] collection = new[] { "Jack", "Jessica" }; + string[] collection = { "Jack", "Jessica" }; // Act Action act = () => collection.Should() diff --git a/Tests/FluentAssertions.Specs/Collections/GenericCollectionAssertionOfStringSpecs.cs b/Tests/FluentAssertions.Specs/Collections/GenericCollectionAssertionOfStringSpecs.cs index 5d341eec6f..91fe66cc84 100644 --- a/Tests/FluentAssertions.Specs/Collections/GenericCollectionAssertionOfStringSpecs.cs +++ b/Tests/FluentAssertions.Specs/Collections/GenericCollectionAssertionOfStringSpecs.cs @@ -843,7 +843,7 @@ public void When_asserting_the_items_in_an_two_non_intersecting_collections_inte // Assert action.Should().Throw() .WithMessage("Expected collection to intersect with {\"four\", \"five\"} because they should share items," + - " but {\"one\", \"two\", \"three\"} does not contain any shared items."); + " but {\"one\", \"two\", \"three\"} does not contain any shared items."); } [Fact] @@ -1465,8 +1465,8 @@ public void When_two_collections_contain_the_same_elements_it_should_treat_them_ public void When_two_arrays_contain_the_same_elements_it_should_treat_them_as_equivalent() { // Arrange - string[] array1 = new[] { "one", "two", "three" }; - string[] array2 = new[] { "three", "two", "one" }; + string[] array1 = { "one", "two", "three" }; + string[] array2 = { "three", "two", "one" }; // Act / Assert array1.Should().BeEquivalentTo(array2); @@ -1697,7 +1697,7 @@ from method in methodInfo public void When_collection_contains_a_match_it_should_not_throw() { // Arrange - IEnumerable collection = new string[] { "build succeded", "test failed" }; + IEnumerable collection = new[] { "build succeded", "test failed" }; // Act Action action = () => collection.Should().ContainMatch("* failed"); @@ -1710,7 +1710,7 @@ public void When_collection_contains_a_match_it_should_not_throw() public void When_collection_contains_multiple_matches_it_should_not_throw() { // Arrange - IEnumerable collection = new string[] { "build succeded", "test failed", "pack failed" }; + IEnumerable collection = new[] { "build succeded", "test failed", "pack failed" }; // Act Action action = () => collection.Should().ContainMatch("* failed"); @@ -1723,7 +1723,7 @@ public void When_collection_contains_multiple_matches_it_should_not_throw() public void When_collection_contains_multiple_matches_which_should_throw() { // Arrange - IEnumerable collection = new string[] { "build succeded", "test failed", "pack failed" }; + IEnumerable collection = new[] { "build succeded", "test failed", "pack failed" }; // Act Action action = () => @@ -1741,21 +1741,22 @@ public void When_collection_contains_multiple_matches_which_should_throw() public void When_collection_does_not_contain_a_match_it_should_throw() { // Arrange - IEnumerable collection = new string[] { "build succeded", "test failed" }; + IEnumerable collection = new[] { "build succeded", "test failed" }; // Act Action action = () => collection.Should().ContainMatch("* stopped", "because {0}", "we do"); // Assert action.Should().Throw() - .WithMessage("Expected collection {\"build succeded\", \"test failed\"} to contain a match of \"* stopped\" because we do."); + .WithMessage( + "Expected collection {\"build succeded\", \"test failed\"} to contain a match of \"* stopped\" because we do."); } [Fact] public void When_collection_contains_a_match_that_differs_in_casing_it_should_throw() { // Arrange - IEnumerable collection = new string[] { "build succeded", "test failed" }; + IEnumerable collection = new[] { "build succeded", "test failed" }; // Act Action action = () => collection.Should().ContainMatch("* Failed"); @@ -1801,14 +1802,15 @@ public void When_asserting_null_collection_for_match_it_should_throw() public void When_asserting_collection_to_have_null_match_it_should_throw() { // Arrange - IEnumerable collection = new string[] { "build succeded", "test failed" }; + IEnumerable collection = new[] { "build succeded", "test failed" }; // Act Action action = () => collection.Should().ContainMatch(null); // Assert action.Should().Throw() - .WithMessage("Cannot match strings in collection against . Provide a wildcard pattern or use the Contain method.*") + .WithMessage( + "Cannot match strings in collection against . Provide a wildcard pattern or use the Contain method.*") .WithParameterName("wildcardPattern"); } @@ -1816,14 +1818,15 @@ public void When_asserting_collection_to_have_null_match_it_should_throw() public void When_asserting_collection_to_have_empty_string_match_it_should_throw() { // Arrange - IEnumerable collection = new string[] { "build succeded", "test failed" }; + IEnumerable collection = new[] { "build succeded", "test failed" }; // Act Action action = () => collection.Should().ContainMatch(string.Empty); // Assert action.Should().Throw() - .WithMessage("Cannot match strings in collection against an empty string. Provide a wildcard pattern or use the Contain method.*") + .WithMessage( + "Cannot match strings in collection against an empty string. Provide a wildcard pattern or use the Contain method.*") .WithParameterName("wildcardPattern"); } @@ -1835,7 +1838,7 @@ public void When_asserting_collection_to_have_empty_string_match_it_should_throw public void When_collection_doesnt_contain_a_match_it_should_not_throw() { // Arrange - IEnumerable collection = new string[] { "build succeded", "test" }; + IEnumerable collection = new[] { "build succeded", "test" }; // Act Action action = () => collection.Should().NotContainMatch("* failed"); @@ -1848,7 +1851,7 @@ public void When_collection_doesnt_contain_a_match_it_should_not_throw() public void When_collection_doesnt_contain_multiple_matches_it_should_not_throw() { // Arrange - IEnumerable collection = new string[] { "build succeded", "test", "pack" }; + IEnumerable collection = new[] { "build succeded", "test", "pack" }; // Act Action action = () => collection.Should().NotContainMatch("* failed"); @@ -1861,35 +1864,37 @@ public void When_collection_doesnt_contain_multiple_matches_it_should_not_throw( public void When_collection_contains_a_match_it_should_throw() { // Arrange - IEnumerable collection = new string[] { "build succeded", "test failed" }; + IEnumerable collection = new[] { "build succeded", "test failed" }; // Act Action action = () => collection.Should().NotContainMatch("* failed", "because {0}", "it shouldn't"); // Assert action.Should().Throw() - .WithMessage("Did not expect collection {\"build succeded\", \"test failed\"} to contain a match of \"* failed\" because it shouldn't."); + .WithMessage( + "Did not expect collection {\"build succeded\", \"test failed\"} to contain a match of \"* failed\" because it shouldn't."); } [Fact] public void When_collection_contains_multiple_matches_it_should_throw() { // Arrange - IEnumerable collection = new string[] { "build failed", "test failed" }; + IEnumerable collection = new[] { "build failed", "test failed" }; // Act Action action = () => collection.Should().NotContainMatch("* failed", "because {0}", "it shouldn't"); // Assert action.Should().Throw() - .WithMessage("Did not expect collection {\"build failed\", \"test failed\"} to contain a match of \"* failed\" because it shouldn't."); + .WithMessage( + "Did not expect collection {\"build failed\", \"test failed\"} to contain a match of \"* failed\" because it shouldn't."); } [Fact] public void When_collection_contains_a_match_with_different_casing_it_should_not_throw() { // Arrange - IEnumerable collection = new string[] { "build succeded", "test failed" }; + IEnumerable collection = new[] { "build succeded", "test failed" }; // Act Action action = () => collection.Should().NotContainMatch("* Failed"); @@ -1902,14 +1907,15 @@ public void When_collection_contains_a_match_with_different_casing_it_should_not public void When_asserting_collection_to_not_have_null_match_it_should_throw() { // Arrange - IEnumerable collection = new string[] { "build succeded", "test failed" }; + IEnumerable collection = new[] { "build succeded", "test failed" }; // Act Action action = () => collection.Should().NotContainMatch(null); // Assert action.Should().Throw() - .WithMessage("Cannot match strings in collection against . Provide a wildcard pattern or use the NotContain method.*") + .WithMessage( + "Cannot match strings in collection against . Provide a wildcard pattern or use the NotContain method.*") .WithParameterName("wildcardPattern"); } @@ -1917,14 +1923,15 @@ public void When_asserting_collection_to_not_have_null_match_it_should_throw() public void When_asserting_collection_to_not_have_empty_string_match_it_should_throw() { // Arrange - IEnumerable collection = new string[] { "build succeded", "test failed" }; + IEnumerable collection = new[] { "build succeded", "test failed" }; // Act Action action = () => collection.Should().NotContainMatch(string.Empty); // Assert action.Should().Throw() - .WithMessage("Cannot match strings in collection against an empty string. Provide a wildcard pattern or use the NotContain method.*") + .WithMessage( + "Cannot match strings in collection against an empty string. Provide a wildcard pattern or use the NotContain method.*") .WithParameterName("wildcardPattern"); } @@ -1954,7 +1961,7 @@ public void When_asserting_null_collection_to_not_have_null_match_it_should_thro public void When_string_collection_satisfies_all_inspectors_it_should_succeed() { // Arrange - string[] collection = new[] { "John", "Jane" }; + string[] collection = { "John", "Jane" }; // Act / Assert collection.Should().SatisfyRespectively( @@ -1967,7 +1974,7 @@ public void When_string_collection_satisfies_all_inspectors_it_should_succeed() public void When_string_collection_does_not_satisfy_all_inspectors_it_should_throw() { // Arrange - string[] collection = new[] { "Jack", "Jessica" }; + string[] collection = { "Jack", "Jessica" }; // Act Action act = () => collection.Should().SatisfyRespectively(new Action[] @@ -1995,6 +2002,8 @@ public void When_accidentally_using_equals_it_should_throw_a_helpful_error() Action action = () => someCollection.Should().Equals(someCollection); // Assert - action.Should().Throw().WithMessage("Equals is not part of Fluent Assertions. Did you mean BeSameAs(), Equal(), or BeEquivalentTo() instead?"); + action.Should().Throw() + .WithMessage( + "Equals is not part of Fluent Assertions. Did you mean BeSameAs(), Equal(), or BeEquivalentTo() instead?"); } } diff --git a/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs index c3d3ca3fae..5f08521359 100644 --- a/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs @@ -171,7 +171,8 @@ public void // Assert action.Should().Throw() - .WithMessage("Expected dictionary to contain 4 item(s) because we want to test the failure message, but found 3: {[1] = \"One\", [2] = \"Two\", [3] = \"Three\"}."); + .WithMessage( + "Expected dictionary to contain 4 item(s) because we want to test the failure message, but found 3: {[1] = \"One\", [2] = \"Two\", [3] = \"Three\"}."); } [Fact] @@ -320,7 +321,8 @@ public void When_dictionary_count_is_same_than_and_dictionary_is_null_it_should_ Action act = () => dictionary.Should().NotHaveCount(1, "we want to test the behaviour with a null subject"); // Assert - act.Should().Throw().WithMessage("*not contain*1*we want to test the behaviour with a null subject*found *"); + act.Should().Throw() + .WithMessage("*not contain*1*we want to test the behaviour with a null subject*found *"); } } @@ -371,11 +373,13 @@ public void When_dictionary_has_a_count_greater_than_the_number_of_items_it_shou }; // Act - Action action = () => dictionary.Should().HaveCountGreaterThan(3, "because we want to test the failure {0}", "message"); + Action action = () => + dictionary.Should().HaveCountGreaterThan(3, "because we want to test the failure {0}", "message"); // Assert action.Should().Throw() - .WithMessage("Expected dictionary to contain more than 3 item(s) because we want to test the failure message, but found 3: {[1] = \"One\", [2] = \"Two\", [3] = \"Three\"}."); + .WithMessage( + "Expected dictionary to contain more than 3 item(s) because we want to test the failure message, but found 3: {[1] = \"One\", [2] = \"Two\", [3] = \"Three\"}."); } [Fact] @@ -388,7 +392,8 @@ public void When_dictionary_count_is_greater_than_and_dictionary_is_null_it_shou Action act = () => dictionary.Should().HaveCountGreaterThan(1, "we want to test the behaviour with a null subject"); // Assert - act.Should().Throw().WithMessage("*more than*1*we want to test the behaviour with a null subject*found *"); + act.Should().Throw() + .WithMessage("*more than*1*we want to test the behaviour with a null subject*found *"); } } @@ -428,7 +433,8 @@ public void Should_fail_when_asserting_dictionary_has_a_count_greater_than_or_eq } [Fact] - public void When_dictionary_has_a_count_greater_than_or_equal_to_the_number_of_items_it_should_fail_with_descriptive_message_() + public void + When_dictionary_has_a_count_greater_than_or_equal_to_the_number_of_items_it_should_fail_with_descriptive_message_() { // Arrange var dictionary = new Dictionary @@ -439,11 +445,13 @@ public void When_dictionary_has_a_count_greater_than_or_equal_to_the_number_of_i }; // Act - Action action = () => dictionary.Should().HaveCountGreaterThanOrEqualTo(4, "because we want to test the failure {0}", "message"); + Action action = () => + dictionary.Should().HaveCountGreaterThanOrEqualTo(4, "because we want to test the failure {0}", "message"); // Assert action.Should().Throw() - .WithMessage("Expected dictionary to contain at least 4 item(s) because we want to test the failure message, but found 3: {[1] = \"One\", [2] = \"Two\", [3] = \"Three\"}."); + .WithMessage( + "Expected dictionary to contain at least 4 item(s) because we want to test the failure message, but found 3: {[1] = \"One\", [2] = \"Two\", [3] = \"Three\"}."); } [Fact] @@ -453,10 +461,12 @@ public void When_dictionary_count_is_greater_than_or_equal_to_and_dictionary_is_ Dictionary dictionary = null; // Act - Action act = () => dictionary.Should().HaveCountGreaterThanOrEqualTo(1, "we want to test the behaviour with a null subject"); + Action act = () => + dictionary.Should().HaveCountGreaterThanOrEqualTo(1, "we want to test the behaviour with a null subject"); // Assert - act.Should().Throw().WithMessage("*at least*1*we want to test the behaviour with a null subject*found *"); + act.Should().Throw() + .WithMessage("*at least*1*we want to test the behaviour with a null subject*found *"); } } @@ -511,7 +521,8 @@ public void When_dictionary_has_a_count_less_than_the_number_of_items_it_should_ // Assert action.Should().Throw() - .WithMessage("Expected dictionary to contain fewer than 3 item(s) because we want to test the failure message, but found 3: {[1] = \"One\", [2] = \"Two\", [3] = \"Three\"}."); + .WithMessage( + "Expected dictionary to contain fewer than 3 item(s) because we want to test the failure message, but found 3: {[1] = \"One\", [2] = \"Two\", [3] = \"Three\"}."); } [Fact] @@ -524,7 +535,8 @@ public void When_dictionary_count_is_less_than_and_dictionary_is_null_it_should_ Action act = () => dictionary.Should().HaveCountLessThan(1, "we want to test the behaviour with a null subject"); // Assert - act.Should().Throw().WithMessage("*fewer than*1*we want to test the behaviour with a null subject*found *"); + act.Should().Throw() + .WithMessage("*fewer than*1*we want to test the behaviour with a null subject*found *"); } } @@ -564,7 +576,8 @@ public void Should_fail_when_asserting_dictionary_has_a_count_less_than_or_equal } [Fact] - public void When_dictionary_has_a_count_less_than_or_equal_to_the_number_of_items_it_should_fail_with_descriptive_message_() + public void + When_dictionary_has_a_count_less_than_or_equal_to_the_number_of_items_it_should_fail_with_descriptive_message_() { // Arrange var dictionary = new Dictionary @@ -575,11 +588,13 @@ public void When_dictionary_has_a_count_less_than_or_equal_to_the_number_of_item }; // Act - Action action = () => dictionary.Should().HaveCountLessThanOrEqualTo(2, "because we want to test the failure {0}", "message"); + Action action = () => + dictionary.Should().HaveCountLessThanOrEqualTo(2, "because we want to test the failure {0}", "message"); // Assert action.Should().Throw() - .WithMessage("Expected dictionary to contain at most 2 item(s) because we want to test the failure message, but found 3: {[1] = \"One\", [2] = \"Two\", [3] = \"Three\"}."); + .WithMessage( + "Expected dictionary to contain at most 2 item(s) because we want to test the failure message, but found 3: {[1] = \"One\", [2] = \"Two\", [3] = \"Three\"}."); } [Fact] @@ -589,10 +604,12 @@ public void When_dictionary_count_is_less_than_or_equal_to_and_dictionary_is_nul Dictionary dictionary = null; // Act - Action act = () => dictionary.Should().HaveCountLessThanOrEqualTo(1, "we want to test the behaviour with a null subject"); + Action act = () => + dictionary.Should().HaveCountLessThanOrEqualTo(1, "we want to test the behaviour with a null subject"); // Assert - act.Should().Throw().WithMessage("*at most*1*we want to test the behaviour with a null subject*found *"); + act.Should().Throw() + .WithMessage("*at most*1*we want to test the behaviour with a null subject*found *"); } } @@ -608,6 +625,7 @@ public void When_dictionary_and_collection_have_the_same_number_elements_it_shou [2] = "Two", [3] = "Three" }; + var collection = new[] { 4, 5, 6 }; // Act / Assert @@ -624,6 +642,7 @@ public void When_dictionary_and_collection_do_not_have_the_same_number_of_elemen [2] = "Two", [3] = "Three" }; + var collection = new[] { 4, 6 }; // Act @@ -644,6 +663,7 @@ public void When_comparing_item_counts_and_a_reason_is_specified_it_should_it_in [2] = "Two", [3] = "Three" }; + var collection = new[] { 4, 6 }; // Act @@ -680,6 +700,7 @@ public void When_asserting_dictionary_and_collection_have_same_count_against_a_n [2] = "Two", [3] = "Three" }; + int[] collection = null; // Act @@ -703,6 +724,7 @@ public void When_asserting_not_same_count_and_collections_have_different_number_ [2] = "Two", [3] = "Three" }; + var collection = new[] { 4, 6 }; // Act / Assert @@ -719,6 +741,7 @@ public void When_asserting_not_same_count_and_both_collections_have_the_same_num [2] = "Two", [3] = "Three" }; + var collection = new[] { 4, 5, 6 }; // Act @@ -739,6 +762,7 @@ public void When_comparing_not_same_item_counts_and_a_reason_is_specified_it_sho [2] = "Two", [3] = "Three" }; + var collection = new[] { 4, 5, 6 }; // Act @@ -775,6 +799,7 @@ public void When_asserting_dictionary_and_collection_to_not_have_same_count_agai [2] = "Two", [3] = "Three" }; + int[] collection = null; // Act @@ -786,7 +811,8 @@ public void When_asserting_dictionary_and_collection_to_not_have_same_count_agai } [Fact] - public void When_asserting_dictionary_and_collection_to_not_have_same_count_but_both_reference_the_same_object_it_should_throw() + public void + When_asserting_dictionary_and_collection_to_not_have_same_count_but_both_reference_the_same_object_it_should_throw() { // Arrange var dictionary = new Dictionary @@ -795,6 +821,7 @@ public void When_asserting_dictionary_and_collection_to_not_have_same_count_but_ [2] = "Two", [3] = "Three" }; + var collection = dictionary; // Act @@ -849,7 +876,8 @@ public void Should_fail_with_descriptive_message_when_asserting_dictionary_with_ // Assert act.Should().Throw() - .WithMessage("Expected dictionary to be empty because we want to test the failure message, but found {[1] = \"One\"}."); + .WithMessage( + "Expected dictionary to be empty because we want to test the failure message, but found {[1] = \"One\"}."); } [Fact] @@ -866,7 +894,6 @@ public void When_asserting_dictionary_with_items_is_not_empty_it_should_succeed( } #if !NET5_0_OR_GREATER - [Fact] public void When_asserting_dictionary_with_items_is_not_empty_it_should_enumerate_the_dictionary_only_once() { @@ -949,6 +976,7 @@ public void Should_succeed_when_asserting_dictionary_is_equal_to_the_same_dictio [1] = "One", [2] = "Two" }; + var dictionary2 = new Dictionary { [1] = "One", @@ -968,6 +996,7 @@ public void Should_succeed_when_asserting_dictionary_with_null_value_is_equal_to [1] = "One", [2] = null }; + var dictionary2 = new Dictionary { [1] = "One", @@ -987,6 +1016,7 @@ public void When_asserting_dictionaries_to_be_equal_but_subject_dictionary_misse [1] = "One", [2] = "Two" }; + var dictionary2 = new Dictionary { [1] = "One", @@ -1011,6 +1041,7 @@ public void When_asserting_dictionaries_to_be_equal_but_subject_dictionary_has_e [2] = "Two", [3] = "Three" }; + var dictionary2 = new Dictionary { [1] = "One", @@ -1034,6 +1065,7 @@ public void When_two_dictionaries_are_not_equal_by_values_it_should_throw_using_ [1] = "One", [2] = "Two" }; + var dictionary2 = new Dictionary { [1] = "One", @@ -1053,6 +1085,7 @@ public void When_asserting_dictionaries_to_be_equal_but_subject_dictionary_is_nu { // Arrange Dictionary dictionary1 = null; + var dictionary2 = new Dictionary { [1] = "One", @@ -1060,7 +1093,8 @@ public void When_asserting_dictionaries_to_be_equal_but_subject_dictionary_is_nu }; // Act - Action act = () => dictionary1.Should().Equal(dictionary2, "because we want to test the behaviour with a null subject"); + Action act = () => + dictionary1.Should().Equal(dictionary2, "because we want to test the behaviour with a null subject"); // Assert act.Should().Throw().WithMessage( @@ -1076,10 +1110,12 @@ public void When_asserting_dictionaries_to_be_equal_but_expected_dictionary_is_n [1] = "One", [2] = "Two" }; + Dictionary dictionary2 = null; // Act - Action act = () => dictionary1.Should().Equal(dictionary2, "because we want to test the behaviour with a null subject"); + Action act = () => + dictionary1.Should().Equal(dictionary2, "because we want to test the behaviour with a null subject"); // Assert act.Should().Throw() @@ -1092,6 +1128,7 @@ public void When_an_empty_dictionary_is_compared_for_equality_to_a_non_empty_dic { // Arrange var dictionary1 = new Dictionary(); + var dictionary2 = new Dictionary { [1] = "One", @@ -1118,6 +1155,7 @@ public void Should_succeed_when_asserting_dictionary_is_not_equal_to_a_dictionar [1] = "One", [2] = "Two" }; + var dictionary2 = new Dictionary { [1] = "One", @@ -1137,6 +1175,7 @@ public void Should_succeed_when_asserting_dictionary_is_not_equal_to_a_dictionar [1] = "One", [2] = null }; + var dictionary2 = new Dictionary { [1] = "One", @@ -1156,6 +1195,7 @@ public void When_two_equal_dictionaries_are_not_expected_to_be_equal_it_should_t [1] = "One", [2] = "Two" }; + var dictionary2 = new Dictionary { [1] = "One", @@ -1179,6 +1219,7 @@ public void When_two_equal_dictionaries_are_not_expected_to_be_equal_it_should_r [1] = "One", [2] = "Two" }; + var dictionary2 = new Dictionary { [1] = "One", @@ -1198,6 +1239,7 @@ public void When_asserting_dictionaries_not_to_be_equal_subject_but_dictionary_i { // Arrange Dictionary dictionary1 = null; + var dictionary2 = new Dictionary { [1] = "One", @@ -1222,6 +1264,7 @@ public void When_asserting_dictionaries_not_to_be_equal_but_expected_dictionary_ [1] = "One", [2] = "Two" }; + Dictionary dictionary2 = null; // Act @@ -1235,7 +1278,8 @@ public void When_asserting_dictionaries_not_to_be_equal_but_expected_dictionary_ } [Fact] - public void When_asserting_dictionaries_not_to_be_equal_subject_but_both_dictionaries_reference_the_same_object_it_should_throw() + public void + When_asserting_dictionaries_not_to_be_equal_subject_but_both_dictionaries_reference_the_same_object_it_should_throw() { // Arrange var dictionary1 = new Dictionary @@ -1243,6 +1287,7 @@ public void When_asserting_dictionaries_not_to_be_equal_subject_but_both_diction [1] = "One", [2] = "Two" }; + var dictionary2 = dictionary1; // Act @@ -1327,7 +1372,7 @@ public void When_the_requested_key_exists_it_should_allow_continuation_with_the_ // Arrange var dictionary = new Dictionary { - ["Key"] = new MyClass { SomeProperty = 3 } + ["Key"] = new() { SomeProperty = 3 } }; // Act @@ -1356,7 +1401,8 @@ public void When_a_dictionary_does_not_contain_a_list_of_keys_it_should_throw_wi } [Fact] - public void When_the_contents_of_a_dictionary_are_checked_against_an_empty_list_of_keys_it_should_throw_clear_explanation() + public void + When_the_contents_of_a_dictionary_are_checked_against_an_empty_list_of_keys_it_should_throw_clear_explanation() { // Arrange var dictionary = new Dictionary @@ -1366,7 +1412,7 @@ public void When_the_contents_of_a_dictionary_are_checked_against_an_empty_list_ }; // Act - Action act = () => dictionary.Should().ContainKeys(new int[0]); + Action act = () => dictionary.Should().ContainKeys(); // Assert act.Should().Throw().WithMessage( @@ -1480,7 +1526,8 @@ public void When_a_dictionary_contains_exactly_one_of_the_keys_it_should_throw_w } [Fact] - public void When_the_noncontents_of_a_dictionary_are_checked_against_an_empty_list_of_keys_it_should_throw_clear_explanation() + public void + When_the_noncontents_of_a_dictionary_are_checked_against_an_empty_list_of_keys_it_should_throw_clear_explanation() { // Arrange var dictionary = new Dictionary @@ -1490,7 +1537,7 @@ public void When_the_noncontents_of_a_dictionary_are_checked_against_an_empty_li }; // Act - Action act = () => dictionary.Should().NotContainKeys(new int[0]); + Action act = () => dictionary.Should().NotContainKeys(); // Assert act.Should().Throw().WithMessage( @@ -1498,7 +1545,8 @@ public void When_the_noncontents_of_a_dictionary_are_checked_against_an_empty_li } [Fact] - public void When_a_dictionary_checks_a_list_of_keys_not_to_be_present_it_will_honor_the_case_sensitive_equality_comparer_of_the_dictionary() + public void + When_a_dictionary_checks_a_list_of_keys_not_to_be_present_it_will_honor_the_case_sensitive_equality_comparer_of_the_dictionary() { // Arrange var dictionary = new Dictionary(StringComparer.Ordinal) @@ -1508,14 +1556,15 @@ public void When_a_dictionary_checks_a_list_of_keys_not_to_be_present_it_will_ho }; // Act - Action act = () => dictionary.Should().NotContainKeys(new[] { "One", "Two" }); + Action act = () => dictionary.Should().NotContainKeys("One", "Two"); // Assert act.Should().NotThrow(); } [Fact] - public void When_a_dictionary_checks_a_list_of_keys_not_to_be_present_it_will_honor_the_case_insensitive_equality_comparer_of_the_dictionary() + public void + When_a_dictionary_checks_a_list_of_keys_not_to_be_present_it_will_honor_the_case_insensitive_equality_comparer_of_the_dictionary() { // Arrange var dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase) @@ -1525,7 +1574,7 @@ public void When_a_dictionary_checks_a_list_of_keys_not_to_be_present_it_will_ho }; // Act - Action act = () => dictionary.Should().NotContainKeys(new[] { "One", "Two" }); + Action act = () => dictionary.Should().NotContainKeys("One", "Two"); // Assert act.Should().Throw(); @@ -1623,7 +1672,7 @@ public void When_dictionary_contains_expected_null_value_it_should_succeed() public void When_the_specified_value_exists_it_should_allow_continuation_using_that_value() { // Arrange - var myClass = new MyClass() + var myClass = new MyClass { SomeProperty = 0 }; @@ -1649,7 +1698,7 @@ public void When_multiple_matches_for_the_specified_value_exist_continuation_usi var dictionary = new Dictionary { [1] = myClass, - [2] = new MyClass { SomeProperty = 0 } + [2] = new() { SomeProperty = 0 } }; // Act @@ -1718,7 +1767,8 @@ public void When_a_dictionary_does_not_contain_a_number_of_values_it_should_thro } [Fact] - public void When_the_contents_of_a_dictionary_are_checked_against_an_empty_list_of_values_it_should_throw_clear_explanation() + public void + When_the_contents_of_a_dictionary_are_checked_against_an_empty_list_of_values_it_should_throw_clear_explanation() { // Arrange var dictionary = new Dictionary @@ -1728,7 +1778,7 @@ public void When_the_contents_of_a_dictionary_are_checked_against_an_empty_list_ }; // Act - Action act = () => dictionary.Should().ContainValues(new string[0]); + Action act = () => dictionary.Should().ContainValues(); // Assert act.Should().Throw().WithMessage( @@ -1842,7 +1892,8 @@ public void When_a_dictionary_contains_a_number_of_values_it_should_throw_with_c } [Fact] - public void When_the_noncontents_of_a_dictionary_are_checked_against_an_empty_list_of_values_it_should_throw_clear_explanation() + public void + When_the_noncontents_of_a_dictionary_are_checked_against_an_empty_list_of_values_it_should_throw_clear_explanation() { // Arrange var dictionary = new Dictionary @@ -1852,7 +1903,7 @@ public void When_the_noncontents_of_a_dictionary_are_checked_against_an_empty_li }; // Act - Action act = () => dictionary.Should().NotContainValues(new string[0]); + Action act = () => dictionary.Should().NotContainValues(); // Assert act.Should().Throw().WithMessage( @@ -1872,10 +1923,10 @@ public void Should_succeed_when_asserting_dictionary_contains_single_key_value_p [2] = "Two" }; - var keyValuePairs = new List>() - { - new KeyValuePair(1, "One") - }; + var keyValuePairs = new List> + { + new(1, "One") + }; // Act / Assert dictionary.Should().Contain(keyValuePairs); @@ -1910,11 +1961,11 @@ public void Should_succeed_when_asserting_dictionary_contains_multiple_key_value [2] = "Two" }; - var keyValuePairs = new List>() - { - new KeyValuePair(1, "One"), - new KeyValuePair(2, "Two") - }; + var keyValuePairs = new List> + { + new(1, "One"), + new(2, "Two") + }; // Act / Assert dictionary.Should().Contain(keyValuePairs); @@ -1930,11 +1981,11 @@ public void When_a_dictionary_does_not_contain_single_value_for_key_value_pairs_ [2] = "Two" }; - var keyValuePairs = new List>() - { - new KeyValuePair(1, "One"), - new KeyValuePair(2, "Three") - }; + var keyValuePairs = new List> + { + new(1, "One"), + new(2, "Three") + }; // Act Action act = () => dictionary.Should().Contain(keyValuePairs, "because {0}", "we do"); @@ -1945,7 +1996,8 @@ public void When_a_dictionary_does_not_contain_single_value_for_key_value_pairs_ } [Fact] - public void When_a_dictionary_does_not_contain_multiple_values_for_key_value_pairs_it_should_throw_with_clear_explanation() + public void + When_a_dictionary_does_not_contain_multiple_values_for_key_value_pairs_it_should_throw_with_clear_explanation() { // Arrange var dictionary = new Dictionary @@ -1954,11 +2006,11 @@ public void When_a_dictionary_does_not_contain_multiple_values_for_key_value_pai [2] = "Two" }; - var keyValuePairs = new List>() - { - new KeyValuePair(1, "Two"), - new KeyValuePair(2, "Three") - }; + var keyValuePairs = new List> + { + new(1, "Two"), + new(2, "Three") + }; // Act Action act = () => dictionary.Should().Contain(keyValuePairs, "because {0}", "we do"); @@ -1978,10 +2030,10 @@ public void When_a_dictionary_does_not_contain_single_key_for_key_value_pairs_it [2] = "Two" }; - var keyValuePairs = new List>() - { - new KeyValuePair(3, "Three") - }; + var keyValuePairs = new List> + { + new(3, "Three") + }; // Act Action act = () => dictionary.Should().Contain(keyValuePairs, "because {0}", "we do"); @@ -2001,12 +2053,12 @@ public void When_a_dictionary_does_not_contain_multiple_keys_for_key_value_pairs [2] = "Two" }; - var keyValuePairs = new List>() - { - new KeyValuePair(1, "One"), - new KeyValuePair(3, "Three"), - new KeyValuePair(4, "Four") - }; + var keyValuePairs = new List> + { + new(1, "One"), + new(3, "Three"), + new(4, "Four") + }; // Act Action act = () => dictionary.Should().Contain(keyValuePairs, "because {0}", "we do"); @@ -2021,11 +2073,12 @@ public void When_asserting_dictionary_contains_key_value_pairs_against_null_dict { // Arrange Dictionary dictionary = null; - List> keyValuePairs = new List>() - { - new KeyValuePair(1, "One"), - new KeyValuePair(1, "Two") - }; + + List> keyValuePairs = new() + { + new KeyValuePair(1, "One"), + new KeyValuePair(1, "Two") + }; // Act Action act = () => dictionary.Should().Contain(keyValuePairs, @@ -2045,10 +2098,12 @@ public void When_asserting_dictionary_contains_key_value_pairs_but_expected_key_ [1] = "One", [2] = "Two" }; - List> keyValuePairs = new List>(); + + List> keyValuePairs = new(); // Act - Action act = () => dictionary1.Should().Contain(keyValuePairs, "because we want to test the behaviour with an empty set of key/value pairs"); + Action act = () => dictionary1.Should().Contain(keyValuePairs, + "because we want to test the behaviour with an empty set of key/value pairs"); // Assert act.Should().Throw().WithMessage( @@ -2064,10 +2119,12 @@ public void When_asserting_dictionary_contains_key_value_pairs_but_expected_key_ [1] = "One", [2] = "Two" }; + List> keyValuePairs = null; // Act - Action act = () => dictionary1.Should().Contain(keyValuePairs, "because we want to test the behaviour with a null subject"); + Action act = () => + dictionary1.Should().Contain(keyValuePairs, "because we want to test the behaviour with a null subject"); // Assert act.Should().Throw() @@ -2113,11 +2170,12 @@ public void When_dictionary_contains_expected_key_value_pairs_it_should_not_thro }; // Act / Assert - var items = new List>() - { - new KeyValuePair(1, "One"), - new KeyValuePair(2, "Two") - }; + var items = new List> + { + new(1, "One"), + new(2, "Two") + }; + dictionary.Should().Contain(items); } @@ -2165,11 +2223,11 @@ public void When_dictionary_does_not_contain_the_key_value_pairs_it_should_throw [2] = "Two" }; - var items = new List>() - { - new KeyValuePair(1, "Two"), - new KeyValuePair(2, "Three") - }; + var items = new List> + { + new(1, "Two"), + new(2, "Three") + }; // Act Action act = () => dictionary.Should().Contain(items, "we put them {0}", "there"); @@ -2234,7 +2292,8 @@ public void When_asserting_dictionary_contains_value_at_specific_key_against_nul public void When_a_dictionary_like_collection_contains_the_default_key_it_should_succeed() { // Arrange - var subject = new List>() { new(0, 0) }; + var subject = new List> + { new(0, 0) }; // Act Action act = () => subject.Should().Contain(0, 0); @@ -2256,10 +2315,10 @@ public void Should_succeed_when_asserting_dictionary_does_not_contain_single_key [2] = "Two" }; - var keyValuePairs = new List>() - { - new KeyValuePair(3, "Three") - }; + var keyValuePairs = new List> + { + new(3, "Three") + }; // Act / Assert dictionary.Should().NotContain(keyValuePairs); @@ -2283,7 +2342,8 @@ public void Should_succeed_when_asserting_dictionary_does_not_contain_multiple_k } [Fact] - public void Should_succeed_when_asserting_dictionary_does_not_contain_single_key_value_pair_with_existing_key_but_different_value() + public void + Should_succeed_when_asserting_dictionary_does_not_contain_single_key_value_pair_with_existing_key_but_different_value() { // Arrange var dictionary = new Dictionary @@ -2292,10 +2352,10 @@ public void Should_succeed_when_asserting_dictionary_does_not_contain_single_key [2] = "Two" }; - var keyValuePairs = new List>() - { - new KeyValuePair(1, "Two") - }; + var keyValuePairs = new List> + { + new(1, "Two") + }; // Act / Assert dictionary.Should().NotContain(keyValuePairs); @@ -2311,18 +2371,19 @@ public void Should_succeed_when_asserting_dictionary_does_not_contain_multiple_k [2] = "Two" }; - var keyValuePairs = new List>() - { - new KeyValuePair(3, "Three"), - new KeyValuePair(4, "Four") - }; + var keyValuePairs = new List> + { + new(3, "Three"), + new(4, "Four") + }; // Act / Assert dictionary.Should().NotContain(keyValuePairs); } [Fact] - public void Should_succeed_when_asserting_dictionary_does_not_contain_multiple_key_value_pairs_with_existing_keys_but_different_values() + public void + Should_succeed_when_asserting_dictionary_does_not_contain_multiple_key_value_pairs_with_existing_keys_but_different_values() { // Arrange var dictionary = new Dictionary @@ -2331,11 +2392,11 @@ public void Should_succeed_when_asserting_dictionary_does_not_contain_multiple_k [2] = "Two" }; - var keyValuePairs = new List>() - { - new KeyValuePair(1, "Three"), - new KeyValuePair(2, "Four") - }; + var keyValuePairs = new List> + { + new(1, "Three"), + new(2, "Four") + }; // Act / Assert dictionary.Should().NotContain(keyValuePairs); @@ -2351,10 +2412,10 @@ public void When_a_dictionary_does_contain_single_key_value_pair_it_should_throw [2] = "Two" }; - var keyValuePairs = new List>() - { - new KeyValuePair(1, "One") - }; + var keyValuePairs = new List> + { + new(1, "One") + }; // Act Action act = () => dictionary.Should().NotContain(keyValuePairs, "because {0}", "we do"); @@ -2374,11 +2435,11 @@ public void When_a_dictionary_does_contain_multiple_key_value_pairs_it_should_th [2] = "Two" }; - var keyValuePairs = new List>() - { - new KeyValuePair(1, "One"), - new KeyValuePair(2, "Two") - }; + var keyValuePairs = new List> + { + new(1, "One"), + new(2, "Two") + }; // Act Action act = () => dictionary.Should().NotContain(keyValuePairs, "because {0}", "we do"); @@ -2393,7 +2454,8 @@ public void When_asserting_dictionary_does_not_contain_key_value_pairs_against_n { // Arrange Dictionary dictionary = null; - List> keyValuePairs = new List>() + + List> keyValuePairs = new() { new KeyValuePair(1, "One"), new KeyValuePair(1, "Two") @@ -2409,7 +2471,8 @@ public void When_asserting_dictionary_does_not_contain_key_value_pairs_against_n } [Fact] - public void When_asserting_dictionary_does_not_contain_key_value_pairs_but_expected_key_value_pairs_are_empty_it_should_throw() + public void + When_asserting_dictionary_does_not_contain_key_value_pairs_but_expected_key_value_pairs_are_empty_it_should_throw() { // Arrange var dictionary1 = new Dictionary @@ -2417,10 +2480,12 @@ public void When_asserting_dictionary_does_not_contain_key_value_pairs_but_expec [1] = "One", [2] = "Two" }; - List> keyValuePair = new List>(); + + List> keyValuePair = new(); // Act - Action act = () => dictionary1.Should().NotContain(keyValuePair, "because we want to test the behaviour with an empty set of key/value pairs"); + Action act = () => dictionary1.Should().NotContain(keyValuePair, + "because we want to test the behaviour with an empty set of key/value pairs"); // Assert act.Should().Throw().WithMessage( @@ -2428,7 +2493,8 @@ public void When_asserting_dictionary_does_not_contain_key_value_pairs_but_expec } [Fact] - public void When_asserting_dictionary_does_not_contain_key_value_pairs_but_expected_key_value_pairs_are_null_it_should_throw() + public void + When_asserting_dictionary_does_not_contain_key_value_pairs_but_expected_key_value_pairs_are_null_it_should_throw() { // Arrange var dictionary1 = new Dictionary @@ -2436,10 +2502,12 @@ public void When_asserting_dictionary_does_not_contain_key_value_pairs_but_expec [1] = "One", [2] = "Two" }; + List> keyValuePairs = null; // Act - Action act = () => dictionary1.Should().NotContain(keyValuePairs, "because we want to test the behaviour with a null subject"); + Action act = () => + dictionary1.Should().NotContain(keyValuePairs, "because we want to test the behaviour with a null subject"); // Assert act.Should().Throw() @@ -2502,11 +2570,12 @@ public void When_dictionary_does_not_contain_unexpected_key_value_pairs_it_shoul }; // Act / Assert - var items = new List>() + var items = new List> { - new KeyValuePair(3, "Three"), - new KeyValuePair(4, "Four") + new(3, "Three"), + new(4, "Four") }; + dictionary.Should().NotContain(items); } @@ -2555,11 +2624,12 @@ public void When_dictionary_contains_the_key_value_pairs_it_should_throw() }; // Act - var items = new List>() + var items = new List> { - new KeyValuePair(1, "One"), - new KeyValuePair(2, "Two") + new(1, "One"), + new(2, "Two") }; + Action act = () => dictionary.Should().NotContain(items, "we did not put them {0}", "there"); // Assert @@ -2675,23 +2745,23 @@ public void When_comparing_dictionary_like_collections_for_inequality_it_should_ } public static IEnumerable SingleDictionaryData() => - Dictionaries().Select(x => new[] { x }); + Dictionaries().Select(x => new[] { x }); public static object[] Dictionaries() { return new object[] { - new Dictionary() { [1] = 42 }, - new TrueReadOnlyDictionary(new Dictionary() { [1] = 42 }), - new List> { new KeyValuePair(1, 42) } + new Dictionary { [1] = 42 }, + new TrueReadOnlyDictionary(new Dictionary { [1] = 42 }), + new List> { new(1, 42) } }; } public static IEnumerable DictionariesData() { return from x in Dictionaries() - from y in Dictionaries() - select new[] { x, y }; + from y in Dictionaries() + select new[] { x, y }; } } @@ -2717,7 +2787,7 @@ public void Should_support_chaining_constraints_with_and() /// /// /// @@ -2847,7 +2917,6 @@ public ICollection /// This class only implements , - /// as also implements . + /// as also implements . /// The type of the keys in the dictionary.The type of the values in the dictionary. Values internal class TrackingDictionaryEnumerator : IEnumerator> { private readonly KeyValuePair[] values; - private int loopCount; private int index; public TrackingDictionaryEnumerator(KeyValuePair[] values) @@ -2856,14 +2925,11 @@ public TrackingDictionaryEnumerator(KeyValuePair[] values) this.values = values; } - public int LoopCount - { - get { return loopCount; } - } + public int LoopCount { get; private set; } public void IncreaseEnumerationCount() { - loopCount++; + LoopCount++; } public void Dispose() @@ -2894,7 +2960,7 @@ object IEnumerator.Current internal class DictionaryNotImplementingIReadOnlyDictionary : IDictionary { - private readonly Dictionary dictionary = new Dictionary(); + private readonly Dictionary dictionary = new(); public TValue this[TKey key] { get => dictionary[key]; set => throw new NotImplementedException(); } diff --git a/Tests/FluentAssertions.Specs/Common/TimeSpanExtensions.cs b/Tests/FluentAssertions.Specs/Common/TimeSpanExtensions.cs index 73e39ab8e0..1dbd668b12 100644 --- a/Tests/FluentAssertions.Specs/Common/TimeSpanExtensions.cs +++ b/Tests/FluentAssertions.Specs/Common/TimeSpanExtensions.cs @@ -17,6 +17,7 @@ public static TimeSpan Multiply(this TimeSpan timeSpan, double factor) // Rounding to the nearest tick is as close to the result we would have with unlimited // precision as possible, and so likely to have the least potential to surprise. double ticks = Math.Round(timeSpan.Ticks * factor); + if (ticks is > long.MaxValue or < long.MinValue) { throw new OverflowException("TimeSpan overflowed because the duration is too long."); @@ -33,6 +34,7 @@ public static TimeSpan Divide(this TimeSpan timeSpan, double divisor) } double ticks = Math.Round(timeSpan.Ticks / divisor); + if (ticks > long.MaxValue || ticks < long.MinValue || double.IsNaN(ticks)) { throw new OverflowException("TimeSpan overflowed because the duration is too long."); diff --git a/Tests/FluentAssertions.Specs/ConfigurationSpecs.cs b/Tests/FluentAssertions.Specs/ConfigurationSpecs.cs index d29345ac0e..ae08e821a0 100644 --- a/Tests/FluentAssertions.Specs/ConfigurationSpecs.cs +++ b/Tests/FluentAssertions.Specs/ConfigurationSpecs.cs @@ -33,4 +33,6 @@ public void When_concurrently_accessing_current_Configuration_no_exception_shoul // Due to tests that call Configuration.Current [CollectionDefinition("ConfigurationSpecs", DisableParallelization = true)] -public class ConfigurationSpecsDefinition { } +public class ConfigurationSpecsDefinition +{ +} diff --git a/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedFactAttributeDiscoverer.cs b/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedFactAttributeDiscoverer.cs index 7625ec09b6..49182923dd 100644 --- a/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedFactAttributeDiscoverer.cs +++ b/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedFactAttributeDiscoverer.cs @@ -14,7 +14,8 @@ public CulturedFactAttributeDiscoverer(IMessageSink diagnosticMessageSink) this.diagnosticMessageSink = diagnosticMessageSink; } - public IEnumerable Discover(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute) + public IEnumerable Discover(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, + IAttributeInfo factAttribute) { var ctorArgs = factAttribute.GetConstructorArguments().ToArray(); var cultures = Reflector.ConvertArguments(ctorArgs, new[] { typeof(string[]) }).Cast().Single(); @@ -27,6 +28,7 @@ public IEnumerable Discover(ITestFrameworkDiscoveryOptions disco TestMethodDisplay methodDisplay = discoveryOptions.MethodDisplayOrDefault(); TestMethodDisplayOptions methodDisplayOptions = discoveryOptions.MethodDisplayOptionsOrDefault(); - return cultures.Select(culture => new CulturedXunitTestCase(diagnosticMessageSink, methodDisplay, methodDisplayOptions, testMethod, culture)).ToList(); + return cultures.Select(culture => + new CulturedXunitTestCase(diagnosticMessageSink, methodDisplay, methodDisplayOptions, testMethod, culture)).ToList(); } } diff --git a/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedTheoryAttribute.cs b/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedTheoryAttribute.cs index 74c73135a4..5620288f72 100644 --- a/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedTheoryAttribute.cs +++ b/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedTheoryAttribute.cs @@ -3,7 +3,8 @@ namespace FluentAssertions.Specs.CultureAwareTesting; -[XunitTestCaseDiscoverer("FluentAssertions.Specs.CultureAwareTesting.CulturedTheoryAttributeDiscoverer", "FluentAssertions.Specs")] +[XunitTestCaseDiscoverer("FluentAssertions.Specs.CultureAwareTesting.CulturedTheoryAttributeDiscoverer", + "FluentAssertions.Specs")] public sealed class CulturedTheoryAttribute : TheoryAttribute { #pragma warning disable CA1019 // Define accessors for attribute arguments diff --git a/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedTheoryAttributeDiscoverer.cs b/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedTheoryAttributeDiscoverer.cs index 5cf90769f5..4c7ce5153f 100644 --- a/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedTheoryAttributeDiscoverer.cs +++ b/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedTheoryAttributeDiscoverer.cs @@ -8,18 +8,28 @@ namespace FluentAssertions.Specs.CultureAwareTesting; public class CulturedTheoryAttributeDiscoverer : TheoryDiscoverer { public CulturedTheoryAttributeDiscoverer(IMessageSink diagnosticMessageSink) - : base(diagnosticMessageSink) { } + : base(diagnosticMessageSink) + { + } - protected override IEnumerable CreateTestCasesForDataRow(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo theoryAttribute, object[] dataRow) + protected override IEnumerable CreateTestCasesForDataRow(ITestFrameworkDiscoveryOptions discoveryOptions, + ITestMethod testMethod, IAttributeInfo theoryAttribute, object[] dataRow) { var cultures = GetCultures(theoryAttribute); - return cultures.Select(culture => new CulturedXunitTestCase(DiagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), discoveryOptions.MethodDisplayOptionsOrDefault(), testMethod, culture, dataRow)).ToList(); + + return cultures.Select(culture => new CulturedXunitTestCase(DiagnosticMessageSink, + discoveryOptions.MethodDisplayOrDefault(), discoveryOptions.MethodDisplayOptionsOrDefault(), testMethod, culture, + dataRow)).ToList(); } - protected override IEnumerable CreateTestCasesForTheory(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo theoryAttribute) + protected override IEnumerable CreateTestCasesForTheory(ITestFrameworkDiscoveryOptions discoveryOptions, + ITestMethod testMethod, IAttributeInfo theoryAttribute) { var cultures = GetCultures(theoryAttribute); - return cultures.Select(culture => new CulturedXunitTheoryTestCase(DiagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), discoveryOptions.MethodDisplayOptionsOrDefault(), testMethod, culture)).ToList(); + + return cultures.Select(culture => new CulturedXunitTheoryTestCase(DiagnosticMessageSink, + discoveryOptions.MethodDisplayOrDefault(), discoveryOptions.MethodDisplayOptionsOrDefault(), testMethod, culture)) + .ToList(); } private static string[] GetCultures(IAttributeInfo culturedTheoryAttribute) diff --git a/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedXunitTestCase.cs b/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedXunitTestCase.cs index 85803fa3d6..36f4077890 100644 --- a/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedXunitTestCase.cs +++ b/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedXunitTestCase.cs @@ -17,11 +17,11 @@ public class CulturedXunitTestCase : XunitTestCase public CulturedXunitTestCase() { } public CulturedXunitTestCase(IMessageSink diagnosticMessageSink, - TestMethodDisplay defaultMethodDisplay, - TestMethodDisplayOptions defaultMethodDisplayOptions, - ITestMethod testMethod, - string culture, - object[] testMethodArguments = null) + TestMethodDisplay defaultMethodDisplay, + TestMethodDisplayOptions defaultMethodDisplayOptions, + ITestMethod testMethod, + string culture, + object[] testMethodArguments = null) : base(diagnosticMessageSink, defaultMethodDisplay, defaultMethodDisplayOptions, testMethod, testMethodArguments) { Initialize(culture); @@ -36,8 +36,7 @@ private void Initialize(string culture) DisplayName += $"[{culture}]"; } - protected override string GetUniqueID() - => $"{base.GetUniqueID()}[{culture}]"; + protected override string GetUniqueID() => $"{base.GetUniqueID()}[{culture}]"; public override void Deserialize(IXunitSerializationInfo data) { @@ -54,10 +53,10 @@ public override void Serialize(IXunitSerializationInfo data) } public override async Task RunAsync(IMessageSink diagnosticMessageSink, - IMessageBus messageBus, - object[] constructorArguments, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource) + IMessageBus messageBus, + object[] constructorArguments, + ExceptionAggregator aggregator, + CancellationTokenSource cancellationTokenSource) { CultureInfo originalCulture = CurrentCulture; CultureInfo originalUICulture = CurrentUICulture; @@ -68,7 +67,8 @@ public override async Task RunAsync(IMessageSink diagnosticMessageSi CurrentCulture = cultureInfo; CurrentUICulture = cultureInfo; - return await base.RunAsync(diagnosticMessageSink, messageBus, constructorArguments, aggregator, cancellationTokenSource); + return await base.RunAsync(diagnosticMessageSink, messageBus, constructorArguments, aggregator, + cancellationTokenSource); } finally { diff --git a/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedXunitTheoryTestCase.cs b/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedXunitTheoryTestCase.cs index cef465f649..f596256ebb 100644 --- a/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedXunitTheoryTestCase.cs +++ b/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedXunitTheoryTestCase.cs @@ -21,10 +21,10 @@ public CulturedXunitTheoryTestCase() { } /// Default method display options to use (when not customized). /// The method under test. public CulturedXunitTheoryTestCase(IMessageSink diagnosticMessageSink, - TestMethodDisplay defaultMethodDisplay, - TestMethodDisplayOptions defaultMethodDisplayOptions, - ITestMethod testMethod, - string culture) + TestMethodDisplay defaultMethodDisplay, + TestMethodDisplayOptions defaultMethodDisplayOptions, + ITestMethod testMethod, + string culture) : base(diagnosticMessageSink, defaultMethodDisplay, defaultMethodDisplayOptions, testMethod) { Initialize(culture); @@ -39,8 +39,7 @@ public override void Deserialize(IXunitSerializationInfo data) Initialize(data.GetValue("Culture")); } - protected override string GetUniqueID() - => $"{base.GetUniqueID()}[{Culture}]"; + protected override string GetUniqueID() => $"{base.GetUniqueID()}[{Culture}]"; private void Initialize(string culture) { @@ -52,11 +51,12 @@ private void Initialize(string culture) } public override Task RunAsync(IMessageSink diagnosticMessageSink, - IMessageBus messageBus, - object[] constructorArguments, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource) - => new CulturedXunitTheoryTestCaseRunner(this, DisplayName, SkipReason, constructorArguments, diagnosticMessageSink, messageBus, aggregator, cancellationTokenSource).RunAsync(); + IMessageBus messageBus, + object[] constructorArguments, + ExceptionAggregator aggregator, + CancellationTokenSource cancellationTokenSource) => + new CulturedXunitTheoryTestCaseRunner(this, DisplayName, SkipReason, constructorArguments, diagnosticMessageSink, + messageBus, aggregator, cancellationTokenSource).RunAsync(); public override void Serialize(IXunitSerializationInfo data) { diff --git a/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedXunitTheoryTestCaseRunner.cs b/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedXunitTheoryTestCaseRunner.cs index 1cbb811bc1..7ec493ca10 100644 --- a/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedXunitTheoryTestCaseRunner.cs +++ b/Tests/FluentAssertions.Specs/CultureAwareTesting/CulturedXunitTheoryTestCaseRunner.cs @@ -14,14 +14,15 @@ public class CulturedXunitTheoryTestCaseRunner : XunitTheoryTestCaseRunner private CultureInfo originalUICulture; public CulturedXunitTheoryTestCaseRunner(CulturedXunitTheoryTestCase culturedXunitTheoryTestCase, - string displayName, - string skipReason, - object[] constructorArguments, - IMessageSink diagnosticMessageSink, - IMessageBus messageBus, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource) - : base(culturedXunitTheoryTestCase, displayName, skipReason, constructorArguments, diagnosticMessageSink, messageBus, aggregator, cancellationTokenSource) + string displayName, + string skipReason, + object[] constructorArguments, + IMessageSink diagnosticMessageSink, + IMessageBus messageBus, + ExceptionAggregator aggregator, + CancellationTokenSource cancellationTokenSource) + : base(culturedXunitTheoryTestCase, displayName, skipReason, constructorArguments, diagnosticMessageSink, messageBus, + aggregator, cancellationTokenSource) { culture = culturedXunitTheoryTestCase.Culture; } diff --git a/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs index 2221c69ace..d491e9b366 100644 --- a/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs @@ -1,9 +1,4 @@ -#if NETFRAMEWORK -using System.Reflection; -using System.Reflection.Emit; -#endif - -using System; +using System; using System.ComponentModel; using System.Linq; using FluentAssertions.Events; @@ -11,6 +6,10 @@ using FluentAssertions.Formatting; using Xunit; using Xunit.Sdk; +#if NETFRAMEWORK +using System.Reflection; +using System.Reflection.Emit; +#endif namespace FluentAssertions.Specs.Events; @@ -96,7 +95,7 @@ public void When_an_unexpected_event_was_raised_it_should_throw_and_use_the_reas // Assert act.Should().Throw() .WithMessage("Expected object " + Formatter.ToString(subject) + - " to not raise event \"PropertyChanged\" because Foo() should cause the event to get raised, but it did."); + " to not raise event \"PropertyChanged\" because Foo() should cause the event to get raised, but it did."); } [Fact] @@ -224,7 +223,7 @@ public void When_running_in_parallel_it_should_not_throw() // Arrange void Action(int _) { - EventRaisingClass subject = new EventRaisingClass(); + EventRaisingClass subject = new(); using var monitor = subject.Monitor(); subject.RaiseEventWithSender(); monitor.Should().Raise("PropertyChanged"); @@ -321,7 +320,8 @@ public void When_a_non_conventional_event_with_a_specific_argument_was_not_raise // Assert act.Should().Throw().WithMessage( - "Expected at least one event with some argument*type*Int32*matches*(args == " + wrongArgument + "), but found none."); + "Expected at least one event with some argument*type*Int32*matches*(args == " + wrongArgument + + "), but found none."); } [Fact] @@ -516,7 +516,8 @@ public void When_a_property_agnostic_property_changed_event_for_was_not_raised_i } [Fact] - public void When_the_property_changed_event_was_raised_for_the_wrong_property_it_should_throw_and_include_the_actual_properties_raised() + public void + When_the_property_changed_event_was_raised_for_the_wrong_property_it_should_throw_and_include_the_actual_properties_raised() { // Arrange var bar = new EventRaisingClass(); @@ -727,12 +728,17 @@ private object CreateProxyObject() { Type baseType = typeof(EventRaisingClass); Type interfaceType = typeof(IEventRaisingInterface); - AssemblyName assemblyName = new AssemblyName { Name = baseType.Assembly.FullName + ".GeneratedForTest" }; + + AssemblyName assemblyName = new() { Name = baseType.Assembly.FullName + ".GeneratedForTest" }; + AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); + ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, false); string typeName = baseType.Name + "_GeneratedForTest"; - TypeBuilder typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes.Public, baseType, new[] { interfaceType }); + + TypeBuilder typeBuilder = + moduleBuilder.DefineType(typeName, TypeAttributes.Public, baseType, new[] { interfaceType }); MethodBuilder addHandler = EmitAddRemoveEventHandler("add"); typeBuilder.DefineMethodOverride(addHandler, interfaceType.GetMethod("add_InterfaceEvent")); @@ -749,6 +755,7 @@ MethodBuilder EmitAddRemoveEventHandler(string methodName) MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot); + method.SetReturnType(typeof(void)); method.SetParameters(typeof(EventHandler)); ILGenerator gen = method.GetILGenerator(); @@ -828,7 +835,7 @@ public class WithArgs public void One_matching_argument_type_before_mismatching_types_passes() { // Arrange - A a = new A(); + A a = new(); using var aMonitor = a.Monitor(); a.OnEvent(new B()); @@ -843,7 +850,7 @@ public void One_matching_argument_type_before_mismatching_types_passes() public void One_matching_argument_type_after_mismatching_types_passes() { // Arrange - A a = new A(); + A a = new(); using var aMonitor = a.Monitor(); a.OnEvent(new C()); @@ -858,7 +865,7 @@ public void One_matching_argument_type_after_mismatching_types_passes() public void Throws_when_none_of_the_arguments_are_of_the_expected_type() { // Arrange - A a = new A(); + A a = new(); using var aMonitor = a.Monitor(); a.OnEvent(new C()); @@ -876,7 +883,7 @@ public void Throws_when_none_of_the_arguments_are_of_the_expected_type() public void One_matching_argument_type_anywhere_between_mismatching_types_passes() { // Arrange - A a = new A(); + A a = new(); using var aMonitor = a.Monitor(); a.OnEvent(new C()); @@ -892,7 +899,7 @@ public void One_matching_argument_type_anywhere_between_mismatching_types_passes public void One_matching_argument_type_anywhere_between_mismatching_types_with_parameters_passes() { // Arrange - A a = new A(); + A a = new(); using var aMonitor = a.Monitor(); a.OnEvent(new C()); @@ -908,7 +915,7 @@ public void One_matching_argument_type_anywhere_between_mismatching_types_with_p public void Mismatching_argument_types_with_one_parameter_matching_a_different_type_fails() { // Arrange - A a = new A(); + A a = new(); using var aMonitor = a.Monitor(); a.OnEvent(new C()); @@ -926,7 +933,7 @@ public void Mismatching_argument_types_with_one_parameter_matching_a_different_t public void Mismatching_argument_types_with_two_or_more_parameters_matching_a_different_type_fails() { // Arrange - A a = new A(); + A a = new(); using var aMonitor = a.Monitor(); a.OnEvent(new C()); @@ -944,7 +951,7 @@ public void Mismatching_argument_types_with_two_or_more_parameters_matching_a_di public void One_matching_argument_type_with_two_or_more_parameters_matching_a_mismatching_type_fails() { // Arrange - A a = new A(); + A a = new(); using var aMonitor = a.Monitor(); a.OnEvent(new C()); @@ -969,9 +976,13 @@ public void OnEvent(object o) } } - public class B { } + public class B + { + } - public class C { } + public class C + { + } public class ClassThatRaisesEventsItself : IInheritsEventRaisingInterface { diff --git a/Tests/FluentAssertions.Specs/Exceptions/AsyncFunctionExceptionAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Exceptions/AsyncFunctionExceptionAssertionSpecs.cs index 622e244651..47971b006e 100644 --- a/Tests/FluentAssertions.Specs/Exceptions/AsyncFunctionExceptionAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Exceptions/AsyncFunctionExceptionAssertionSpecs.cs @@ -1,14 +1,12 @@ using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; using FluentAssertions.Execution; using FluentAssertions.Extensions; +using Xunit; +using Xunit.Sdk; #if NETFRAMEWORK using FluentAssertions.Specs.Common; #endif -using Xunit; -using Xunit.Sdk; namespace FluentAssertions.Specs.Exceptions; @@ -215,7 +213,7 @@ public async Task When_the_expected_exception_is_not_wrapped_on_UI_thread_async_ public static TheoryData, Exception> AggregateExceptionTestData() { - var tasks = new Func[] + var tasks = new[] { AggregateExceptionWithLeftNestedException, AggregateExceptionWithRightNestedException @@ -284,7 +282,8 @@ public async Task When_subject_throws_subclass_of_expected_exact_exception_it_sh // Assert await action.Should().ThrowAsync() - .WithMessage("Expected type to be System.ArgumentException because IFoo.Do should do that, but found System.ArgumentNullException."); + .WithMessage( + "Expected type to be System.ArgumentException because IFoo.Do should do that, but found System.ArgumentNullException."); } [Fact] @@ -300,7 +299,8 @@ public async Task When_subject_ValueTask_throws_subclass_of_expected_exact_excep // Assert await action.Should().ThrowAsync() - .WithMessage("Expected type to be System.ArgumentException because IFoo.Do should do that, but found System.ArgumentNullException."); + .WithMessage( + "Expected type to be System.ArgumentException because IFoo.Do should do that, but found System.ArgumentNullException."); } [Fact] @@ -316,7 +316,8 @@ public async Task When_subject_throws_aggregate_exception_and_not_expected_exact // Assert await action.Should().ThrowAsync() - .WithMessage("Expected type to be System.ArgumentException because IFoo.Do should do that, but found System.AggregateException."); + .WithMessage( + "Expected type to be System.ArgumentException because IFoo.Do should do that, but found System.AggregateException."); } [Fact] @@ -332,7 +333,8 @@ public async Task When_subject_throws_aggregate_exception_and_not_expected_exact // Assert await action.Should().ThrowAsync() - .WithMessage("Expected type to be System.ArgumentException because IFoo.Do should do that, but found System.AggregateException."); + .WithMessage( + "Expected type to be System.ArgumentException because IFoo.Do should do that, but found System.AggregateException."); } [Fact] @@ -429,7 +431,8 @@ public async Task When_async_method_does_not_throw_expected_exception_it_should_ // Assert await action.Should().ThrowAsync() - .WithMessage("Expected a to be thrown because IFoo.Do should do that, but no exception was thrown."); + .WithMessage( + "Expected a to be thrown because IFoo.Do should do that, but no exception was thrown."); } [Fact] @@ -445,7 +448,8 @@ public async Task When_async_method_does_not_throw_expected_exception_through_Va // Assert await action.Should().ThrowAsync() - .WithMessage("Expected a to be thrown because IFoo.Do should do that, but no exception was thrown."); + .WithMessage( + "Expected a to be thrown because IFoo.Do should do that, but no exception was thrown."); } [Fact] @@ -461,7 +465,8 @@ public async Task When_async_method_throws_unexpected_exception_it_should_fail() // Assert await action.Should().ThrowAsync() - .WithMessage("Expected a to be thrown because IFoo.Do should do that, but found *"); + .WithMessage( + "Expected a to be thrown because IFoo.Do should do that, but found *"); } [Fact] @@ -477,7 +482,8 @@ public async Task When_async_method_throws_unexpected_exception_through_ValueTas // Assert await action.Should().ThrowAsync() - .WithMessage("Expected a to be thrown because IFoo.Do should do that, but found *"); + .WithMessage( + "Expected a to be thrown because IFoo.Do should do that, but found *"); } [Fact] @@ -700,7 +706,8 @@ public async Task When_async_method_throws_exception_and_expected_not_to_throw_a } [Fact] - public async Task When_async_method_throws_exception_through_ValueTask_and_expected_not_to_throw_another_one_it_should_succeed() + public async Task + When_async_method_throws_exception_through_ValueTask_and_expected_not_to_throw_another_one_it_should_succeed() { // Arrange var asyncObject = new AsyncClass(); @@ -743,7 +750,8 @@ public async Task When_async_method_succeeds_and_expected_not_to_throw_particula } [Fact] - public async Task When_async_method_succeeds_and_expected_not_to_throw_particular_exception_through_ValueTask_it_should_succeed() + public async Task + When_async_method_succeeds_and_expected_not_to_throw_particular_exception_through_ValueTask_it_should_succeed() { // Arrange var asyncObject = new AsyncClass(); @@ -1102,6 +1110,7 @@ await act.Should().ThrowAsync() } #region NotThrowAfterAsync + [Fact] public async Task When_wait_time_is_zero_for_async_func_executed_with_wait_it_should_not_throw() { @@ -1150,6 +1159,7 @@ public async Task When_subject_is_null_for_async_func_it_should_throw() Func testAction = async () => { using var _ = new AssertionScope(); + await action.Should().NotThrowAfterAsync(waitTime, pollInterval, "because we want to test the failure {0}", "message"); }; @@ -1249,7 +1259,8 @@ await action.Should().ThrowAsync() public partial class UIFacts { [UIFact] - public async Task When_no_exception_should_be_thrown_on_UI_thread_for_async_func_after_wait_time_but_it_was_it_should_throw() + public async Task + When_no_exception_should_be_thrown_on_UI_thread_for_async_func_after_wait_time_but_it_was_it_should_throw() { // Arrange var waitTime = 2.Seconds(); @@ -1310,7 +1321,8 @@ public async Task When_no_exception_should_be_thrown_for_async_func_after_wait_t public partial class UIFacts { [UIFact] - public async Task When_no_exception_should_be_thrown_on_UI_thread_for_async_func_after_wait_time_and_none_was_it_should_not_throw() + public async Task + When_no_exception_should_be_thrown_on_UI_thread_for_async_func_after_wait_time_and_none_was_it_should_not_throw() { // Arrange var waitTime = 6.Seconds(); @@ -1337,6 +1349,7 @@ public async Task When_no_exception_should_be_thrown_on_UI_thread_for_async_func await act.Should().NotThrowAsync(); } } + #endregion } diff --git a/Tests/FluentAssertions.Specs/Exceptions/ExceptionAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Exceptions/ExceptionAssertionSpecs.cs index ccbf4f2299..d55e32acc4 100644 --- a/Tests/FluentAssertions.Specs/Exceptions/ExceptionAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Exceptions/ExceptionAssertionSpecs.cs @@ -1,15 +1,8 @@ using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Threading.Tasks; -#if NETFRAMEWORK -using FluentAssertions.Specs.Common; -#endif using Xunit; using Xunit.Sdk; -using static FluentAssertions.Extensions.FluentTimeSpanExtensions; - namespace FluentAssertions.Specs.Exceptions; public class ExceptionAssertionSpecs @@ -52,7 +45,7 @@ public void When_the_expected_exception_is_not_wrapped_it_should_fail(Action public static TheoryData AggregateExceptionTestData() { - var tasks = new Action[] + var tasks = new[] { AggregateExceptionWithLeftNestedException, AggregateExceptionWithRightNestedException @@ -119,7 +112,9 @@ public void ThrowExactly_when_subject_throws_subclass_of_expected_exception_it_s catch (XunitException ex) { // Assert - ex.Message.Should().Match("Expected type to be System.ArgumentException because Does.Do should do that, but found System.ArgumentNullException."); + ex.Message.Should() + .Match( + "Expected type to be System.ArgumentException because Does.Do should do that, but found System.ArgumentNullException."); } } @@ -139,7 +134,9 @@ public void ThrowExactly_when_subject_throws_aggregate_exception_instead_of_expe catch (XunitException ex) { // Assert - ex.Message.Should().Match("Expected type to be System.ArgumentException because Does.Do should do that, but found System.AggregateException."); + ex.Message.Should() + .Match( + "Expected type to be System.ArgumentException because Does.Do should do that, but found System.AggregateException."); } } diff --git a/Tests/FluentAssertions.Specs/Exceptions/FunctionExceptionAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Exceptions/FunctionExceptionAssertionSpecs.cs index 0939551af3..582a6a27e1 100644 --- a/Tests/FluentAssertions.Specs/Exceptions/FunctionExceptionAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Exceptions/FunctionExceptionAssertionSpecs.cs @@ -1,13 +1,12 @@ using System; -using System.Collections.Generic; using System.Threading.Tasks; using FluentAssertions.Execution; using FluentAssertions.Extensions; +using Xunit; +using Xunit.Sdk; #if NETFRAMEWORK using FluentAssertions.Specs.Common; #endif -using Xunit; -using Xunit.Sdk; namespace FluentAssertions.Specs.Exceptions; @@ -70,7 +69,7 @@ public void When_the_expected_exception_is_not_wrapped_it_should_fail(Func, Exception> AggregateExceptionTestData() { - var tasks = new Func[] + var tasks = new[] { AggregateExceptionWithLeftNestedException, AggregateExceptionWithRightNestedException @@ -217,7 +216,8 @@ public void When_function_does_throw_expected_exception_but_in_aggregate_it_shou } [Fact] - public void When_function_does_not_throw_expected_exception_but_throws_aggregate_in_aggregate_it_should_fail_with_inner_exception_one_level_deep() + public void + When_function_does_not_throw_expected_exception_but_throws_aggregate_in_aggregate_it_should_fail_with_inner_exception_one_level_deep() { // Arrange Func f = () => throw new AggregateException(new AggregateException(new ArgumentNullException())); @@ -260,6 +260,7 @@ public void When_function_does_not_throw_any_exception_it_should_fail() #endregion #region ThrowExactly + [Fact] public void When_subject_is_null_when_an_exact_exception_should_be_thrown_it_should_throw() { @@ -348,6 +349,7 @@ public void When_function_does_not_throw_any_exception_when_expected_exact_it_sh #endregion #region NotThrow + [Fact] public void When_subject_is_null_when_an_exception_should_not_be_thrown_it_should_throw() { @@ -420,7 +422,8 @@ public void When_function_throw_aggregate_exception_and_that_was_not_expected_it } [Fact] - public void When_function_throw_aggregate_in_aggregate_exception_and_that_was_not_expected_it_should_fail_with_most_inner_exception_in_message() + public void + When_function_throw_aggregate_in_aggregate_exception_and_that_was_not_expected_it_should_fail_with_most_inner_exception_in_message() { // Arrange Func f = () => throw new AggregateException(new AggregateException(new ArgumentNullException())); @@ -443,6 +446,7 @@ public void When_an_assertion_fails_on_NotThrow_succeeding_message_should_be_inc Action act = () => { using var _ = new AssertionScope(); + throwingFunction.Should().NotThrow() .And.BeNull(); }; @@ -458,6 +462,7 @@ public void When_an_assertion_fails_on_NotThrow_succeeding_message_should_be_inc #endregion #region NotThrowAfter + [Fact] public void When_subject_is_null_it_should_throw() { @@ -540,7 +545,7 @@ public void When_no_exception_should_be_thrown_after_wait_time_but_it_was_it_sho // Assert action.Should().Throw() - .WithMessage("Did not expect any exceptions after 100ms because we passed valid arguments*"); + .WithMessage("Did not expect any exceptions after 100ms because we passed valid arguments*"); } [Fact] @@ -590,7 +595,7 @@ public void When_no_exception_should_be_thrown_after_wait_time_the_func_result_s // Act Action act = () => throwShorterThanWaitTime.Should(clock).NotThrowAfter(waitTime, pollInterval) - .Which.Should().Be(42); + .Which.Should().Be(42); // Assert act.Should().NotThrow(); @@ -608,6 +613,7 @@ public void When_an_assertion_fails_on_NotThrowAfter_succeeding_message_should_b Action act = () => { using var _ = new AssertionScope(); + throwingFunction.Should().NotThrowAfter(waitTime, pollInterval) .And.BeNull(); }; @@ -621,9 +627,12 @@ public void When_an_assertion_fails_on_NotThrowAfter_succeeding_message_should_b } #endregion + #region NotThrow + [Fact] - public void When_function_does_not_throw_at_all_when_some_particular_exception_was_not_expected_it_should_succeed_but_then_cannot_continue_assertion() + public void + When_function_does_not_throw_at_all_when_some_particular_exception_was_not_expected_it_should_succeed_but_then_cannot_continue_assertion() { // Arrange Func f = () => 12; @@ -643,7 +652,8 @@ public void When_function_does_throw_exception_and_that_exception_was_not_expect // Assert action.Should().Throw() - .WithMessage("*Did not expect System.InvalidOperationException because it was so fast, but found System.InvalidOperationException with message*custom message*"); + .WithMessage( + "*Did not expect System.InvalidOperationException because it was so fast, but found System.InvalidOperationException with message*custom message*"); } [Fact] diff --git a/Tests/FluentAssertions.Specs/Exceptions/InnerExceptionSpecs.cs b/Tests/FluentAssertions.Specs/Exceptions/InnerExceptionSpecs.cs index 8019338364..e2b818bae8 100644 --- a/Tests/FluentAssertions.Specs/Exceptions/InnerExceptionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Exceptions/InnerExceptionSpecs.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics.CodeAnalysis; using Xunit; using Xunit.Sdk; @@ -47,7 +46,8 @@ public void When_subject_throws_an_exception_with_the_expected_inner_exception_f } [Fact] - public void WithInnerExceptionExactly_no_parameters_when_subject_throws_subclass_of_expected_inner_exception_it_should_throw_with_clear_description() + public void + WithInnerExceptionExactly_no_parameters_when_subject_throws_subclass_of_expected_inner_exception_it_should_throw_with_clear_description() { // Arrange var innerException = new ArgumentNullException("InnerExceptionMessage", (Exception)null); @@ -77,11 +77,12 @@ public void WithInnerExceptionExactly_no_parameters_when_subject_throws_expected // Act / Assert act.Should().Throw() - .WithInnerExceptionExactly(); + .WithInnerExceptionExactly(); } [Fact] - public void WithInnerExceptionExactly_when_subject_throws_subclass_of_expected_inner_exception_it_should_throw_with_clear_description() + public void + WithInnerExceptionExactly_when_subject_throws_subclass_of_expected_inner_exception_it_should_throw_with_clear_description() { // Arrange var innerException = new ArgumentNullException("InnerExceptionMessage", (Exception)null); @@ -99,12 +100,14 @@ public void WithInnerExceptionExactly_when_subject_throws_subclass_of_expected_i catch (XunitException ex) { // Assert - ex.Message.Should().Match("Expected*ArgumentException*the action should do just that*ArgumentNullException*InnerExceptionMessage*"); + ex.Message.Should() + .Match("Expected*ArgumentException*the action should do just that*ArgumentNullException*InnerExceptionMessage*"); } } [Fact] - public void WithInnerExceptionExactly_with_type_exception_when_subject_throws_expected_inner_exception_it_should_not_do_anything() + public void + WithInnerExceptionExactly_with_type_exception_when_subject_throws_expected_inner_exception_it_should_not_do_anything() { // Arrange Action act = () => throw new BadImageFormatException("", new ArgumentNullException()); @@ -115,7 +118,8 @@ public void WithInnerExceptionExactly_with_type_exception_when_subject_throws_ex } [Fact] - public void WithInnerExceptionExactly_with_type_exception_no_parameters_when_subject_throws_expected_inner_exception_it_should_not_do_anything() + public void + WithInnerExceptionExactly_with_type_exception_no_parameters_when_subject_throws_expected_inner_exception_it_should_not_do_anything() { // Arrange Action act = () => throw new BadImageFormatException("", new ArgumentNullException()); @@ -126,7 +130,8 @@ public void WithInnerExceptionExactly_with_type_exception_no_parameters_when_sub } [Fact] - public void WithInnerExceptionExactly_with_type_exception_when_subject_throws_subclass_of_expected_inner_exception_it_should_throw_with_clear_description() + public void + WithInnerExceptionExactly_with_type_exception_when_subject_throws_subclass_of_expected_inner_exception_it_should_throw_with_clear_description() { // Arrange var innerException = new ArgumentNullException("InnerExceptionMessage", (Exception)null); @@ -144,7 +149,8 @@ public void WithInnerExceptionExactly_with_type_exception_when_subject_throws_su catch (XunitException ex) { // Assert - ex.Message.Should().Match("Expected*ArgumentException*the action should do just that*ArgumentNullException*InnerExceptionMessage*"); + ex.Message.Should() + .Match("Expected*ArgumentException*the action should do just that*ArgumentNullException*InnerExceptionMessage*"); } } @@ -156,7 +162,7 @@ public void WithInnerExceptionExactly_when_subject_throws_expected_inner_excepti // Act / Assert act.Should().Throw() - .WithInnerExceptionExactly("because {0} should do just that", "the action"); + .WithInnerExceptionExactly("because {0} should do just that", "the action"); } [Fact] @@ -205,7 +211,8 @@ public void When_subject_throws_an_exception_without_expected_inner_exception_it } [Fact] - public void When_subject_throws_an_exception_without_expected_inner_exception_and_has_reason_it_should_throw_with_clear_description() + public void + When_subject_throws_an_exception_without_expected_inner_exception_and_has_reason_it_should_throw_with_clear_description() { try { @@ -238,7 +245,8 @@ public void When_an_inner_exception_matches_exactly_it_should_allow_chaining_mor } [Fact] - public void When_an_inner_exception_matches_exactly_it_should_allow_chaining_more_asserts_on_that_exception_type_from_argument() + public void + When_an_inner_exception_matches_exactly_it_should_allow_chaining_more_asserts_on_that_exception_type_from_argument() { // Act Action act = () => diff --git a/Tests/FluentAssertions.Specs/Exceptions/MiscellaneousExceptionSpecs.cs b/Tests/FluentAssertions.Specs/Exceptions/MiscellaneousExceptionSpecs.cs index 346c520beb..430fc82bb5 100644 --- a/Tests/FluentAssertions.Specs/Exceptions/MiscellaneousExceptionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Exceptions/MiscellaneousExceptionSpecs.cs @@ -68,7 +68,7 @@ public void When_custom_condition_is_not_met_it_should_throw() { // Act act - .Should().Throw("") + .Should().Throw() .Where(e => e.Message.Length > 0, "an exception must have a message"); throw new XunitException("This point should not be reached"); @@ -91,7 +91,7 @@ public void When_a_2nd_condition_is_not_met_it_should_throw() { // Act act - .Should().Throw("") + .Should().Throw() .Where(e => e.Message.Length > 0) .Where(e => e.Message == "Error"); diff --git a/Tests/FluentAssertions.Specs/Exceptions/NotThrowSpecs.cs b/Tests/FluentAssertions.Specs/Exceptions/NotThrowSpecs.cs index 1a04903259..61d089b2e6 100644 --- a/Tests/FluentAssertions.Specs/Exceptions/NotThrowSpecs.cs +++ b/Tests/FluentAssertions.Specs/Exceptions/NotThrowSpecs.cs @@ -1,13 +1,11 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using System.Threading.Tasks; -using FluentAssertions.Execution; -#if NETFRAMEWORK +#if NETFRAMEWORK using FluentAssertions.Specs.Common; #endif +using System; +using System.Threading.Tasks; +using FluentAssertions.Execution; using Xunit; using Xunit.Sdk; - using static FluentAssertions.Extensions.FluentTimeSpanExtensions; namespace FluentAssertions.Specs.Exceptions; @@ -47,7 +45,7 @@ public void When_a_specific_exception_should_not_be_thrown_but_it_was_it_should_ action .Should().Throw().WithMessage( "Did not expect System.ArgumentException because we passed valid arguments, " + - "but found*with message \"An exception was forced\"*"); + "but found*with message \"An exception was forced\"*"); } [Fact] @@ -83,7 +81,7 @@ public void When_no_exception_should_be_thrown_but_it_was_it_should_throw() action .Should().Throw().WithMessage( "Did not expect any exception because we passed valid arguments, " + - "but found System.ArgumentException with message \"An exception was forced\"*"); + "but found System.ArgumentException with message \"An exception was forced\"*"); } [Fact] @@ -106,6 +104,7 @@ public void When_subject_is_null_when_it_should_not_throw_it_should_throw() Action action = () => { using var _ = new AssertionScope(); + act.Should().NotThrowAfter(0.Milliseconds(), 0.Milliseconds(), "because we want to test the failure {0}", "message"); }; @@ -193,7 +192,7 @@ public void When_no_exception_should_be_thrown_after_wait_time_but_it_was_it_sho // Assert action.Should().Throw() - .WithMessage("Did not expect any exceptions after 100ms because we passed valid arguments*"); + .WithMessage("Did not expect any exceptions after 100ms because we passed valid arguments*"); } [Fact] diff --git a/Tests/FluentAssertions.Specs/Exceptions/OuterExceptionSpecs.cs b/Tests/FluentAssertions.Specs/Exceptions/OuterExceptionSpecs.cs index f1b554bc3f..f4c56646be 100644 --- a/Tests/FluentAssertions.Specs/Exceptions/OuterExceptionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Exceptions/OuterExceptionSpecs.cs @@ -70,11 +70,13 @@ public void When_subject_throws_expected_exception_with_message_that_does_not_st // Assert action.Should().Throw() - .WithMessage("Expected exception message to match the equivalent of*\"Expected mes*\", but*\"OxpectOd message\" does not*"); + .WithMessage( + "Expected exception message to match the equivalent of*\"Expected mes*\", but*\"OxpectOd message\" does not*"); } [Fact] - public void When_subject_throws_expected_exception_with_message_starting_with_expected_equivalent_message_it_should_not_throw() + public void + When_subject_throws_expected_exception_with_message_starting_with_expected_equivalent_message_it_should_not_throw() { // Arrange Does testSubject = Does.Throw(new InvalidOperationException("Expected Message")); @@ -96,13 +98,14 @@ public void When_subject_throws_expected_exception_with_message_that_does_not_st // Act Action action = () => testSubject - .Invoking(s => s.Do()) - .Should().Throw() - .WithMessage("expected mes"); + .Invoking(s => s.Do()) + .Should().Throw() + .WithMessage("expected mes"); // Assert action.Should().Throw() - .WithMessage("Expected exception message to match the equivalent of*\"expected mes*\", but*\"OxpectOd message\" does not*"); + .WithMessage( + "Expected exception message to match the equivalent of*\"expected mes*\", but*\"OxpectOd message\" does not*"); } [Fact] @@ -154,7 +157,8 @@ public void When_subject_throws_some_exception_with_an_empty_message_it_should_t } [Fact] - public void When_subject_throws_some_exception_with_message_which_contains_complete_expected_exception_and_more_it_should_throw() + public void + When_subject_throws_some_exception_with_message_which_contains_complete_expected_exception_and_more_it_should_throw() { // Arrange Does subjectThatThrows = Does.Throw(new ArgumentNullException("someParam", "message2")); @@ -266,7 +270,8 @@ public void When_asserting_with_an_aggregate_exception_type_the_asserts_should_o } [Fact] - public void When_asserting_with_an_aggregate_exception_and_inner_exception_type_from_argument_the_asserts_should_occur_against_the_aggregate_exception() + public void + When_asserting_with_an_aggregate_exception_and_inner_exception_type_from_argument_the_asserts_should_occur_against_the_aggregate_exception() { // Arrange Does testSubject = Does.Throw(new AggregateException("Outer Message", new Exception("Inner Message"))); diff --git a/Tests/FluentAssertions.Specs/Execution/AssertionScope.ChainingApiSpecs.cs b/Tests/FluentAssertions.Specs/Execution/AssertionScope.ChainingApiSpecs.cs index b158569dc9..dfe06be10b 100644 --- a/Tests/FluentAssertions.Specs/Execution/AssertionScope.ChainingApiSpecs.cs +++ b/Tests/FluentAssertions.Specs/Execution/AssertionScope.ChainingApiSpecs.cs @@ -27,7 +27,7 @@ public void When_the_previous_assertion_succeeded_it_should_not_affect_the_next_ catch (Exception e) { // Assert - succeeded = (e is XunitException xUnitException) && xUnitException.Message.Contains("Second"); + succeeded = e is XunitException xUnitException && xUnitException.Message.Contains("Second"); } if (!succeeded) @@ -145,6 +145,7 @@ public void When_the_previous_assertion_failed_it_should_not_evaluate_the_succee { // Arrange bool secondConditionEvaluated = false; + try { using var _ = new AssertionScope(); @@ -195,6 +196,7 @@ public void When_the_previous_assertion_failed_it_should_not_execute_the_succeed Action act = () => { using var _ = new AssertionScope(); + Execute.Assertion .ForCondition(false) .FailWith("First assertion") @@ -214,6 +216,7 @@ public void When_the_previous_assertion_failed_it_should_not_execute_the_succeed Action act = () => { using var _ = new AssertionScope(); + Execute.Assertion .ForCondition(false) .FailWith("First assertion") @@ -233,6 +236,7 @@ public void When_the_previous_assertion_failed_it_should_not_execute_the_succeed Action act = () => { using var _ = new AssertionScope(); + Execute.Assertion .ForCondition(false) .FailWith("First assertion") @@ -252,6 +256,7 @@ public void When_the_previous_assertion_failed_it_should_not_execute_the_succeed Action act = () => { using var _ = new AssertionScope(); + Execute.Assertion .WithExpectation("Expectations are the root ") .ForCondition(false) @@ -273,6 +278,7 @@ public void When_the_previous_assertion_failed_it_should_not_execute_the_succeed Action act = () => { using var _ = new AssertionScope(); + Execute.Assertion .WithExpectation("Expectations are the {0} ", "root") .ForCondition(false) @@ -294,6 +300,7 @@ public void When_the_previous_assertion_failed_it_should_not_execute_the_succeed Action act = () => { using var _ = new AssertionScope(); + Execute.Assertion .WithDefaultIdentifier("identifier") .ForCondition(false) @@ -315,6 +322,7 @@ public void When_continuing_a_failed_assertion_chain_consecutive_resons_are_igno Action act = () => { using var _ = new AssertionScope(); + Execute.Assertion .BecauseOf("because {0}", "whatever") .ForCondition(false) @@ -336,6 +344,7 @@ public void When_continuing_a_failed_assertion_chain_consecutive_resons_with_arg Action act = () => { using var _ = new AssertionScope(); + Execute.Assertion .BecauseOf("because {0}", "whatever") .ForCondition(false) diff --git a/Tests/FluentAssertions.Specs/Execution/AssertionScope.ContextDataSpecs.cs b/Tests/FluentAssertions.Specs/Execution/AssertionScope.ContextDataSpecs.cs index 49546581c8..1a36fb62bc 100644 --- a/Tests/FluentAssertions.Specs/Execution/AssertionScope.ContextDataSpecs.cs +++ b/Tests/FluentAssertions.Specs/Execution/AssertionScope.ContextDataSpecs.cs @@ -41,9 +41,9 @@ public void Get_default_value_when_nullable_value_is_null() { // Arrange var scope = new AssertionScope(); -#pragma warning disable IDE0004 // Remove Unnecessary Cast - scope.AddNonReportable("SomeKey", (int?)null); -#pragma warning restore IDE0004 // Remove Unnecessary Cast + + int? someValue = null; + scope.AddNonReportable("SomeKey", someValue); // Act var value = scope.Get("SomeKey"); diff --git a/Tests/FluentAssertions.Specs/Execution/AssertionScope.MessageFormatingSpecs.cs b/Tests/FluentAssertions.Specs/Execution/AssertionScope.MessageFormatingSpecs.cs index aad22bb341..b773d14759 100644 --- a/Tests/FluentAssertions.Specs/Execution/AssertionScope.MessageFormatingSpecs.cs +++ b/Tests/FluentAssertions.Specs/Execution/AssertionScope.MessageFormatingSpecs.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Text.RegularExpressions; using FluentAssertions.Execution; using Xunit; using Xunit.Sdk; @@ -143,11 +142,13 @@ public void Because_reason_should_threat_parentheses_as_literals_if_no_arguments public void Because_reason_should_inform_about_invalid_parentheses_with_a_default_message() { // Act - Action act = () => 1.Should().Be(2, "use of {} is considered invalid in because parameter with becauseArgs", "additional becauseArgs argument"); + Action act = () => 1.Should().Be(2, "use of {} is considered invalid in because parameter with becauseArgs", + "additional becauseArgs argument"); // Assert act.Should().Throw() - .WithMessage("*because message 'use of {} is considered invalid in because parameter with becauseArgs' could not be formatted with string.Format*"); + .WithMessage( + "*because message 'use of {} is considered invalid in because parameter with becauseArgs' could not be formatted with string.Format*"); } [Fact] @@ -381,6 +382,7 @@ public void Message_should_have_named_placeholder_be_replaced_by_defered_reporta // Assert act.Should().ThrowExactly() .WithMessage("MyValue*\n\nWith MyKey:\nMyValue\n"); + deferredValueInvoked.Should().BeTrue(); } diff --git a/Tests/FluentAssertions.Specs/Execution/AssertionScopeSpecs.cs b/Tests/FluentAssertions.Specs/Execution/AssertionScopeSpecs.cs index 8576323280..f4f4caa1d3 100644 --- a/Tests/FluentAssertions.Specs/Execution/AssertionScopeSpecs.cs +++ b/Tests/FluentAssertions.Specs/Execution/AssertionScopeSpecs.cs @@ -68,6 +68,7 @@ public void When_lazy_version_is_not_disposed_it_should_not_execute_fail_reason_ // Arrange var scope = new AssertionScope(); bool failReasonCalled = false; + AssertionScope.Current .ForCondition(true) .FailWith(() => @@ -241,8 +242,8 @@ public void When_nested_scope_is_disposed_it_passes_reports_to_parent_scope() // Arrange/Act using (var outerScope = new AssertionScope()) { - outerScope.AddReportable("outerReportable", "foo"); - + outerScope.AddReportable("outerReportable", "foo"); + using (var innerScope = new AssertionScope()) { innerScope.AddReportable("innerReportable", "bar"); diff --git a/Tests/FluentAssertions.Specs/Execution/GivenSelectorSpecs.cs b/Tests/FluentAssertions.Specs/Execution/GivenSelectorSpecs.cs index 87ee2297d4..d9808ab3f2 100644 --- a/Tests/FluentAssertions.Specs/Execution/GivenSelectorSpecs.cs +++ b/Tests/FluentAssertions.Specs/Execution/GivenSelectorSpecs.cs @@ -122,6 +122,7 @@ public void When_continuing_a_failed_assertion_chain_consecutive_failure_message Action act = () => { using var _ = new AssertionScope(); + Execute.Assertion .Given(() => "First") .FailWith("First selector") @@ -141,6 +142,7 @@ public void When_continuing_a_failed_assertion_chain_consecutive_failure_message Action act = () => { using var _ = new AssertionScope(); + Execute.Assertion .Given(() => "First") .FailWith("{0} selector", "First") @@ -160,6 +162,7 @@ public void When_continuing_a_failed_assertion_chain_consecutive_failure_message Action act = () => { using var _ = new AssertionScope(); + Execute.Assertion .Given(() => "First") .FailWith("{0} selector", _ => "First") @@ -187,7 +190,8 @@ public void The_failure_message_should_be_preceded_by_the_expectation_after_sele } [Fact] - public void The_failure_message_should_not_be_preceded_by_the_expectation_after_selecting_a_subject_and_clearing_the_expectation() + public void + The_failure_message_should_not_be_preceded_by_the_expectation_after_selecting_a_subject_and_clearing_the_expectation() { // Act Action act = () => Execute.Assertion diff --git a/Tests/FluentAssertions.Specs/Execution/TestFrameworkProviderTests.cs b/Tests/FluentAssertions.Specs/Execution/TestFrameworkProviderTests.cs index d6b1426d9d..50f2b43d37 100644 --- a/Tests/FluentAssertions.Specs/Execution/TestFrameworkProviderTests.cs +++ b/Tests/FluentAssertions.Specs/Execution/TestFrameworkProviderTests.cs @@ -30,6 +30,7 @@ public void When_running_xunit_test_explicitly_it_should_be_detected() { TestFrameworkName = "xunit2" }; + var testFrameworkProvider = new TestFrameworkProvider(configuration); // Act @@ -47,6 +48,7 @@ public void When_running_test_with_unknown_test_framework_it_should_throw() { TestFrameworkName = "foo" }; + var testFrameworkProvider = new TestFrameworkProvider(configuration); // Act @@ -65,6 +67,7 @@ public void When_running_test_with_direct_bound_but_unavailable_test_framework_i { TestFrameworkName = "nspec3" }; + var testFrameworkProvider = new TestFrameworkProvider(configuration); // Act @@ -83,6 +86,7 @@ public void When_running_test_with_late_bound_but_unavailable_test_framework_it_ { TestFrameworkName = "nunit" }; + var testFrameworkProvider = new TestFrameworkProvider(configuration); // Act diff --git a/Tests/FluentAssertions.Specs/Extensions/FluentDateTimeSpecs.cs b/Tests/FluentAssertions.Specs/Extensions/FluentDateTimeSpecs.cs index 8cce42e8c5..3ed0ac6908 100644 --- a/Tests/FluentAssertions.Specs/Extensions/FluentDateTimeSpecs.cs +++ b/Tests/FluentAssertions.Specs/Extensions/FluentDateTimeSpecs.cs @@ -147,7 +147,9 @@ public void When_fluently_specifying_a_datetimeoffset_and_time_it_should_return_ DateTimeOffset dateTime = 10.December(2011).ToDateTimeOffset().At(09, 30, 45, 123, 456, 700); // Assert - dateTime.Should().Be(new DateTimeOffset(2011, 12, 10, 9, 30, 45, 123, TimeSpan.Zero).AddMicroseconds(456).AddNanoseconds(700)); + dateTime.Should().Be(new DateTimeOffset(2011, 12, 10, 9, 30, 45, 123, TimeSpan.Zero).AddMicroseconds(456) + .AddNanoseconds(700)); + dateTime.Microsecond().Should().Be(456); dateTime.Nanosecond().Should().Be(700); } @@ -159,7 +161,7 @@ public void When_fluently_specifying_a_datetime_with_out_of_range_microseconds_i { // Act string expectedParameterName = "microseconds"; - Action act = () => 10.December(2011).At(0, 0, 0, 0, microseconds, 0); + Action act = () => 10.December(2011).At(0, 0, 0, 0, microseconds); // Assert act.Should().Throw() @@ -172,7 +174,7 @@ public void When_fluently_specifying_a_datetime_with_out_of_range_microseconds_i public void When_fluently_specifying_a_datetime_with_inrange_microseconds_it_should_not_throw(int microseconds) { // Act - Action act = () => 10.December(2011).At(0, 0, 0, 0, microseconds, 0); + Action act = () => 10.December(2011).At(0, 0, 0, 0, microseconds); // Assert act.Should().NotThrow(); @@ -211,7 +213,7 @@ public void When_fluently_specifying_a_datetimeoffset_with_out_of_range_microsec { // Act var expectedParameterName = "microseconds"; - Action act = () => 10.December(2011).ToDateTimeOffset().At(0, 0, 0, 0, microseconds, 0); + Action act = () => 10.December(2011).ToDateTimeOffset().At(0, 0, 0, 0, microseconds); // Assert act.Should().Throw() @@ -224,7 +226,7 @@ public void When_fluently_specifying_a_datetimeoffset_with_out_of_range_microsec public void When_fluently_specifying_a_datetimeoffset_with_inrange_microseconds_it_should_not_throw(int microseconds) { // Act - Action act = () => 10.December(2011).ToDateTimeOffset().At(0, 0, 0, 0, microseconds, 0); + Action act = () => 10.December(2011).ToDateTimeOffset().At(0, 0, 0, 0, microseconds); // Assert act.Should().NotThrow(); diff --git a/Tests/FluentAssertions.Specs/Extensions/ObjectExtensionsSpecs.cs b/Tests/FluentAssertions.Specs/Extensions/ObjectExtensionsSpecs.cs index ebbb284538..c999833eb6 100644 --- a/Tests/FluentAssertions.Specs/Extensions/ObjectExtensionsSpecs.cs +++ b/Tests/FluentAssertions.Specs/Extensions/ObjectExtensionsSpecs.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using FluentAssertions.Common; -using FluentAssertions.Specs.Common; using Xunit; namespace FluentAssertions.Specs.Extensions; @@ -59,9 +58,10 @@ public void When_comparing_a_numeric_to_a_numeric_it_should_succeed(object actua public static IEnumerable GetNumericAndNumericData() { - return from x in GetNumericIConvertibles() - from y in GetNumericIConvertibles() - select new[] { x, y }; + return + from x in GetNumericIConvertibles() + from y in GetNumericIConvertibles() + select new[] { x, y }; } [Theory] @@ -81,8 +81,8 @@ public void When_comparing_a_non_numeric_to_a_numeric_it_should_fail(object actu public static IEnumerable GetNonNumericAndNumericData() { return from x in GetNonNumericIConvertibles() - from y in GetNumericIConvertibles() - select new[] { x, y }; + from y in GetNumericIConvertibles() + select new[] { x, y }; } [Theory] @@ -102,8 +102,8 @@ public void When_comparing_a_numeric_to_a_non_numeric_it_should_fail(object actu public static IEnumerable GetNumericAndNonNumericData() { return from x in GetNumericIConvertibles() - from y in GetNonNumericIConvertibles() - select new[] { x, y }; + from y in GetNonNumericIConvertibles() + select new[] { x, y }; } [Theory] @@ -123,10 +123,12 @@ public void When_comparing_a_non_numeric_to_a_non_numeric_it_should_fail(object public static IEnumerable GetNonNumericAndNonNumericData() { object[] nonNumerics = GetNonNumericIConvertibles(); - return from x in nonNumerics - from y in nonNumerics - where x != y - select new[] { x, y }; + + return + from x in nonNumerics + from y in nonNumerics + where x != y + select new[] { x, y }; } private static object[] GetNumericIConvertibles() diff --git a/Tests/FluentAssertions.Specs/Formatting/DateTimeOffsetValueFormatterSpecs.cs b/Tests/FluentAssertions.Specs/Formatting/DateTimeOffsetValueFormatterSpecs.cs index 0987c2c63e..620d54c4b6 100644 --- a/Tests/FluentAssertions.Specs/Formatting/DateTimeOffsetValueFormatterSpecs.cs +++ b/Tests/FluentAssertions.Specs/Formatting/DateTimeOffsetValueFormatterSpecs.cs @@ -32,7 +32,7 @@ public void When_the_offset_is_not_relevant_it_should_not_be_included_in_the_out public void When_the_offset_is_negative_it_should_include_it_in_the_output() { // Arrange - DateTimeOffset date = new DateTimeOffset(1973, 9, 20, 12, 59, 59, -3.Hours()); + DateTimeOffset date = new(1973, 9, 20, 12, 59, 59, -3.Hours()); // Act string result = Formatter.ToString(date); @@ -110,7 +110,8 @@ public void When_a_full_date_and_time_is_specified_all_parts_should_be_included_ [InlineData("0001-02-03 00:00:00.0000100", "<0001-02-03 00:00:00.000010>")] [InlineData("0001-02-03 00:00:00.0000010", "<0001-02-03 00:00:00.000001>")] [InlineData("0001-02-03 00:00:00.0000001", "<0001-02-03 00:00:00.0000001>")] - public void When_datetime_components_are_not_relevant_they_should_not_be_included_in_the_output(string actual, string expected) + public void When_datetime_components_are_not_relevant_they_should_not_be_included_in_the_output(string actual, + string expected) { // Arrange var value = DateTime.Parse(actual, CultureInfo.InvariantCulture); @@ -138,7 +139,8 @@ public void When_datetime_components_are_not_relevant_they_should_not_be_include [InlineData("0001-02-03 00:00:00.0000100 +1", "<0001-02-03 00:00:00.000010 +1h>")] [InlineData("0001-02-03 00:00:00.0000010 +1", "<0001-02-03 00:00:00.000001 +1h>")] [InlineData("0001-02-03 00:00:00.0000001 +1", "<0001-02-03 00:00:00.0000001 +1h>")] - public void When_datetimeoffset_components_are_not_relevant_they_should_not_be_included_in_the_output(string actual, string expected) + public void When_datetimeoffset_components_are_not_relevant_they_should_not_be_included_in_the_output(string actual, + string expected) { // Arrange var value = DateTimeOffset.Parse(actual, CultureInfo.InvariantCulture); diff --git a/Tests/FluentAssertions.Specs/Formatting/FormatterSpecs.cs b/Tests/FluentAssertions.Specs/Formatting/FormatterSpecs.cs index fb2fdacee3..9ad739ebbf 100644 --- a/Tests/FluentAssertions.Specs/Formatting/FormatterSpecs.cs +++ b/Tests/FluentAssertions.Specs/Formatting/FormatterSpecs.cs @@ -36,6 +36,7 @@ public void When_the_same_object_appears_twice_in_the_graph_at_different_paths() { // Arrange var a = new A(); + var b = new B { X = a, @@ -160,13 +161,13 @@ public void When_the_object_is_a_generic_type_without_custom_string_representati // Arrange var stuff = new List> { - new Stuff + new() { StuffId = 1, Description = "Stuff_1", Children = new List { 1, 2, 3, 4 } }, - new Stuff + new() { StuffId = 2, Description = "Stuff_2", @@ -176,13 +177,13 @@ public void When_the_object_is_a_generic_type_without_custom_string_representati var expectedStuff = new List> { - new Stuff + new() { StuffId = 1, Description = "Stuff_1", Children = new List { 1, 2, 3, 4 } }, - new Stuff + new() { StuffId = 2, Description = "WRONG_DESCRIPTION", @@ -224,6 +225,7 @@ public void int maxDepth = 10; int iterations = (maxDepth / 2) + 1; // Each iteration adds two levels of depth to the graph + foreach (int i in Enumerable.Range(0, iterations)) { var newHead = new Node(); @@ -249,6 +251,7 @@ public void When_the_maximum_recursion_depth_is_never_reached_it_should_render_t var node = head; int iterations = 10; + foreach (int i in Enumerable.Range(0, iterations)) { var newHead = new Node(); @@ -609,7 +612,7 @@ public void When_formatting_a_dictionary_it_should_format_keys_and_values() // Arrange var subject = new Dictionary { - [new() { KeyProp = 13 }] = new() { ValueProp = 37 } + [new MyKey { KeyProp = 13 }] = new() { ValueProp = 37 } }; // Act @@ -646,13 +649,14 @@ public void When_formatting_a_large_dictionary_it_should_limit_the_number_of_for } [Fact] - public void When_formatting_multiple_items_with_a_custom_string_representation_using_line_breaks_it_should_end_lines_with_a_comma() + public void + When_formatting_multiple_items_with_a_custom_string_representation_using_line_breaks_it_should_end_lines_with_a_comma() { // Arrange var subject = new[] { typeof(A), typeof(B) }; // Act - string result = Formatter.ToString(subject, new FormattingOptions { UseLineBreaks = true } ); + string result = Formatter.ToString(subject, new FormattingOptions { UseLineBreaks = true }); // Assert result.Should().Contain($"FluentAssertions.Specs.Formatting.FormatterSpecs+A, {Environment.NewLine}"); @@ -707,7 +711,7 @@ public void When_a_base_class_has_a_custom_formatter_it_should_override_the_defa // Arrange Configuration.Current.ValueFormatterDetectionMode = ValueFormatterDetectionMode.Scan; - var subject = new SomeClassInheritedFromClassWithCustomFormatterLvl1() + var subject = new SomeClassInheritedFromClassWithCustomFormatterLvl1 { Property = "SomeValue" }; @@ -725,7 +729,7 @@ public void When_there_are_multiple_custom_formatters_it_should_select_a_more_sp // Arrange Configuration.Current.ValueFormatterDetectionMode = ValueFormatterDetectionMode.Scan; - var subject = new SomeClassInheritedFromClassWithCustomFormatterLvl2() + var subject = new SomeClassInheritedFromClassWithCustomFormatterLvl2 { Property = "SomeValue" }; @@ -743,7 +747,7 @@ public void When_a_base_class_has_multiple_custom_formatters_it_should_work_the_ // Arrange Configuration.Current.ValueFormatterDetectionMode = ValueFormatterDetectionMode.Scan; - var subject = new SomeClassInheritedFromClassWithCustomFormatterLvl3() + var subject = new SomeClassInheritedFromClassWithCustomFormatterLvl3 { Property = "SomeValue" }; @@ -889,10 +893,10 @@ public void When_defining_a_custom_value_formatter_it_should_respect_the_overrid // Assert str.Should().Match( -"*CustomClass" + Environment.NewLine + -"{" + Environment.NewLine + -" IntProperty = 0" + Environment.NewLine + -"}*"); + "*CustomClass" + Environment.NewLine + + "{" + Environment.NewLine + + " IntProperty = 0" + Environment.NewLine + + "}*"); } private class CustomClass @@ -925,8 +929,8 @@ public void When_defining_a_custom_enumerable_value_formatter_it_should_respect_ // Arrange var values = new CustomClass[] { - new CustomClass { IntProperty = 1 }, - new CustomClass { IntProperty = 2 } + new() { IntProperty = 1 }, + new() { IntProperty = 2 } }; var formatter = new SingleItemValueFormatter(); @@ -936,11 +940,11 @@ public void When_defining_a_custom_enumerable_value_formatter_it_should_respect_ string str = Formatter.ToString(values); str.Should().Match( -"{*FluentAssertions*FormatterSpecs+CustomClass" + Environment.NewLine + -" {" + Environment.NewLine + -" IntProperty = 1, " + Environment.NewLine + -" StringProperty = " + Environment.NewLine + -" },*…1 more…*}*"); + "{*FluentAssertions*FormatterSpecs+CustomClass" + Environment.NewLine + + " {" + Environment.NewLine + + " IntProperty = 1, " + Environment.NewLine + + " StringProperty = " + Environment.NewLine + + " },*…1 more…*}*"); } private class SingleItemValueFormatter : EnumerableValueFormatter @@ -966,7 +970,9 @@ public FormatterScope(IValueFormatter formatter) // Due to the tests that call Configuration.Current [CollectionDefinition("FormatterSpecs", DisableParallelization = true)] -public class FormatterSpecsDefinition { } +public class FormatterSpecsDefinition +{ +} internal class ExceptionThrowingClass { @@ -995,7 +1001,7 @@ public Node() Children = new List(); } - public static Node Default { get; } = new Node(); + public static Node Default { get; } = new(); public List Children { get; set; } } diff --git a/Tests/FluentAssertions.Specs/Formatting/MultidimensionalArrayFormatterSpecs.cs b/Tests/FluentAssertions.Specs/Formatting/MultidimensionalArrayFormatterSpecs.cs index 96fb50dc0a..d9ab77b8b6 100644 --- a/Tests/FluentAssertions.Specs/Formatting/MultidimensionalArrayFormatterSpecs.cs +++ b/Tests/FluentAssertions.Specs/Formatting/MultidimensionalArrayFormatterSpecs.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using FluentAssertions.Formatting; using Xunit; @@ -28,7 +27,7 @@ public void When_formatting_a_multi_dimensional_array_it_should_show_structure(o "{empty}" }, { - new int[,] + new[,] { { 1, 2 }, { 3, 4 } @@ -36,7 +35,7 @@ public void When_formatting_a_multi_dimensional_array_it_should_show_structure(o "{{1, 2}, {3, 4}}" }, { - new int[,,] + new[,,] { { { 1, 2, 3 }, @@ -55,16 +54,17 @@ public void When_formatting_a_multi_dimensional_array_it_should_show_structure(o public void When_formatting_a_multi_dimensional_array_with_bounds_it_should_show_structure() { // Arrange - var lengthsArray = new int[] { 2, 3, 4 }; - var boundsArray = new int[] { 1, 5, 7 }; + var lengthsArray = new[] { 2, 3, 4 }; + var boundsArray = new[] { 1, 5, 7 }; var value = Array.CreateInstance(typeof(string), lengthsArray, boundsArray); + for (int i = value.GetLowerBound(0); i <= value.GetUpperBound(0); i++) { for (int j = value.GetLowerBound(1); j <= value.GetUpperBound(1); j++) { for (int k = value.GetLowerBound(2); k <= value.GetUpperBound(2); k++) { - var indices = new int[] { i, j, k }; + var indices = new[] { i, j, k }; value.SetValue($"{i}-{j}-{k}", indices); } } @@ -74,6 +74,8 @@ public void When_formatting_a_multi_dimensional_array_with_bounds_it_should_show string result = Formatter.ToString(value); // Assert - result.Should().Match("{{{'1-5-7', '1-5-8', '1-5-9', '1-5-10'}, {'1-6-7', '1-6-8', '1-6-9', '1-6-10'}, {'1-7-7', '1-7-8', '1-7-9', '1-7-10'}}, {{'2-5-7', '2-5-8', '2-5-9', '2-5-10'}, {'2-6-7', '2-6-8', '2-6-9', '2-6-10'}, {'2-7-7', '2-7-8', '2-7-9', '2-7-10'}}}".Replace("'", "\"")); + result.Should().Match( + "{{{'1-5-7', '1-5-8', '1-5-9', '1-5-10'}, {'1-6-7', '1-6-8', '1-6-9', '1-6-10'}, {'1-7-7', '1-7-8', '1-7-9', '1-7-10'}}, {{'2-5-7', '2-5-8', '2-5-9', '2-5-10'}, {'2-6-7', '2-6-8', '2-6-9', '2-6-10'}, {'2-7-7', '2-7-8', '2-7-9', '2-7-10'}}}" + .Replace("'", "\"")); } } diff --git a/Tests/FluentAssertions.Specs/Formatting/PredicateLambdaExpressionValueFormatterSpecs.cs b/Tests/FluentAssertions.Specs/Formatting/PredicateLambdaExpressionValueFormatterSpecs.cs index 3366c0b144..d09dcd79cf 100644 --- a/Tests/FluentAssertions.Specs/Formatting/PredicateLambdaExpressionValueFormatterSpecs.cs +++ b/Tests/FluentAssertions.Specs/Formatting/PredicateLambdaExpressionValueFormatterSpecs.cs @@ -22,7 +22,8 @@ public void When_first_level_properties_are_tested_for_equality_against_constant } [Fact] - public void When_first_level_properties_are_tested_for_equality_against_constant_expressions_then_output_should_contain_values_of_constant_expressions() + public void + When_first_level_properties_are_tested_for_equality_against_constant_expressions_then_output_should_contain_values_of_constant_expressions() { // Arrange var expectedText = "foo"; diff --git a/Tests/FluentAssertions.Specs/Formatting/TimeSpanFormatterSpecs.cs b/Tests/FluentAssertions.Specs/Formatting/TimeSpanFormatterSpecs.cs index 2221e1036c..6b7b4f6884 100644 --- a/Tests/FluentAssertions.Specs/Formatting/TimeSpanFormatterSpecs.cs +++ b/Tests/FluentAssertions.Specs/Formatting/TimeSpanFormatterSpecs.cs @@ -64,7 +64,8 @@ public void When_min_time_span_it_should_return_a_literal() [InlineData("-01:02:03.123456", "-1h, 2m, 3s, 123ms and 456.0µs")] [InlineData("01:02:03.1234567", "1h, 2m, 3s, 123ms and 456.7µs")] [InlineData("-01:02:03.1234567", "-1h, 2m, 3s, 123ms and 456.7µs")] - public void When_timespan_components_are_not_relevant_they_should_not_be_included_in_the_output(string actual, string expected) + public void When_timespan_components_are_not_relevant_they_should_not_be_included_in_the_output(string actual, + string expected) { // Arrange var value = TimeSpan.Parse(actual, CultureInfo.InvariantCulture); diff --git a/Tests/FluentAssertions.Specs/Numeric/ComparableSpecs.cs b/Tests/FluentAssertions.Specs/Numeric/ComparableSpecs.cs index 4a0a7338d1..5fd324b210 100644 --- a/Tests/FluentAssertions.Specs/Numeric/ComparableSpecs.cs +++ b/Tests/FluentAssertions.Specs/Numeric/ComparableSpecs.cs @@ -111,7 +111,8 @@ public void When_a_value_is_not_equal_to_one_of_the_specified_values_it_should_t var value = new EquatableOfInt(3); // Act - Action act = () => value.Should().BeOneOf(new[] { new EquatableOfInt(4), new EquatableOfInt(5) }, "because those are the valid {0}", "values"); + Action act = () => value.Should().BeOneOf(new[] { new EquatableOfInt(4), new EquatableOfInt(5) }, + "because those are the valid {0}", "values"); // Assert act @@ -190,6 +191,7 @@ public void When_two_instances_are_equivalent_due_to_exclusion_it_should_succeed { // Arrange var subject = new ComparableCustomer(42); + var expected = new AnotherCustomerDto(42) { SomeOtherProperty = 1337 @@ -221,6 +223,7 @@ public void When_two_instances_are_not_equivalent_it_should_throw() { // Arrange var subject = new ComparableCustomer(42); + var expected = new AnotherCustomerDto(42) { SomeOtherProperty = 1337 diff --git a/Tests/FluentAssertions.Specs/Numeric/NumericAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Numeric/NumericAssertionSpecs.cs index 79eebfa730..71aecb389b 100644 --- a/Tests/FluentAssertions.Specs/Numeric/NumericAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Numeric/NumericAssertionSpecs.cs @@ -3980,6 +3980,7 @@ public void Should_throw_a_helpful_error_when_accidentally_using_equals() Action action = () => value.Should().Equals(1); // Assert - action.Should().Throw().WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); + action.Should().Throw() + .WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); } } diff --git a/Tests/FluentAssertions.Specs/Numeric/NumericDifferenceAssertionsSpecs.cs b/Tests/FluentAssertions.Specs/Numeric/NumericDifferenceAssertionsSpecs.cs index 6bf01565eb..397a766318 100644 --- a/Tests/FluentAssertions.Specs/Numeric/NumericDifferenceAssertionsSpecs.cs +++ b/Tests/FluentAssertions.Specs/Numeric/NumericDifferenceAssertionsSpecs.cs @@ -37,7 +37,8 @@ public void The_difference_between_ints_is_included_in_the_message(int value, in // Assert act .Should().Throw() - .WithMessage($"Expected value to be {expected} because we want to test the failure message, but found {value} (difference of {expectedDifference})."); + .WithMessage( + $"Expected value to be {expected} because we want to test the failure message, but found {value} (difference of {expectedDifference})."); } [Theory] @@ -94,7 +95,8 @@ public void The_difference_between_null_and_int_is_not_included_in_the_message() [InlineData(20, 50, -30)] [InlineData(123, -123, 246)] [InlineData(-123, 123, -246)] - public void The_difference_between_nullable_ints_is_included_in_the_message(int? value, int expected, int expectedDifference) + public void The_difference_between_nullable_ints_is_included_in_the_message(int? value, int expected, + int expectedDifference) { // Act Action act = () => @@ -103,7 +105,8 @@ public void The_difference_between_nullable_ints_is_included_in_the_message(int? // Assert act .Should().Throw() - .WithMessage($"Expected value to be {expected} because we want to test the failure message, but found {value} (difference of {expectedDifference})."); + .WithMessage( + $"Expected value to be {expected} because we want to test the failure message, but found {value} (difference of {expectedDifference})."); } [Fact] @@ -120,7 +123,8 @@ public void The_difference_between_nullable_uints_is_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected value to be 19u because we want to test the failure message, but found 29u (difference of 10)."); + .WithMessage( + "Expected value to be 19u because we want to test the failure message, but found 29u (difference of 10)."); } [Theory] @@ -135,7 +139,8 @@ public void The_difference_between_small_longs_is_not_included_in_the_message(lo // Assert act .Should().Throw() - .WithMessage($"Expected value to be {expected}L because we want to test the failure message, but found {value}L."); + .WithMessage( + $"Expected value to be {expected}L because we want to test the failure message, but found {value}L."); } [Theory] @@ -150,7 +155,8 @@ public void The_difference_between_longs_is_included_in_the_message(long value, // Assert act .Should().Throw() - .WithMessage($"Expected value to be {expected}L because we want to test the failure message, but found {value}L (difference of {expectedDifference})."); + .WithMessage( + $"Expected value to be {expected}L because we want to test the failure message, but found {value}L (difference of {expectedDifference})."); } [Theory] @@ -165,13 +171,15 @@ public void The_difference_between_small_nullable_longs_is_not_included_in_the_m // Assert act .Should().Throw() - .WithMessage($"Expected value to be {expected}L because we want to test the failure message, but found {value}L."); + .WithMessage( + $"Expected value to be {expected}L because we want to test the failure message, but found {value}L."); } [Theory] [InlineData(50L, 20, 30)] [InlineData(20L, 50, -30)] - public void The_difference_between_nullable_longs_is_included_in_the_message(long? value, long expected, long expectedDifference) + public void The_difference_between_nullable_longs_is_included_in_the_message(long? value, long expected, + long expectedDifference) { // Act Action act = () => @@ -180,7 +188,8 @@ public void The_difference_between_nullable_longs_is_included_in_the_message(lon // Assert act .Should().Throw() - .WithMessage($"Expected value to be {expected}L because we want to test the failure message, but found {value}L (difference of {expectedDifference})."); + .WithMessage( + $"Expected value to be {expected}L because we want to test the failure message, but found {value}L (difference of {expectedDifference})."); } [Theory] @@ -195,13 +204,15 @@ public void The_difference_between_small_shorts_is_not_included_in_the_message(s // Assert act .Should().Throw() - .WithMessage($"Expected value to be {expected}s because we want to test the failure message, but found {value}s."); + .WithMessage( + $"Expected value to be {expected}s because we want to test the failure message, but found {value}s."); } [Theory] [InlineData(50, 20, 30)] [InlineData(20, 50, -30)] - public void The_difference_between_shorts_is_included_in_the_message(short value, short expected, short expectedDifference) + public void The_difference_between_shorts_is_included_in_the_message(short value, short expected, + short expectedDifference) { // Act Action act = () => @@ -210,7 +221,8 @@ public void The_difference_between_shorts_is_included_in_the_message(short value // Assert act .Should().Throw() - .WithMessage($"Expected value to be {expected}s because we want to test the failure message, but found {value}s (difference of {expectedDifference})."); + .WithMessage( + $"Expected value to be {expected}s because we want to test the failure message, but found {value}s (difference of {expectedDifference})."); } [Fact] @@ -244,7 +256,8 @@ public void The_difference_between_nullable_shorts_is_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected value to be 2s because we want to test the failure message, but found 15s (difference of 13)."); + .WithMessage( + "Expected value to be 2s because we want to test the failure message, but found 15s (difference of 13)."); } [Fact] @@ -278,7 +291,8 @@ public void The_difference_between_ulongs_is_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected value to be 20UL because we want to test the failure message, but found 50UL (difference of 30)."); + .WithMessage( + "Expected value to be 20UL because we want to test the failure message, but found 50UL (difference of 30)."); } [Fact] @@ -312,7 +326,8 @@ public void The_difference_between_nullable_ulongs_is_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected value to be 20UL because we want to test the failure message, but found 50UL (difference of 30)."); + .WithMessage( + "Expected value to be 20UL because we want to test the failure message, but found 50UL (difference of 30)."); } [Fact] @@ -329,7 +344,8 @@ public void The_difference_between_ushorts_is_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected value to be 2us because we want to test the failure message, but found 11us (difference of 9)."); + .WithMessage( + "Expected value to be 2us because we want to test the failure message, but found 11us (difference of 9)."); } [Fact] @@ -346,7 +362,8 @@ public void The_difference_between_doubles_is_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected value to be 1.0 because we want to test the failure message, but found 1.5 (difference of 0.5)."); + .WithMessage( + "Expected value to be 1.0 because we want to test the failure message, but found 1.5 (difference of 0.5)."); } [Fact] @@ -363,7 +380,8 @@ public void The_difference_between_nullable_doubles_is_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected value to be 1.0 because we want to test the failure message, but found 1.5 (difference of 0.5)."); + .WithMessage( + "Expected value to be 1.0 because we want to test the failure message, but found 1.5 (difference of 0.5)."); } [Fact] @@ -380,7 +398,8 @@ public void The_difference_between_floats_is_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected value to be 1F because we want to test the failure message, but found 1.5F (difference of 0.5)."); + .WithMessage( + "Expected value to be 1F because we want to test the failure message, but found 1.5F (difference of 0.5)."); } [Fact] @@ -397,7 +416,8 @@ public void The_difference_between_nullable_floats_is_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected value to be 1F because we want to test the failure message, but found 1.5F (difference of 0.5)."); + .WithMessage( + "Expected value to be 1F because we want to test the failure message, but found 1.5F (difference of 0.5)."); } [Fact] @@ -414,7 +434,8 @@ public void The_difference_between_decimals_is_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected value to be 1m because we want to test the failure message, but found 1.5m (difference of 0.5)."); + .WithMessage( + "Expected value to be 1m because we want to test the failure message, but found 1.5m (difference of 0.5)."); } [Fact] @@ -431,7 +452,8 @@ public void The_difference_between_nullable_decimals_is_included_in_the_message( // Assert act .Should().Throw() - .WithMessage("Expected value to be 1m because we want to test the failure message, but found 1.5m (difference of 0.5)."); + .WithMessage( + "Expected value to be 1m because we want to test the failure message, but found 1.5m (difference of 0.5)."); } [Fact] @@ -448,7 +470,8 @@ public void The_difference_between_sbytes_is_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected value to be 3y because we want to test the failure message, but found 1y (difference of -2)."); + .WithMessage( + "Expected value to be 3y because we want to test the failure message, but found 1y (difference of -2)."); } [Fact] @@ -465,7 +488,8 @@ public void The_difference_between_nullable_sbytes_is_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected value to be 3y because we want to test the failure message, but found 1y (difference of -2)."); + .WithMessage( + "Expected value to be 3y because we want to test the failure message, but found 1y (difference of -2)."); } } @@ -519,7 +543,8 @@ public void The_difference_between_ints_is_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected value to be less than 22 because we want to test the failure message, but found 52 (difference of 30)."); + .WithMessage( + "Expected value to be less than 22 because we want to test the failure message, but found 52 (difference of 30)."); } } @@ -539,7 +564,8 @@ public void The_difference_between_small_ints_is_not_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected value to be less than or equal to 2 because we want to test the failure message, but found 4."); + .WithMessage( + "Expected value to be less than or equal to 2 because we want to test the failure message, but found 4."); } [Fact] @@ -556,7 +582,8 @@ public void The_difference_between_ints_is_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected value to be less than or equal to 22 because we want to test the failure message, but found 52 (difference of 30)."); + .WithMessage( + "Expected value to be less than or equal to 22 because we want to test the failure message, but found 52 (difference of 30)."); } } @@ -610,7 +637,8 @@ public void The_difference_between_ints_is_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected value to be greater than 52 because we want to test the failure message, but found 22 (difference of -30)."); + .WithMessage( + "Expected value to be greater than 52 because we want to test the failure message, but found 22 (difference of -30)."); } [Fact] @@ -661,7 +689,8 @@ public void The_difference_between_equal_floats_is_not_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected value to be greater than 2.3F because we want to test the failure message, but found 2.3F."); + .WithMessage( + "Expected value to be greater than 2.3F because we want to test the failure message, but found 2.3F."); } [Fact] @@ -678,7 +707,8 @@ public void The_difference_between_equal_ushorts_is_not_included_in_the_message( // Assert act .Should().Throw() - .WithMessage("Expected value to be greater than 11us because we want to test the failure message, but found 11us."); + .WithMessage( + "Expected value to be greater than 11us because we want to test the failure message, but found 11us."); } [Fact] @@ -712,7 +742,8 @@ public void The_difference_between_equal_nullable_ulongs_is_not_included_in_the_ // Assert act .Should().Throw() - .WithMessage("Expected value to be greater than 15UL because we want to test the failure message, but found 15UL."); + .WithMessage( + "Expected value to be greater than 15UL because we want to test the failure message, but found 15UL."); } } @@ -732,7 +763,8 @@ public void The_difference_between_small_ints_is_not_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected value to be greater than or equal to 4 because we want to test the failure message, but found 2."); + .WithMessage( + "Expected value to be greater than or equal to 4 because we want to test the failure message, but found 2."); } [Fact] @@ -749,7 +781,8 @@ public void The_difference_between_ints_is_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected value to be greater than or equal to 52 because we want to test the failure message, but found 22 (difference of -30)."); + .WithMessage( + "Expected value to be greater than or equal to 52 because we want to test the failure message, but found 22 (difference of -30)."); } } @@ -823,7 +856,8 @@ public void The_difference_between_overflowed_longs_is_included_in_the_message() // Assert act .Should().Throw() - .WithMessage("Expected long.MinValue to be 9223372036854775807L*found -9223372036854775808L (difference of -18446744073709551615)."); + .WithMessage( + "Expected long.MinValue to be 9223372036854775807L*found -9223372036854775808L (difference of -18446744073709551615)."); } [Fact] @@ -839,7 +873,8 @@ public void The_difference_between_overflowed_nullable_longs_is_included_in_the_ // Assert act .Should().Throw() - .WithMessage("Expected minValue to be 9223372036854775807L*found -9223372036854775808L (difference of -18446744073709551615)."); + .WithMessage( + "Expected minValue to be 9223372036854775807L*found -9223372036854775808L (difference of -18446744073709551615)."); } [Fact] @@ -852,7 +887,8 @@ public void The_difference_between_overflowed_ulongs_is_included_in_the_message( // Assert act .Should().Throw() - .WithMessage("Expected ulong.MinValue to be 18446744073709551615UL*found 0UL (difference of -18446744073709551615)."); + .WithMessage( + "Expected ulong.MinValue to be 18446744073709551615UL*found 0UL (difference of -18446744073709551615)."); } [Fact] @@ -881,7 +917,8 @@ public void The_difference_between_overflowed_decimals_is_not_included_in_the_me // Assert act .Should().Throw() - .WithMessage("Expected decimal.MinValue to be 79228162514264337593543950335M*found -79228162514264337593543950335M."); + .WithMessage( + "Expected decimal.MinValue to be 79228162514264337593543950335M*found -79228162514264337593543950335M."); } [Fact] diff --git a/Tests/FluentAssertions.Specs/Primitives/BooleanAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Primitives/BooleanAssertionSpecs.cs index 7350062612..f956cb55af 100644 --- a/Tests/FluentAssertions.Specs/Primitives/BooleanAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Primitives/BooleanAssertionSpecs.cs @@ -162,7 +162,8 @@ public void Should_throw_a_helpful_error_when_accidentally_using_equals() Action action = () => true.Should().Equals(true); // Assert - action.Should().Throw().WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); + action.Should().Throw() + .WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); } } diff --git a/Tests/FluentAssertions.Specs/Primitives/DateOnlyAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Primitives/DateOnlyAssertionSpecs.cs index 823a98b013..edbd61a548 100644 --- a/Tests/FluentAssertions.Specs/Primitives/DateOnlyAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Primitives/DateOnlyAssertionSpecs.cs @@ -3,7 +3,6 @@ using Xunit.Sdk; #if NET6_0_OR_GREATER - namespace FluentAssertions.Specs.Primitives; public class DateOnlyAssertionSpecs @@ -784,7 +783,8 @@ public void Should_throw_a_helpful_error_when_accidentally_using_equals() Action action = () => someDateOnly.Should().Equals(someDateOnly); // Assert - action.Should().Throw().WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); + action.Should().Throw() + .WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); } } } diff --git a/Tests/FluentAssertions.Specs/Primitives/DateTimeAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Primitives/DateTimeAssertionSpecs.cs index 1b83c880d8..f8cb8105df 100644 --- a/Tests/FluentAssertions.Specs/Primitives/DateTimeAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Primitives/DateTimeAssertionSpecs.cs @@ -133,8 +133,8 @@ public class Be public void Should_succeed_when_asserting_datetime_value_is_equal_to_the_same_value() { // Arrange - DateTime dateTime = new DateTime(2016, 06, 04); - DateTime sameDateTime = new DateTime(2016, 06, 04); + DateTime dateTime = new(2016, 06, 04); + DateTime sameDateTime = new(2016, 06, 04); // Act Action act = () => dateTime.Should().Be(sameDateTime); @@ -235,7 +235,7 @@ public void When_a_nullable_date_time_is_equal_to_a_normal_date_time_but_the_kin { // Arrange DateTime? nullableDateTime = new DateTime(2014, 4, 20, 9, 11, 0, DateTimeKind.Unspecified); - DateTime normalDateTime = new DateTime(2014, 4, 20, 9, 11, 0, DateTimeKind.Utc); + DateTime normalDateTime = new(2014, 4, 20, 9, 11, 0, DateTimeKind.Utc); // Act Action action = () => @@ -249,8 +249,8 @@ public void When_a_nullable_date_time_is_equal_to_a_normal_date_time_but_the_kin public void When_two_date_times_are_equal_but_the_kinds_differ_it_should_still_succeed() { // Arrange - DateTime dateTimeA = new DateTime(2014, 4, 20, 9, 11, 0, DateTimeKind.Unspecified); - DateTime dateTimeB = new DateTime(2014, 4, 20, 9, 11, 0, DateTimeKind.Utc); + DateTime dateTimeA = new(2014, 4, 20, 9, 11, 0, DateTimeKind.Unspecified); + DateTime dateTimeB = new(2014, 4, 20, 9, 11, 0, DateTimeKind.Utc); // Act Action action = () => @@ -302,7 +302,8 @@ public void Should_fail_with_descriptive_message_when_asserting_datetime_null_va // Assert action.Should().Throw() - .WithMessage("Expected nullableDateTime to be <2016-06-04> because we want to test the failure message, but found ."); + .WithMessage( + "Expected nullableDateTime to be <2016-06-04> because we want to test the failure message, but found ."); } } @@ -312,8 +313,8 @@ public class NotBe public void Should_succeed_when_asserting_datetime_value_is_not_equal_to_a_different_value() { // Arrange - DateTime dateTime = new DateTime(2016, 06, 04); - DateTime otherDateTime = new DateTime(2016, 06, 05); + DateTime dateTime = new(2016, 06, 04); + DateTime otherDateTime = new(2016, 06, 05); // Act Action act = () => dateTime.Should().NotBe(otherDateTime); @@ -349,7 +350,8 @@ public void Should_fail_when_asserting_datetime_value_is_not_equal_to_the_same_v // Assert act.Should().Throw() - .WithMessage("Expected dateTime not to be <2012-03-10 10:00:00> because we want to test the failure message, but it is."); + .WithMessage( + "Expected dateTime not to be <2012-03-10 10:00:00> because we want to test the failure message, but it is."); } [Fact] @@ -365,7 +367,8 @@ public void When_datetime_value_is_not_equal_to_the_same_nullable_value_notbe_sh // Assert act.Should().Throw() - .WithMessage("Expected dateTime not to be <2012-03-10 10:00:00> because we want to test the failure message, but it is."); + .WithMessage( + "Expected dateTime not to be <2012-03-10 10:00:00> because we want to test the failure message, but it is."); } } @@ -488,7 +491,8 @@ public void When_asserting_subject_datetime_is_close_to_another_value_that_is_la } [Fact] - public void When_asserting_subject_datetime_is_close_to_another_value_that_is_later_by_more_than_a_20ms_timespan_it_should_throw() + public void + When_asserting_subject_datetime_is_close_to_another_value_that_is_later_by_more_than_a_20ms_timespan_it_should_throw() { // Arrange DateTime time = 13.March(2012).At(12, 15, 30, 979); @@ -663,7 +667,8 @@ public void When_asserting_subject_datetime_is_not_close_to_a_later_datetime_it_ // Assert act.Should().Throw() - .WithMessage("Did not expect time to be within 20ms from <2016-06-04 12:15:31>, but it was <2016-06-04 12:15:30.980>."); + .WithMessage( + "Did not expect time to be within 20ms from <2016-06-04 12:15:31>, but it was <2016-06-04 12:15:30.980>."); } [Fact] @@ -678,7 +683,8 @@ public void When_asserting_subject_datetime_is_not_close_to_an_earlier_datetime_ // Assert act.Should().Throw() - .WithMessage("Did not expect time to be within 20ms from <2016-06-04 12:15:31>, but it was <2016-06-04 12:15:31.020>."); + .WithMessage( + "Did not expect time to be within 20ms from <2016-06-04 12:15:31>, but it was <2016-06-04 12:15:31.020>."); } [Fact] @@ -693,11 +699,13 @@ public void When_asserting_subject_datetime_is_not_close_to_an_earlier_datetime_ // Assert act.Should().Throw() - .WithMessage("Did not expect time to be within 20ms from <2016-06-04 12:15:31>, but it was <2016-06-04 12:15:31.020>."); + .WithMessage( + "Did not expect time to be within 20ms from <2016-06-04 12:15:31>, but it was <2016-06-04 12:15:31.020>."); } [Fact] - public void When_asserting_subject_datetime_is_not_close_to_another_value_that_is_later_by_more_than_20ms_it_should_succeed() + public void + When_asserting_subject_datetime_is_not_close_to_another_value_that_is_later_by_more_than_20ms_it_should_succeed() { // Arrange DateTime time = 13.March(2012).At(12, 15, 30, 979); @@ -711,7 +719,8 @@ public void When_asserting_subject_datetime_is_not_close_to_another_value_that_i } [Fact] - public void When_asserting_subject_datetime_is_not_close_to_another_value_that_is_earlier_by_more_than_20ms_it_should_succeed() + public void + When_asserting_subject_datetime_is_not_close_to_another_value_that_is_earlier_by_more_than_20ms_it_should_succeed() { // Arrange DateTime time = 13.March(2012).At(12, 15, 31, 021); @@ -736,7 +745,8 @@ public void When_asserting_subject_datetime_is_not_close_to_an_earlier_datetime_ // Assert act.Should().Throw() - .WithMessage("Did not expect time to be within 35ms from <2016-06-04 12:15:31>, but it was <2016-06-04 12:15:31.035>."); + .WithMessage( + "Did not expect time to be within 35ms from <2016-06-04 12:15:31>, but it was <2016-06-04 12:15:31.035>."); } [Fact] @@ -781,7 +791,8 @@ public void When_asserting_subject_datetime_is_not_close_to_the_maximum_datetime // Assert act.Should().Throw() - .WithMessage("Did not expect time to be within 100ms from <9999-12-31 23:59:59.9999999>, but it was <9999-12-31 23:59:59.9499999>."); + .WithMessage( + "Did not expect time to be within 100ms from <9999-12-31 23:59:59.9999999>, but it was <9999-12-31 23:59:59.9499999>."); } } @@ -805,8 +816,8 @@ public void When_asserting_a_point_of_time_is_before_a_later_point_it_should_suc public void When_asserting_subject_is_before_earlier_expected_datetime_it_should_throw() { // Arrange - DateTime expected = new DateTime(2016, 06, 03); - DateTime subject = new DateTime(2016, 06, 04); + DateTime expected = new(2016, 06, 03); + DateTime subject = new(2016, 06, 04); // Act Action act = () => subject.Should().BeBefore(expected); @@ -820,8 +831,8 @@ public void When_asserting_subject_is_before_earlier_expected_datetime_it_should public void When_asserting_subject_datetime_is_before_the_same_datetime_it_should_throw() { // Arrange - DateTime expected = new DateTime(2016, 06, 04); - DateTime subject = new DateTime(2016, 06, 04); + DateTime expected = new(2016, 06, 04); + DateTime subject = new(2016, 06, 04); // Act Action act = () => subject.Should().BeBefore(expected); @@ -853,8 +864,8 @@ public void When_asserting_a_point_of_time_is_not_before_another_it_should_throw public void When_asserting_subject_is_not_before_earlier_expected_datetime_it_should_succeed() { // Arrange - DateTime expected = new DateTime(2016, 06, 03); - DateTime subject = new DateTime(2016, 06, 04); + DateTime expected = new(2016, 06, 03); + DateTime subject = new(2016, 06, 04); // Act Action act = () => subject.Should().NotBeBefore(expected); @@ -867,8 +878,8 @@ public void When_asserting_subject_is_not_before_earlier_expected_datetime_it_sh public void When_asserting_subject_datetime_is_not_before_the_same_datetime_it_should_succeed() { // Arrange - DateTime expected = new DateTime(2016, 06, 04); - DateTime subject = new DateTime(2016, 06, 04); + DateTime expected = new(2016, 06, 04); + DateTime subject = new(2016, 06, 04); // Act Action act = () => subject.Should().NotBeBefore(expected); @@ -884,8 +895,8 @@ public class BeOnOrBefore public void When_asserting_subject_datetime_is_on_or_before_expected_datetime_should_succeed() { // Arrange - DateTime subject = new DateTime(2016, 06, 04); - DateTime expectation = new DateTime(2016, 06, 05); + DateTime subject = new(2016, 06, 04); + DateTime expectation = new(2016, 06, 05); // Act Action act = () => subject.Should().BeOnOrBefore(expectation); @@ -898,8 +909,8 @@ public void When_asserting_subject_datetime_is_on_or_before_expected_datetime_sh public void When_asserting_subject_datetime_is_on_or_before_the_same_date_as_the_expected_datetime_should_succeed() { // Arrange - DateTime subject = new DateTime(2016, 06, 04); - DateTime expectation = new DateTime(2016, 06, 04); + DateTime subject = new(2016, 06, 04); + DateTime expectation = new(2016, 06, 04); // Act Action act = () => subject.Should().BeOnOrBefore(expectation); @@ -912,8 +923,8 @@ public void When_asserting_subject_datetime_is_on_or_before_the_same_date_as_the public void When_asserting_subject_datetime_is_not_on_or_before_earlier_expected_datetime_should_throw() { // Arrange - DateTime subject = new DateTime(2016, 06, 04); - DateTime expectation = new DateTime(2016, 06, 03); + DateTime subject = new(2016, 06, 04); + DateTime expectation = new(2016, 06, 03); // Act Action act = () => subject.Should().BeOnOrBefore(expectation); @@ -930,8 +941,8 @@ public class NotBeOnOrBefore public void When_asserting_subject_datetime_is_on_or_before_expected_datetime_should_throw() { // Arrange - DateTime subject = new DateTime(2016, 06, 04); - DateTime expectation = new DateTime(2016, 06, 05); + DateTime subject = new(2016, 06, 04); + DateTime expectation = new(2016, 06, 05); // Act Action act = () => subject.Should().NotBeOnOrBefore(expectation); @@ -945,8 +956,8 @@ public void When_asserting_subject_datetime_is_on_or_before_expected_datetime_sh public void When_asserting_subject_datetime_is_on_or_before_the_same_date_as_the_expected_datetime_should_throw() { // Arrange - DateTime subject = new DateTime(2016, 06, 04); - DateTime expectation = new DateTime(2016, 06, 04); + DateTime subject = new(2016, 06, 04); + DateTime expectation = new(2016, 06, 04); // Act Action act = () => subject.Should().NotBeOnOrBefore(expectation); @@ -960,8 +971,8 @@ public void When_asserting_subject_datetime_is_on_or_before_the_same_date_as_the public void When_asserting_subject_datetime_is_not_on_or_before_earlier_expected_datetime_should_succeed() { // Arrange - DateTime subject = new DateTime(2016, 06, 04); - DateTime expectation = new DateTime(2016, 06, 03); + DateTime subject = new(2016, 06, 04); + DateTime expectation = new(2016, 06, 03); // Act Action act = () => subject.Should().NotBeOnOrBefore(expectation); @@ -977,8 +988,8 @@ public class BeAfter public void When_asserting_subject_datetime_is_after_earlier_expected_datetime_should_succeed() { // Arrange - DateTime subject = new DateTime(2016, 06, 04); - DateTime expectation = new DateTime(2016, 06, 03); + DateTime subject = new(2016, 06, 04); + DateTime expectation = new(2016, 06, 03); // Act Action act = () => subject.Should().BeAfter(expectation); @@ -991,8 +1002,8 @@ public void When_asserting_subject_datetime_is_after_earlier_expected_datetime_s public void When_asserting_subject_datetime_is_after_later_expected_datetime_should_throw() { // Arrange - DateTime subject = new DateTime(2016, 06, 04); - DateTime expectation = new DateTime(2016, 06, 05); + DateTime subject = new(2016, 06, 04); + DateTime expectation = new(2016, 06, 05); // Act Action act = () => subject.Should().BeAfter(expectation); @@ -1006,8 +1017,8 @@ public void When_asserting_subject_datetime_is_after_later_expected_datetime_sho public void When_asserting_subject_datetime_is_after_the_same_expected_datetime_should_throw() { // Arrange - DateTime subject = new DateTime(2016, 06, 04); - DateTime expectation = new DateTime(2016, 06, 04); + DateTime subject = new(2016, 06, 04); + DateTime expectation = new(2016, 06, 04); // Act Action act = () => subject.Should().BeAfter(expectation); @@ -1024,8 +1035,8 @@ public class NotBeAfter public void When_asserting_subject_datetime_is_not_after_earlier_expected_datetime_should_throw() { // Arrange - DateTime subject = new DateTime(2016, 06, 04); - DateTime expectation = new DateTime(2016, 06, 03); + DateTime subject = new(2016, 06, 04); + DateTime expectation = new(2016, 06, 03); // Act Action act = () => subject.Should().NotBeAfter(expectation); @@ -1039,8 +1050,8 @@ public void When_asserting_subject_datetime_is_not_after_earlier_expected_dateti public void When_asserting_subject_datetime_is_not_after_later_expected_datetime_should_succeed() { // Arrange - DateTime subject = new DateTime(2016, 06, 04); - DateTime expectation = new DateTime(2016, 06, 05); + DateTime subject = new(2016, 06, 04); + DateTime expectation = new(2016, 06, 05); // Act Action act = () => subject.Should().NotBeAfter(expectation); @@ -1053,8 +1064,8 @@ public void When_asserting_subject_datetime_is_not_after_later_expected_datetime public void When_asserting_subject_datetime_is_not_after_the_same_expected_datetime_should_succeed() { // Arrange - DateTime subject = new DateTime(2016, 06, 04); - DateTime expectation = new DateTime(2016, 06, 04); + DateTime subject = new(2016, 06, 04); + DateTime expectation = new(2016, 06, 04); // Act Action act = () => subject.Should().NotBeAfter(expectation); @@ -1070,8 +1081,8 @@ public class BeOnOrAfter public void When_asserting_subject_datetime_is_on_or_after_earlier_expected_datetime_should_succeed() { // Arrange - DateTime subject = new DateTime(2016, 06, 04); - DateTime expectation = new DateTime(2016, 06, 03); + DateTime subject = new(2016, 06, 04); + DateTime expectation = new(2016, 06, 03); // Act Action act = () => subject.Should().BeOnOrAfter(expectation); @@ -1084,8 +1095,8 @@ public void When_asserting_subject_datetime_is_on_or_after_earlier_expected_date public void When_asserting_subject_datetime_is_on_or_after_the_same_expected_datetime_should_succeed() { // Arrange - DateTime subject = new DateTime(2016, 06, 04); - DateTime expectation = new DateTime(2016, 06, 04); + DateTime subject = new(2016, 06, 04); + DateTime expectation = new(2016, 06, 04); // Act Action act = () => subject.Should().BeOnOrAfter(expectation); @@ -1098,8 +1109,8 @@ public void When_asserting_subject_datetime_is_on_or_after_the_same_expected_dat public void When_asserting_subject_datetime_is_on_or_after_later_expected_datetime_should_throw() { // Arrange - DateTime subject = new DateTime(2016, 06, 04); - DateTime expectation = new DateTime(2016, 06, 05); + DateTime subject = new(2016, 06, 04); + DateTime expectation = new(2016, 06, 05); // Act Action act = () => subject.Should().BeOnOrAfter(expectation); @@ -1116,8 +1127,8 @@ public class NotBeOnOrAfter public void When_asserting_subject_datetime_is_not_on_or_after_earlier_expected_datetime_should_throw() { // Arrange - DateTime subject = new DateTime(2016, 06, 04); - DateTime expectation = new DateTime(2016, 06, 03); + DateTime subject = new(2016, 06, 04); + DateTime expectation = new(2016, 06, 03); // Act Action act = () => subject.Should().NotBeOnOrAfter(expectation); @@ -1131,8 +1142,8 @@ public void When_asserting_subject_datetime_is_not_on_or_after_earlier_expected_ public void When_asserting_subject_datetime_is_not_on_or_after_the_same_expected_datetime_should_throw() { // Arrange - DateTime subject = new DateTime(2016, 06, 04); - DateTime expectation = new DateTime(2016, 06, 04); + DateTime subject = new(2016, 06, 04); + DateTime expectation = new(2016, 06, 04); // Act Action act = () => subject.Should().NotBeOnOrAfter(expectation); @@ -1146,8 +1157,8 @@ public void When_asserting_subject_datetime_is_not_on_or_after_the_same_expected public void When_asserting_subject_datetime_is_not_on_or_after_later_expected_datetime_should_succeed() { // Arrange - DateTime subject = new DateTime(2016, 06, 04); - DateTime expectation = new DateTime(2016, 06, 05); + DateTime subject = new(2016, 06, 04); + DateTime expectation = new(2016, 06, 05); // Act Action act = () => subject.Should().NotBeOnOrAfter(expectation); @@ -1163,7 +1174,7 @@ public class HaveYear public void When_asserting_subject_datetime_should_have_year_with_the_same_value_should_succeed() { // Arrange - DateTime subject = new DateTime(2009, 12, 31); + DateTime subject = new(2009, 12, 31); int expectation = 2009; // Act @@ -1177,7 +1188,7 @@ public void When_asserting_subject_datetime_should_have_year_with_the_same_value public void When_asserting_subject_datetime_should_have_year_with_a_different_value_should_throw() { // Arrange - DateTime subject = new DateTime(2009, 12, 31); + DateTime subject = new(2009, 12, 31); int expectation = 2008; // Act @@ -1210,7 +1221,7 @@ public class NotHaveYear public void When_asserting_subject_datetime_should_not_have_year_with_the_same_value_should_throw() { // Arrange - DateTime subject = new DateTime(2009, 12, 31); + DateTime subject = new(2009, 12, 31); int expectation = 2009; // Act @@ -1225,7 +1236,7 @@ public void When_asserting_subject_datetime_should_not_have_year_with_the_same_v public void When_asserting_subject_datetime_should_not_have_year_with_a_different_value_should_succeed() { // Arrange - DateTime subject = new DateTime(2009, 12, 31); + DateTime subject = new(2009, 12, 31); int expectation = 2008; // Act @@ -1257,7 +1268,7 @@ public class HaveMonth public void When_asserting_subject_datetime_should_have_month_with_the_same_value_it_should_succeed() { // Arrange - DateTime subject = new DateTime(2009, 12, 31); + DateTime subject = new(2009, 12, 31); int expectation = 12; // Act @@ -1271,7 +1282,7 @@ public void When_asserting_subject_datetime_should_have_month_with_the_same_valu public void When_asserting_subject_datetime_should_have_a_month_with_a_different_value_it_should_throw() { // Arrange - DateTime subject = new DateTime(2009, 12, 31); + DateTime subject = new(2009, 12, 31); int expectation = 11; // Act @@ -1304,7 +1315,7 @@ public class NotHaveMonth public void When_asserting_subject_datetime_should_not_have_month_with_the_same_value_it_should_throw() { // Arrange - DateTime subject = new DateTime(2009, 12, 31); + DateTime subject = new(2009, 12, 31); int expectation = 12; // Act @@ -1319,7 +1330,7 @@ public void When_asserting_subject_datetime_should_not_have_month_with_the_same_ public void When_asserting_subject_datetime_should_not_have_a_month_with_a_different_value_it_should_succeed() { // Arrange - DateTime subject = new DateTime(2009, 12, 31); + DateTime subject = new(2009, 12, 31); int expectation = 11; // Act @@ -1351,7 +1362,7 @@ public class HaveDay public void When_asserting_subject_datetime_should_have_day_with_the_same_value_it_should_succeed() { // Arrange - DateTime subject = new DateTime(2009, 12, 31); + DateTime subject = new(2009, 12, 31); int expectation = 31; // Act @@ -1365,7 +1376,7 @@ public void When_asserting_subject_datetime_should_have_day_with_the_same_value_ public void When_asserting_subject_datetime_should_have_day_with_a_different_value_it_should_throw() { // Arrange - DateTime subject = new DateTime(2009, 12, 31); + DateTime subject = new(2009, 12, 31); int expectation = 30; // Act @@ -1398,7 +1409,7 @@ public class NotHaveDay public void When_asserting_subject_datetime_should_not_have_day_with_the_same_value_it_should_throw() { // Arrange - DateTime subject = new DateTime(2009, 12, 31); + DateTime subject = new(2009, 12, 31); int expectation = 31; // Act @@ -1413,7 +1424,7 @@ public void When_asserting_subject_datetime_should_not_have_day_with_the_same_va public void When_asserting_subject_datetime_should_not_have_day_with_a_different_value_it_should_succeed() { // Arrange - DateTime subject = new DateTime(2009, 12, 31); + DateTime subject = new(2009, 12, 31); int expectation = 30; // Act @@ -1445,7 +1456,7 @@ public class HaveHour public void When_asserting_subject_datetime_should_have_hour_with_the_same_value_it_should_succeed() { // Arrange - DateTime subject = new DateTime(2009, 12, 31, 23, 59, 00); + DateTime subject = new(2009, 12, 31, 23, 59, 00); int expectation = 23; // Act @@ -1459,7 +1470,7 @@ public void When_asserting_subject_datetime_should_have_hour_with_the_same_value public void When_asserting_subject_datetime_should_have_hour_with_different_value_it_should_throw() { // Arrange - DateTime subject = new DateTime(2009, 12, 31, 23, 59, 00); + DateTime subject = new(2009, 12, 31, 23, 59, 00); int expectation = 22; // Act @@ -1492,7 +1503,7 @@ public class NotHaveHour public void When_asserting_subject_datetime_should_not_have_hour_with_the_same_value_it_should_throw() { // Arrange - DateTime subject = new DateTime(2009, 12, 31, 23, 59, 00); + DateTime subject = new(2009, 12, 31, 23, 59, 00); int expectation = 23; // Act @@ -1507,7 +1518,7 @@ public void When_asserting_subject_datetime_should_not_have_hour_with_the_same_v public void When_asserting_subject_datetime_should_not_have_hour_with_different_value_it_should_succeed() { // Arrange - DateTime subject = new DateTime(2009, 12, 31, 23, 59, 00); + DateTime subject = new(2009, 12, 31, 23, 59, 00); int expectation = 22; // Act @@ -1539,7 +1550,7 @@ public class HaveMinute public void When_asserting_subject_datetime_should_have_minutes_with_the_same_value_it_should_succeed() { // Arrange - DateTime subject = new DateTime(2009, 12, 31, 23, 59, 00); + DateTime subject = new(2009, 12, 31, 23, 59, 00); int expectation = 59; // Act @@ -1553,7 +1564,7 @@ public void When_asserting_subject_datetime_should_have_minutes_with_the_same_va public void When_asserting_subject_datetime_should_have_minutes_with_different_value_it_should_throw() { // Arrange - DateTime subject = new DateTime(2009, 12, 31, 23, 59, 00); + DateTime subject = new(2009, 12, 31, 23, 59, 00); int expectation = 58; // Act @@ -1586,7 +1597,7 @@ public class NotHaveMinute public void When_asserting_subject_datetime_should_not_have_minutes_with_the_same_value_it_should_throw() { // Arrange - DateTime subject = new DateTime(2009, 12, 31, 23, 59, 00); + DateTime subject = new(2009, 12, 31, 23, 59, 00); int expectation = 59; // Act @@ -1601,7 +1612,7 @@ public void When_asserting_subject_datetime_should_not_have_minutes_with_the_sam public void When_asserting_subject_datetime_should_not_have_minutes_with_different_value_it_should_succeed() { // Arrange - DateTime subject = new DateTime(2009, 12, 31, 23, 59, 00); + DateTime subject = new(2009, 12, 31, 23, 59, 00); int expectation = 58; // Act @@ -1633,7 +1644,7 @@ public class HaveSecond public void When_asserting_subject_datetime_should_have_seconds_with_the_same_value_it_should_succeed() { // Arrange - DateTime subject = new DateTime(2009, 12, 31, 23, 59, 00); + DateTime subject = new(2009, 12, 31, 23, 59, 00); int expectation = 0; // Act @@ -1647,7 +1658,7 @@ public void When_asserting_subject_datetime_should_have_seconds_with_the_same_va public void When_asserting_subject_datetime_should_have_seconds_with_different_value_it_should_throw() { // Arrange - DateTime subject = new DateTime(2009, 12, 31, 23, 59, 00); + DateTime subject = new(2009, 12, 31, 23, 59, 00); int expectation = 1; // Act @@ -1680,7 +1691,7 @@ public class NotHaveSecond public void When_asserting_subject_datetime_should_not_have_seconds_with_the_same_value_it_should_throw() { // Arrange - DateTime subject = new DateTime(2009, 12, 31, 23, 59, 00); + DateTime subject = new(2009, 12, 31, 23, 59, 00); int expectation = 0; // Act @@ -1695,7 +1706,7 @@ public void When_asserting_subject_datetime_should_not_have_seconds_with_the_sam public void When_asserting_subject_datetime_should_not_have_seconds_with_different_value_it_should_succeed() { // Arrange - DateTime subject = new DateTime(2009, 12, 31, 23, 59, 00); + DateTime subject = new(2009, 12, 31, 23, 59, 00); int expectation = 1; // Act @@ -1727,7 +1738,7 @@ public class BeInUtcOrLocal public void When_asserting_subject_datetime_represents_its_own_kind_it_should_succeed() { // Arrange - DateTime subject = new DateTime(2009, 12, 31, 23, 59, 00, DateTimeKind.Local); + DateTime subject = new(2009, 12, 31, 23, 59, 00, DateTimeKind.Local); // Act Action act = () => subject.Should().BeIn(DateTimeKind.Local); @@ -1740,7 +1751,7 @@ public void When_asserting_subject_datetime_represents_its_own_kind_it_should_su public void When_asserting_subject_datetime_represents_a_different_kind_it_should_throw() { // Arrange - DateTime subject = new DateTime(2009, 12, 31, 23, 59, 00, DateTimeKind.Local); + DateTime subject = new(2009, 12, 31, 23, 59, 00, DateTimeKind.Local); // Act Action act = () => subject.Should().BeIn(DateTimeKind.Utc); @@ -1781,7 +1792,8 @@ public void When_asserting_subject_datetime_should_be_same_date_as_another_with_ } [Fact] - public void When_asserting_subject_datetime_should_be_same_as_another_with_same_date_but_different_time_it_should_succeed() + public void + When_asserting_subject_datetime_should_be_same_as_another_with_same_date_but_different_time_it_should_succeed() { // Arrange var subject = new DateTime(2009, 12, 31, 4, 5, 6); @@ -1839,7 +1851,8 @@ public void When_asserting_subject_datetime_should_not_be_same_date_as_another_w } [Fact] - public void When_asserting_subject_datetime_should_not_be_same_as_another_with_same_date_but_different_time_it_should_throw() + public void + When_asserting_subject_datetime_should_not_be_same_as_another_with_same_date_but_different_time_it_should_throw() { // Arrange var subject = new DateTime(2009, 12, 31, 4, 5, 6); @@ -2064,7 +2077,8 @@ public void When_asserting_subject_be_more_than_10_seconds_after_target_but_subj [Theory] [InlineData(30, 20)] // edge case [InlineData(30, 15)] - public void When_asserting_subject_be_at_least_10_seconds_after_target_but_subject_is_before_target_it_should_throw(int targetSeconds, int subjectSeconds) + public void When_asserting_subject_be_at_least_10_seconds_after_target_but_subject_is_before_target_it_should_throw( + int targetSeconds, int subjectSeconds) { // Arrange var expectation = 1.January(0001).At(0, 0, targetSeconds); @@ -2075,7 +2089,8 @@ public void When_asserting_subject_be_at_least_10_seconds_after_target_but_subje // Assert action.Should().Throw() - .WithMessage($"Expected subject <00:00:{subjectSeconds}> to be at least 10s after <00:00:30>, but it is behind by {Math.Abs(subjectSeconds - targetSeconds)}s."); + .WithMessage( + $"Expected subject <00:00:{subjectSeconds}> to be at least 10s after <00:00:30>, but it is behind by {Math.Abs(subjectSeconds - targetSeconds)}s."); } [Fact] @@ -2096,7 +2111,8 @@ public void When_asserting_subject_be_exactly_10_seconds_after_target_but_subjec [Theory] [InlineData(30, 20)] // edge case [InlineData(30, 25)] - public void When_asserting_subject_be_within_10_seconds_after_target_but_subject_is_before_target_it_should_throw(int targetSeconds, int subjectSeconds) + public void When_asserting_subject_be_within_10_seconds_after_target_but_subject_is_before_target_it_should_throw( + int targetSeconds, int subjectSeconds) { // Arrange var expectation = 1.January(0001).At(0, 0, targetSeconds); @@ -2107,7 +2123,8 @@ public void When_asserting_subject_be_within_10_seconds_after_target_but_subject // Assert action.Should().Throw() - .WithMessage($"Expected subject <00:00:{subjectSeconds}> to be within 10s after <00:00:30>, but it is behind by {Math.Abs(subjectSeconds - targetSeconds)}s."); + .WithMessage( + $"Expected subject <00:00:{subjectSeconds}> to be within 10s after <00:00:30>, but it is behind by {Math.Abs(subjectSeconds - targetSeconds)}s."); } [Fact] @@ -2143,7 +2160,8 @@ public void When_asserting_subject_be_more_than_10_seconds_before_target_but_sub [Theory] [InlineData(30, 40)] // edge case [InlineData(30, 45)] - public void When_asserting_subject_be_at_least_10_seconds_before_target_but_subject_is_after_target_it_should_throw(int targetSeconds, int subjectSeconds) + public void When_asserting_subject_be_at_least_10_seconds_before_target_but_subject_is_after_target_it_should_throw( + int targetSeconds, int subjectSeconds) { // Arrange var expectation = 1.January(0001).At(0, 0, targetSeconds); @@ -2154,7 +2172,8 @@ public void When_asserting_subject_be_at_least_10_seconds_before_target_but_subj // Assert action.Should().Throw() - .WithMessage($"Expected subject <00:00:{subjectSeconds}> to be at least 10s before <00:00:30>, but it is ahead by {Math.Abs(subjectSeconds - targetSeconds)}s."); + .WithMessage( + $"Expected subject <00:00:{subjectSeconds}> to be at least 10s before <00:00:30>, but it is ahead by {Math.Abs(subjectSeconds - targetSeconds)}s."); } [Fact] @@ -2175,7 +2194,8 @@ public void When_asserting_subject_be_exactly_10_seconds_before_target_but_subje [Theory] [InlineData(30, 40)] // edge case [InlineData(30, 35)] - public void When_asserting_subject_be_within_10_seconds_before_target_but_subject_is_after_target_it_should_throw(int targetSeconds, int subjectSeconds) + public void When_asserting_subject_be_within_10_seconds_before_target_but_subject_is_after_target_it_should_throw( + int targetSeconds, int subjectSeconds) { // Arrange var expectation = 1.January(0001).At(0, 0, targetSeconds); @@ -2186,7 +2206,8 @@ public void When_asserting_subject_be_within_10_seconds_before_target_but_subjec // Assert action.Should().Throw() - .WithMessage($"Expected subject <00:00:{subjectSeconds}> to be within 10s before <00:00:30>, but it is ahead by {Math.Abs(subjectSeconds - targetSeconds)}s."); + .WithMessage( + $"Expected subject <00:00:{subjectSeconds}> to be within 10s before <00:00:30>, but it is ahead by {Math.Abs(subjectSeconds - targetSeconds)}s."); } [Fact] @@ -2211,7 +2232,7 @@ public class ChainingConstraint public void Should_support_chaining_constraints_with_and() { // Arrange - DateTime earlierDateTime = new DateTime(2016, 06, 03); + DateTime earlierDateTime = new(2016, 06, 03); DateTime? nullableDateTime = new DateTime(2016, 06, 04); // Act @@ -2232,38 +2253,42 @@ public class BeOneOf public void When_a_value_is_not_one_of_the_specified_values_it_should_throw() { // Arrange - DateTime value = new DateTime(2016, 12, 30, 23, 58, 57); + DateTime value = new(2016, 12, 30, 23, 58, 57); // Act Action action = () => value.Should().BeOneOf(value + 1.Days(), value + 1.Milliseconds()); // Assert action.Should().Throw() - .WithMessage("Expected value to be one of {<2016-12-31 23:58:57>, <2016-12-30 23:58:57.001>}, but found <2016-12-30 23:58:57>."); + .WithMessage( + "Expected value to be one of {<2016-12-31 23:58:57>, <2016-12-30 23:58:57.001>}, but found <2016-12-30 23:58:57>."); } [Fact] public void When_a_value_is_not_one_of_the_specified_values_it_should_throw_with_descriptive_message() { // Arrange - DateTime value = new DateTime(2016, 12, 30, 23, 58, 57); + DateTime value = new(2016, 12, 30, 23, 58, 57); // Act - Action action = () => value.Should().BeOneOf(new[] { value + 1.Days(), value + 1.Milliseconds() }, "because it's true"); + Action action = () => + value.Should().BeOneOf(new[] { value + 1.Days(), value + 1.Milliseconds() }, "because it's true"); // Assert action.Should().Throw() - .WithMessage("Expected value to be one of {<2016-12-31 23:58:57>, <2016-12-30 23:58:57.001>} because it's true, but found <2016-12-30 23:58:57>."); + .WithMessage( + "Expected value to be one of {<2016-12-31 23:58:57>, <2016-12-30 23:58:57.001>} because it's true, but found <2016-12-30 23:58:57>."); } [Fact] public void When_a_value_is_one_of_the_specified_values_it_should_succeed() { // Arrange - DateTime value = new DateTime(2016, 12, 30, 23, 58, 57); + DateTime value = new(2016, 12, 30, 23, 58, 57); // Act - Action action = () => value.Should().BeOneOf(new DateTime(2216, 1, 30, 0, 5, 7), new DateTime(2016, 12, 30, 23, 58, 57), new DateTime(2012, 3, 3)); + Action action = () => value.Should().BeOneOf(new DateTime(2216, 1, 30, 0, 5, 7), + new DateTime(2016, 12, 30, 23, 58, 57), new DateTime(2012, 3, 3)); // Assert action.Should().NotThrow(); @@ -2309,7 +2334,8 @@ public void Should_throw_a_helpful_error_when_accidentally_using_equals() Action action = () => someDateTime.Should().Equals(someDateTime); // Assert - action.Should().Throw().WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); + action.Should().Throw() + .WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); } [Fact] @@ -2322,7 +2348,8 @@ public void Should_throw_a_helpful_error_when_accidentally_using_equals_with_a_r Action action = () => someDateTime.Should().BeLessThan(0.Seconds()).Equals(someDateTime); // Assert - action.Should().Throw().WithMessage("Equals is not part of Fluent Assertions. Did you mean Before() or After() instead?"); + action.Should().Throw() + .WithMessage("Equals is not part of Fluent Assertions. Did you mean Before() or After() instead?"); } } } diff --git a/Tests/FluentAssertions.Specs/Primitives/DateTimeOffsetAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Primitives/DateTimeOffsetAssertionSpecs.cs index ed7b1b9ce7..b130a177bb 100644 --- a/Tests/FluentAssertions.Specs/Primitives/DateTimeOffsetAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Primitives/DateTimeOffsetAssertionSpecs.cs @@ -270,7 +270,8 @@ public void Should_fail_with_descriptive_message_when_asserting_datetimeoffset_n // Assert action.Should().Throw() - .WithMessage("Expected nullableDateTime to represent the same point in time as <2016-03-27 +1h> because we want to test the failure message, but found a DateTimeOffset."); + .WithMessage( + "Expected nullableDateTime to represent the same point in time as <2016-03-27 +1h> because we want to test the failure message, but found a DateTimeOffset."); } [Fact] @@ -286,7 +287,8 @@ public void Should_fail_with_descriptive_message_when_asserting_non_null_value_i // Assert action.Should().Throw() - .WithMessage("Expected nullableDateTime to be because we want to test the failure message, but it was <2016-03-27 +1h>."); + .WithMessage( + "Expected nullableDateTime to be because we want to test the failure message, but it was <2016-03-27 +1h>."); } [Fact] @@ -355,7 +357,7 @@ public void Should_fail_when_asserting_datetimeoffset_value_is_not_equal_to_the_ public void When_datetimeoffset_value_is_not_equal_to_the_same_nullable_value_notbe_should_failed() { // Arrange - DateTimeOffset dateTime = new DateTimeOffset(10.March(2012), 1.Hours()); + DateTimeOffset dateTime = new(10.March(2012), 1.Hours()); DateTimeOffset? sameDateTime = new DateTimeOffset(10.March(2012), 1.Hours()); // Act @@ -369,7 +371,7 @@ public void When_datetimeoffset_value_is_not_equal_to_the_same_nullable_value_no [Fact] public void - When_asserting_different_date_time_offsets_representing_different_world_times_it_should_not_succeed() + When_asserting_different_date_time_offsets_representing_different_world_times_it_should_not_succeed() { // Arrange var specificDate = 1.May(2008).At(6, 32); @@ -486,7 +488,8 @@ public void Should_fail_with_descriptive_message_when_asserting_null_value_is_ex // Assert action.Should().Throw() - .WithMessage("Expected nullableDateTime to be exactly <2016-03-27 +1h> because we want to test the failure message, but found a DateTimeOffset."); + .WithMessage( + "Expected nullableDateTime to be exactly <2016-03-27 +1h> because we want to test the failure message, but found a DateTimeOffset."); } } @@ -534,7 +537,7 @@ public void Should_fail_when_asserting_value_is_not_exactly_equal_to_the_same_va public void Should_fail_when_asserting_value_is_not_exactly_equal_to_the_same_nullable_value() { // Arrange - DateTimeOffset dateTime = new DateTimeOffset(10.March(2012), 1.Hours()); + DateTimeOffset dateTime = new(10.March(2012), 1.Hours()); DateTimeOffset? sameDateTime = new DateTimeOffset(10.March(2012), 1.Hours()); // Act @@ -625,8 +628,8 @@ public void When_a_datetimeoffset_is_close_to_a_MaxValue_by_one_tick_it_should_s public void When_asserting_subject_datetimeoffset_is_close_to_a_later_datetimeoffset_it_should_succeed() { // Arrange - DateTimeOffset time = new DateTimeOffset(2016, 06, 04, 12, 15, 30, 980, TimeSpan.Zero); - DateTimeOffset nearbyTime = new DateTimeOffset(2016, 06, 04, 12, 15, 31, 0, TimeSpan.Zero); + DateTimeOffset time = new(2016, 06, 04, 12, 15, 30, 980, TimeSpan.Zero); + DateTimeOffset nearbyTime = new(2016, 06, 04, 12, 15, 31, 0, TimeSpan.Zero); // Act Action act = () => time.Should().BeCloseTo(nearbyTime, 20.Milliseconds()); @@ -639,8 +642,8 @@ public void When_asserting_subject_datetimeoffset_is_close_to_a_later_datetimeof public void When_asserting_subject_datetimeoffset_is_close_to_an_earlier_datetimeoffset_it_should_succeed() { // Arrange - DateTimeOffset time = new DateTimeOffset(2016, 06, 04, 12, 15, 31, 020, TimeSpan.Zero); - DateTimeOffset nearbyTime = new DateTimeOffset(2016, 06, 04, 12, 15, 31, 0, TimeSpan.Zero); + DateTimeOffset time = new(2016, 06, 04, 12, 15, 31, 020, TimeSpan.Zero); + DateTimeOffset nearbyTime = new(2016, 06, 04, 12, 15, 31, 0, TimeSpan.Zero); // Act Action act = () => time.Should().BeCloseTo(nearbyTime, 20.Milliseconds()); @@ -650,7 +653,8 @@ public void When_asserting_subject_datetimeoffset_is_close_to_an_earlier_datetim } [Fact] - public void When_asserting_subject_datetimeoffset_is_close_to_another_value_that_is_later_by_more_than_20ms_it_should_throw() + public void + When_asserting_subject_datetimeoffset_is_close_to_another_value_that_is_later_by_more_than_20ms_it_should_throw() { // Arrange DateTimeOffset time = 13.March(2012).At(12, 15, 30, 979).ToDateTimeOffset(1.Hours()); @@ -666,7 +670,8 @@ public void When_asserting_subject_datetimeoffset_is_close_to_another_value_that } [Fact] - public void When_asserting_subject_datetimeoffset_is_close_to_another_value_that_is_earlier_by_more_than_20ms_it_should_throw() + public void + When_asserting_subject_datetimeoffset_is_close_to_another_value_that_is_earlier_by_more_than_20ms_it_should_throw() { // Arrange DateTimeOffset time = 13.March(2012).At(12, 15, 31, 021).ToDateTimeOffset(1.Hours()); @@ -682,7 +687,8 @@ public void When_asserting_subject_datetimeoffset_is_close_to_another_value_that } [Fact] - public void When_asserting_subject_datetimeoffset_is_close_to_another_value_that_is_earlier_by_more_than_a_35ms_timespan_it_should_throw() + public void + When_asserting_subject_datetimeoffset_is_close_to_another_value_that_is_earlier_by_more_than_a_35ms_timespan_it_should_throw() { // Arrange DateTimeOffset time = 13.March(2012).At(12, 15, 31, 036).WithOffset(1.Hours()); @@ -833,23 +839,25 @@ public void When_a_datetimeoffset_is_close_to_a_MaxValue_by_one_tick_it_should_f public void When_asserting_subject_datetimeoffset_is_not_close_to_a_later_datetimeoffset_it_should_throw() { // Arrange - DateTimeOffset time = new DateTimeOffset(2016, 06, 04, 12, 15, 30, 980, TimeSpan.Zero); - DateTimeOffset nearbyTime = new DateTimeOffset(2016, 06, 04, 12, 15, 31, 0, TimeSpan.Zero); + DateTimeOffset time = new(2016, 06, 04, 12, 15, 30, 980, TimeSpan.Zero); + DateTimeOffset nearbyTime = new(2016, 06, 04, 12, 15, 31, 0, TimeSpan.Zero); // Act Action act = () => time.Should().NotBeCloseTo(nearbyTime, 20.Milliseconds()); // Assert act.Should().Throw() - .WithMessage("Did not expect time to be within 20ms from <2016-06-04 12:15:31 +0h>, but it was <2016-06-04 12:15:30.980 +0h>."); + .WithMessage( + "Did not expect time to be within 20ms from <2016-06-04 12:15:31 +0h>, but it was <2016-06-04 12:15:30.980 +0h>."); } [Fact] - public void When_asserting_subject_datetimeoffset_is_not_close_to_a_later_datetimeoffset_by_a_20ms_timespan_it_should_throw() + public void + When_asserting_subject_datetimeoffset_is_not_close_to_a_later_datetimeoffset_by_a_20ms_timespan_it_should_throw() { // Arrange - DateTimeOffset time = new DateTimeOffset(2016, 06, 04, 12, 15, 30, 980, TimeSpan.Zero); - DateTimeOffset nearbyTime = new DateTimeOffset(2016, 06, 04, 12, 15, 31, 0, TimeSpan.Zero); + DateTimeOffset time = new(2016, 06, 04, 12, 15, 30, 980, TimeSpan.Zero); + DateTimeOffset nearbyTime = new(2016, 06, 04, 12, 15, 31, 0, TimeSpan.Zero); // Act Action act = () => time.Should().NotBeCloseTo(nearbyTime, TimeSpan.FromMilliseconds(20)); @@ -863,19 +871,21 @@ public void When_asserting_subject_datetimeoffset_is_not_close_to_a_later_dateti public void When_asserting_subject_datetimeoffset_is_not_close_to_an_earlier_datetimeoffset_it_should_throw() { // Arrange - DateTimeOffset time = new DateTimeOffset(2016, 06, 04, 12, 15, 31, 020, TimeSpan.Zero); - DateTimeOffset nearbyTime = new DateTimeOffset(2016, 06, 04, 12, 15, 31, 0, TimeSpan.Zero); + DateTimeOffset time = new(2016, 06, 04, 12, 15, 31, 020, TimeSpan.Zero); + DateTimeOffset nearbyTime = new(2016, 06, 04, 12, 15, 31, 0, TimeSpan.Zero); // Act Action act = () => time.Should().NotBeCloseTo(nearbyTime, 20.Milliseconds()); // Assert act.Should().Throw() - .WithMessage("Did not expect time to be within 20ms from <2016-06-04 12:15:31 +0h>, but it was <2016-06-04 12:15:31.020 +0h>."); + .WithMessage( + "Did not expect time to be within 20ms from <2016-06-04 12:15:31 +0h>, but it was <2016-06-04 12:15:31.020 +0h>."); } [Fact] - public void When_asserting_subject_datetimeoffset_is_not_close_to_another_value_that_is_later_by_more_than_20ms_it_should_succeed() + public void + When_asserting_subject_datetimeoffset_is_not_close_to_another_value_that_is_later_by_more_than_20ms_it_should_succeed() { // Arrange DateTimeOffset time = 13.March(2012).At(12, 15, 30, 979).ToDateTimeOffset(1.Hours()); @@ -889,7 +899,8 @@ public void When_asserting_subject_datetimeoffset_is_not_close_to_another_value_ } [Fact] - public void When_asserting_subject_datetimeoffset_is_not_close_to_another_value_that_is_earlier_by_more_than_20ms_it_should_succeed() + public void + When_asserting_subject_datetimeoffset_is_not_close_to_another_value_that_is_earlier_by_more_than_20ms_it_should_succeed() { // Arrange DateTimeOffset time = 13.March(2012).At(12, 15, 31, 021).ToDateTimeOffset(1.Hours()); @@ -914,7 +925,8 @@ public void When_asserting_subject_datetimeoffset_is_not_close_to_an_earlier_dat // Assert act.Should().Throw() - .WithMessage("Did not expect time to be within 35ms from <2012-03-13 12:15:31 +1h>, but it was <2012-03-13 12:15:31.035 +1h>."); + .WithMessage( + "Did not expect time to be within 35ms from <2012-03-13 12:15:31 +1h>, but it was <2012-03-13 12:15:31.035 +1h>."); } [Fact] @@ -944,7 +956,8 @@ public void When_asserting_subject_datetimeoffset_is_not_close_to_the_minimum_da // Assert act.Should().Throw() - .WithMessage("Did not expect time to be within 100ms from <0001-01-01 00:00:00.000>, but it was <00:00:00.050 +0h>."); + .WithMessage( + "Did not expect time to be within 100ms from <0001-01-01 00:00:00.000>, but it was <00:00:00.050 +0h>."); } [Fact] @@ -959,7 +972,8 @@ public void When_asserting_subject_datetimeoffset_is_not_close_to_the_maximum_da // Assert act.Should().Throw() - .WithMessage("Did not expect time to be within 100ms from <9999-12-31 23:59:59.9999999 +0h>, but it was <9999-12-31 23:59:59.9499999 +0h>."); + .WithMessage( + "Did not expect time to be within 100ms from <9999-12-31 23:59:59.9999999 +0h>, but it was <9999-12-31 23:59:59.9499999 +0h>."); } } @@ -969,8 +983,8 @@ public class BeBefore public void When_asserting_a_point_of_time_is_before_a_later_point_it_should_succeed() { // Arrange - DateTimeOffset earlierDate = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset laterDate = new DateTimeOffset(new DateTime(2016, 06, 04, 0, 5, 0), TimeSpan.Zero); + DateTimeOffset earlierDate = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset laterDate = new(new DateTime(2016, 06, 04, 0, 5, 0), TimeSpan.Zero); // Act Action act = () => earlierDate.Should().BeBefore(laterDate); @@ -983,8 +997,8 @@ public void When_asserting_a_point_of_time_is_before_a_later_point_it_should_suc public void When_asserting_subject_is_before_earlier_expected_datetimeoffset_it_should_throw() { // Arrange - DateTimeOffset expected = new DateTimeOffset(new DateTime(2016, 06, 03), TimeSpan.Zero); - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expected = new(new DateTime(2016, 06, 03), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); // Act Action act = () => subject.Should().BeBefore(expected); @@ -998,8 +1012,8 @@ public void When_asserting_subject_is_before_earlier_expected_datetimeoffset_it_ public void When_asserting_subject_datetimeoffset_is_before_the_same_datetimeoffset_it_should_throw() { // Arrange - DateTimeOffset expected = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expected = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); // Act Action act = () => subject.Should().BeBefore(expected); @@ -1016,8 +1030,8 @@ public class NotBeBefore public void When_asserting_a_point_of_time_is_not_before_another_it_should_throw() { // Arrange - DateTimeOffset earlierDate = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset laterDate = new DateTimeOffset(new DateTime(2016, 06, 04, 0, 5, 0), TimeSpan.Zero); + DateTimeOffset earlierDate = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset laterDate = new(new DateTime(2016, 06, 04, 0, 5, 0), TimeSpan.Zero); // Act Action act = () => earlierDate.Should().NotBeBefore(laterDate); @@ -1031,8 +1045,8 @@ public void When_asserting_a_point_of_time_is_not_before_another_it_should_throw public void When_asserting_subject_is_not_before_earlier_expected_datetimeoffset_it_should_succeed() { // Arrange - DateTimeOffset expected = new DateTimeOffset(new DateTime(2016, 06, 03), TimeSpan.Zero); - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expected = new(new DateTime(2016, 06, 03), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); // Act Action act = () => subject.Should().NotBeBefore(expected); @@ -1045,8 +1059,8 @@ public void When_asserting_subject_is_not_before_earlier_expected_datetimeoffset public void When_asserting_subject_datetimeoffset_is_not_before_the_same_datetimeoffset_it_should_succeed() { // Arrange - DateTimeOffset expected = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expected = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); // Act Action act = () => subject.Should().NotBeBefore(expected); @@ -1062,8 +1076,8 @@ public class BeOnOrBefore public void When_asserting_subject_datetimeoffset_is_on_or_before_expected_datetimeoffset_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2016, 06, 05), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2016, 06, 05), TimeSpan.Zero); // Act Action act = () => subject.Should().BeOnOrBefore(expectation); @@ -1073,11 +1087,12 @@ public void When_asserting_subject_datetimeoffset_is_on_or_before_expected_datet } [Fact] - public void When_asserting_subject_datetimeoffset_is_on_or_before_the_same_date_as_the_expected_datetimeoffset_should_succeed() + public void + When_asserting_subject_datetimeoffset_is_on_or_before_the_same_date_as_the_expected_datetimeoffset_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2016, 06, 04), TimeSpan.Zero); // Act Action act = () => subject.Should().BeOnOrBefore(expectation); @@ -1090,8 +1105,8 @@ public void When_asserting_subject_datetimeoffset_is_on_or_before_the_same_date_ public void When_asserting_subject_datetimeoffset_is_not_on_or_before_earlier_expected_datetimeoffset_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2016, 06, 03), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2016, 06, 03), TimeSpan.Zero); // Act Action act = () => subject.Should().BeOnOrBefore(expectation); @@ -1108,8 +1123,8 @@ public class NotBeOnOrBefore public void When_asserting_subject_datetimeoffset_is_on_or_before_expected_datetimeoffset_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2016, 06, 05), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2016, 06, 05), TimeSpan.Zero); // Act Action act = () => subject.Should().NotBeOnOrBefore(expectation); @@ -1120,11 +1135,12 @@ public void When_asserting_subject_datetimeoffset_is_on_or_before_expected_datet } [Fact] - public void When_asserting_subject_datetimeoffset_is_on_or_before_the_same_date_as_the_expected_datetimeoffset_should_throw() + public void + When_asserting_subject_datetimeoffset_is_on_or_before_the_same_date_as_the_expected_datetimeoffset_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2016, 06, 04), TimeSpan.Zero); // Act Action act = () => subject.Should().NotBeOnOrBefore(expectation); @@ -1138,8 +1154,8 @@ public void When_asserting_subject_datetimeoffset_is_on_or_before_the_same_date_ public void When_asserting_subject_datetimeoffset_is_not_on_or_before_earlier_expected_datetimeoffset_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2016, 06, 03), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2016, 06, 03), TimeSpan.Zero); // Act Action act = () => subject.Should().NotBeOnOrBefore(expectation); @@ -1155,8 +1171,8 @@ public class BeAfter public void When_asserting_subject_datetimeoffset_is_after_earlier_expected_datetimeoffset_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2016, 06, 03), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2016, 06, 03), TimeSpan.Zero); // Act Action act = () => subject.Should().BeAfter(expectation); @@ -1169,8 +1185,8 @@ public void When_asserting_subject_datetimeoffset_is_after_earlier_expected_date public void When_asserting_subject_datetimeoffset_is_after_later_expected_datetimeoffset_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2016, 06, 05), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2016, 06, 05), TimeSpan.Zero); // Act Action act = () => subject.Should().BeAfter(expectation); @@ -1184,8 +1200,8 @@ public void When_asserting_subject_datetimeoffset_is_after_later_expected_dateti public void When_asserting_subject_datetimeoffset_is_after_the_same_expected_datetimeoffset_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2016, 06, 04), TimeSpan.Zero); // Act Action act = () => subject.Should().BeAfter(expectation); @@ -1202,8 +1218,8 @@ public class NotBeAfter public void When_asserting_subject_datetimeoffset_is_not_after_earlier_expected_datetimeoffset_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2016, 06, 03), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2016, 06, 03), TimeSpan.Zero); // Act Action act = () => subject.Should().NotBeAfter(expectation); @@ -1217,8 +1233,8 @@ public void When_asserting_subject_datetimeoffset_is_not_after_earlier_expected_ public void When_asserting_subject_datetimeoffset_is_not_after_later_expected_datetimeoffset_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2016, 06, 05), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2016, 06, 05), TimeSpan.Zero); // Act Action act = () => subject.Should().NotBeAfter(expectation); @@ -1231,8 +1247,8 @@ public void When_asserting_subject_datetimeoffset_is_not_after_later_expected_da public void When_asserting_subject_datetimeoffset_is_not_after_the_same_expected_datetimeoffset_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2016, 06, 04), TimeSpan.Zero); // Act Action act = () => subject.Should().NotBeAfter(expectation); @@ -1248,8 +1264,8 @@ public class BeOnOrAfter public void When_asserting_subject_datetimeoffset_is_on_or_after_earlier_expected_datetimeoffset_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2016, 06, 03), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2016, 06, 03), TimeSpan.Zero); // Act Action act = () => subject.Should().BeOnOrAfter(expectation); @@ -1262,8 +1278,8 @@ public void When_asserting_subject_datetimeoffset_is_on_or_after_earlier_expecte public void When_asserting_subject_datetimeoffset_is_on_or_after_the_same_expected_datetimeoffset_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2016, 06, 04), TimeSpan.Zero); // Act Action act = () => subject.Should().BeOnOrAfter(expectation); @@ -1276,8 +1292,8 @@ public void When_asserting_subject_datetimeoffset_is_on_or_after_the_same_expect public void When_asserting_subject_datetimeoffset_is_on_or_after_later_expected_datetimeoffset_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2016, 06, 05), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2016, 06, 05), TimeSpan.Zero); // Act Action act = () => subject.Should().BeOnOrAfter(expectation); @@ -1294,8 +1310,8 @@ public class NotBeOnOrAfter public void When_asserting_subject_datetimeoffset_is_not_on_or_after_earlier_expected_datetimeoffset_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2016, 06, 03), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2016, 06, 03), TimeSpan.Zero); // Act Action act = () => subject.Should().NotBeOnOrAfter(expectation); @@ -1309,8 +1325,8 @@ public void When_asserting_subject_datetimeoffset_is_not_on_or_after_earlier_exp public void When_asserting_subject_datetimeoffset_is_not_on_or_after_the_same_expected_datetimeoffset_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2016, 06, 04), TimeSpan.Zero); // Act Action act = () => subject.Should().NotBeOnOrAfter(expectation); @@ -1324,8 +1340,8 @@ public void When_asserting_subject_datetimeoffset_is_not_on_or_after_the_same_ex public void When_asserting_subject_datetimeoffset_is_not_on_or_after_later_expected_datetimeoffset_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2016, 06, 04), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2016, 06, 05), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2016, 06, 04), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2016, 06, 05), TimeSpan.Zero); // Act Action act = () => subject.Should().NotBeOnOrAfter(expectation); @@ -1341,7 +1357,7 @@ public class HaveYear public void When_asserting_subject_datetimeoffset_should_have_year_with_the_same_value_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 06, 04), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 06, 04), TimeSpan.Zero); int expectation = 2009; // Act @@ -1355,7 +1371,7 @@ public void When_asserting_subject_datetimeoffset_should_have_year_with_the_same public void When_asserting_subject_datetimeoffset_should_have_year_with_a_different_value_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 06, 04), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 06, 04), TimeSpan.Zero); int expectation = 2008; // Act @@ -1388,7 +1404,7 @@ public class NotHaveYear public void When_asserting_subject_datetimeoffset_should_not_have_year_with_the_same_value_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 06, 04), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 06, 04), TimeSpan.Zero); int expectation = 2009; // Act @@ -1403,7 +1419,7 @@ public void When_asserting_subject_datetimeoffset_should_not_have_year_with_the_ public void When_asserting_subject_datetimeoffset_should_not_have_year_with_a_different_value_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 06, 04), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 06, 04), TimeSpan.Zero); int expectation = 2008; // Act @@ -1435,7 +1451,7 @@ public class HaveMonth public void When_asserting_subject_datetimeoffset_should_have_month_with_the_same_value_it_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31), TimeSpan.Zero); int expectation = 12; // Act @@ -1449,7 +1465,7 @@ public void When_asserting_subject_datetimeoffset_should_have_month_with_the_sam public void When_asserting_subject_datetimeoffset_should_have_a_month_with_a_different_value_it_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31), TimeSpan.Zero); int expectation = 11; // Act @@ -1482,7 +1498,7 @@ public class NotHaveMonth public void When_asserting_subject_datetimeoffset_should_not_have_month_with_the_same_value_it_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31), TimeSpan.Zero); int expectation = 12; // Act @@ -1497,7 +1513,7 @@ public void When_asserting_subject_datetimeoffset_should_not_have_month_with_the public void When_asserting_subject_datetimeoffset_should_not_have_a_month_with_a_different_value_it_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31), TimeSpan.Zero); int expectation = 11; // Act @@ -1529,7 +1545,7 @@ public class HaveDay public void When_asserting_subject_datetimeoffset_should_have_day_with_the_same_value_it_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31), TimeSpan.Zero); int expectation = 31; // Act @@ -1543,7 +1559,7 @@ public void When_asserting_subject_datetimeoffset_should_have_day_with_the_same_ public void When_asserting_subject_datetimeoffset_should_have_day_with_a_different_value_it_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31), TimeSpan.Zero); int expectation = 30; // Act @@ -1576,7 +1592,7 @@ public class NotHaveDay public void When_asserting_subject_datetimeoffset_should_not_have_day_with_the_same_value_it_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31), TimeSpan.Zero); int expectation = 31; // Act @@ -1591,7 +1607,7 @@ public void When_asserting_subject_datetimeoffset_should_not_have_day_with_the_s public void When_asserting_subject_datetimeoffset_should_not_have_day_with_a_different_value_it_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31), TimeSpan.Zero); int expectation = 30; // Act @@ -1623,7 +1639,7 @@ public class HaveHour public void When_asserting_subject_datetimeoffset_should_have_hour_with_the_same_value_it_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); int expectation = 23; // Act @@ -1637,7 +1653,7 @@ public void When_asserting_subject_datetimeoffset_should_have_hour_with_the_same public void When_asserting_subject_datetimeoffset_should_have_hour_with_different_value_it_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); int expectation = 22; // Act @@ -1670,7 +1686,7 @@ public class NotHaveHour public void When_asserting_subject_datetimeoffset_should_not_have_hour_with_the_same_value_it_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); int expectation = 23; // Act @@ -1685,7 +1701,7 @@ public void When_asserting_subject_datetimeoffset_should_not_have_hour_with_the_ public void When_asserting_subject_datetimeoffset_should_not_have_hour_with_different_value_it_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); int expectation = 22; // Act @@ -1717,7 +1733,7 @@ public class HaveMinute public void When_asserting_subject_datetimeoffset_should_have_minutes_with_the_same_value_it_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); int expectation = 59; // Act @@ -1731,7 +1747,7 @@ public void When_asserting_subject_datetimeoffset_should_have_minutes_with_the_s public void When_asserting_subject_datetimeoffset_should_have_minutes_with_different_value_it_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); int expectation = 58; // Act @@ -1764,7 +1780,7 @@ public class NotHaveMinute public void When_asserting_subject_datetimeoffset_should_not_have_minutes_with_the_same_value_it_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); int expectation = 59; // Act @@ -1779,7 +1795,7 @@ public void When_asserting_subject_datetimeoffset_should_not_have_minutes_with_t public void When_asserting_subject_datetimeoffset_should_not_have_minutes_with_different_value_it_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); int expectation = 58; // Act @@ -1811,7 +1827,7 @@ public class HaveSecond public void When_asserting_subject_datetimeoffset_should_have_seconds_with_the_same_value_it_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); int expectation = 0; // Act @@ -1825,7 +1841,7 @@ public void When_asserting_subject_datetimeoffset_should_have_seconds_with_the_s public void When_asserting_subject_datetimeoffset_should_have_seconds_with_different_value_it_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); int expectation = 1; // Act @@ -1858,7 +1874,7 @@ public class NotHaveSecond public void When_asserting_subject_datetimeoffset_should_not_have_seconds_with_the_same_value_it_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); int expectation = 0; // Act @@ -1873,7 +1889,7 @@ public void When_asserting_subject_datetimeoffset_should_not_have_seconds_with_t public void When_asserting_subject_datetimeoffset_should_not_have_seconds_with_different_value_it_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); int expectation = 1; // Act @@ -1905,7 +1921,7 @@ public class HaveOffset public void When_asserting_subject_datetimeoffset_should_have_offset_with_the_same_value_it_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.FromHours(7)); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.FromHours(7)); TimeSpan expectation = TimeSpan.FromHours(7); // Act @@ -1919,7 +1935,7 @@ public void When_asserting_subject_datetimeoffset_should_have_offset_with_the_sa public void When_asserting_subject_datetimeoffset_should_have_offset_with_different_value_it_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 23, 59, 10), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 23, 59, 10), TimeSpan.Zero); TimeSpan expectation = TimeSpan.FromHours(3); // Act @@ -1952,7 +1968,7 @@ public class NotHaveOffset public void When_asserting_subject_datetimeoffset_should_not_have_offset_with_the_same_value_it_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.FromHours(7)); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.FromHours(7)); TimeSpan expectation = TimeSpan.FromHours(7); // Act @@ -1967,7 +1983,7 @@ public void When_asserting_subject_datetimeoffset_should_not_have_offset_with_th public void When_asserting_subject_datetimeoffset_should_not_have_offset_with_different_value_it_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 23, 59, 00), TimeSpan.Zero); TimeSpan expectation = TimeSpan.FromHours(3); // Act @@ -1999,8 +2015,8 @@ public class BeSameDateAs public void When_asserting_subject_datetimeoffset_should_be_same_date_as_another_with_the_same_date_it_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 4, 5, 6), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2009, 12, 31), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 4, 5, 6), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2009, 12, 31), TimeSpan.Zero); // Act Action act = () => subject.Should().BeSameDateAs(expectation); @@ -2010,11 +2026,12 @@ public void When_asserting_subject_datetimeoffset_should_be_same_date_as_another } [Fact] - public void When_asserting_subject_datetimeoffset_should_be_same_as_another_with_same_date_but_different_time_it_should_succeed() + public void + When_asserting_subject_datetimeoffset_should_be_same_as_another_with_same_date_but_different_time_it_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 4, 5, 6), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2009, 12, 31, 11, 15, 11), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 4, 5, 6), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2009, 12, 31, 11, 15, 11), TimeSpan.Zero); // Act Action act = () => subject.Should().BeSameDateAs(expectation); @@ -2028,7 +2045,7 @@ public void When_asserting_subject_null_datetimeoffset_to_be_same_date_as_anothe { // Arrange DateTimeOffset? subject = null; - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2009, 12, 31), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2009, 12, 31), TimeSpan.Zero); // Act Action act = () => subject.Should().BeSameDateAs(expectation); @@ -2042,8 +2059,8 @@ public void When_asserting_subject_null_datetimeoffset_to_be_same_date_as_anothe public void When_asserting_subject_datetimeoffset_should_have_same_date_as_another_but_it_doesnt_it_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2009, 12, 30), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2009, 12, 30), TimeSpan.Zero); // Act Action act = () => subject.Should().BeSameDateAs(expectation); @@ -2060,8 +2077,8 @@ public class NotBeSameDateAs public void When_asserting_subject_datetimeoffset_should_not_be_same_date_as_another_with_the_same_date_it_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 4, 5, 6), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2009, 12, 31), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 4, 5, 6), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2009, 12, 31), TimeSpan.Zero); // Act Action act = () => subject.Should().NotBeSameDateAs(expectation); @@ -2072,11 +2089,12 @@ public void When_asserting_subject_datetimeoffset_should_not_be_same_date_as_ano } [Fact] - public void When_asserting_subject_datetimeoffset_should_not_be_same_as_another_with_same_date_but_different_time_it_should_throw() + public void + When_asserting_subject_datetimeoffset_should_not_be_same_as_another_with_same_date_but_different_time_it_should_throw() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31, 4, 5, 6), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2009, 12, 31, 11, 15, 11), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31, 4, 5, 6), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2009, 12, 31, 11, 15, 11), TimeSpan.Zero); // Act Action act = () => subject.Should().NotBeSameDateAs(expectation); @@ -2091,7 +2109,7 @@ public void When_asserting_subject_null_datetimeoffset_to_not_be_same_date_as_an { // Arrange DateTimeOffset? subject = null; - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2009, 12, 31), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2009, 12, 31), TimeSpan.Zero); // Act Action act = () => subject.Should().NotBeSameDateAs(expectation); @@ -2105,8 +2123,8 @@ public void When_asserting_subject_null_datetimeoffset_to_not_be_same_date_as_an public void When_asserting_subject_datetimeoffset_should_not_have_same_date_as_another_but_it_doesnt_it_should_succeed() { // Arrange - DateTimeOffset subject = new DateTimeOffset(new DateTime(2009, 12, 31), TimeSpan.Zero); - DateTimeOffset expectation = new DateTimeOffset(new DateTime(2009, 12, 30), TimeSpan.Zero); + DateTimeOffset subject = new(new DateTime(2009, 12, 31), TimeSpan.Zero); + DateTimeOffset expectation = new(new DateTime(2009, 12, 30), TimeSpan.Zero); // Act Action act = () => subject.Should().NotBeSameDateAs(expectation); @@ -2294,13 +2312,15 @@ public void When_asserting_subject_be_more_than_10_seconds_after_target_but_subj // Assert action.Should().Throw() - .WithMessage("Expected subject <00:00:15 +0h> to be more than 10s after <00:00:30 +0h>, but it is behind by 15s."); + .WithMessage( + "Expected subject <00:00:15 +0h> to be more than 10s after <00:00:30 +0h>, but it is behind by 15s."); } [Theory] [InlineData(30, 20)] // edge case [InlineData(30, 15)] - public void When_asserting_subject_be_at_least_10_seconds_after_target_but_subject_is_before_target_it_should_throw(int targetSeconds, int subjectSeconds) + public void When_asserting_subject_be_at_least_10_seconds_after_target_but_subject_is_before_target_it_should_throw( + int targetSeconds, int subjectSeconds) { // Arrange var expectation = 1.January(0001).At(0, 0, targetSeconds).WithOffset(0.Hours()); @@ -2311,7 +2331,8 @@ public void When_asserting_subject_be_at_least_10_seconds_after_target_but_subje // Assert action.Should().Throw() - .WithMessage($"Expected subject <00:00:{subjectSeconds} +0h> to be at least 10s after <00:00:30 +0h>, but it is behind by {Math.Abs(subjectSeconds - targetSeconds)}s."); + .WithMessage( + $"Expected subject <00:00:{subjectSeconds} +0h> to be at least 10s after <00:00:30 +0h>, but it is behind by {Math.Abs(subjectSeconds - targetSeconds)}s."); } [Fact] @@ -2332,7 +2353,8 @@ public void When_asserting_subject_be_exactly_10_seconds_after_target_but_subjec [Theory] [InlineData(30, 20)] // edge case [InlineData(30, 25)] - public void When_asserting_subject_be_within_10_seconds_after_target_but_subject_is_before_target_it_should_throw(int targetSeconds, int subjectSeconds) + public void When_asserting_subject_be_within_10_seconds_after_target_but_subject_is_before_target_it_should_throw( + int targetSeconds, int subjectSeconds) { // Arrange var expectation = 1.January(0001).At(0, 0, targetSeconds).WithOffset(0.Hours()); @@ -2343,7 +2365,8 @@ public void When_asserting_subject_be_within_10_seconds_after_target_but_subject // Assert action.Should().Throw() - .WithMessage($"Expected subject <00:00:{subjectSeconds} +0h> to be within 10s after <00:00:30 +0h>, but it is behind by {Math.Abs(subjectSeconds - targetSeconds)}s."); + .WithMessage( + $"Expected subject <00:00:{subjectSeconds} +0h> to be within 10s after <00:00:30 +0h>, but it is behind by {Math.Abs(subjectSeconds - targetSeconds)}s."); } [Fact] @@ -2373,13 +2396,15 @@ public void When_asserting_subject_be_more_than_10_seconds_before_target_but_sub // Assert action.Should().Throw() - .WithMessage("Expected subject <00:00:45 +0h> to be more than 10s before <00:00:30 +0h>, but it is ahead by 15s."); + .WithMessage( + "Expected subject <00:00:45 +0h> to be more than 10s before <00:00:30 +0h>, but it is ahead by 15s."); } [Theory] [InlineData(30, 40)] // edge case [InlineData(30, 45)] - public void When_asserting_subject_be_at_least_10_seconds_before_target_but_subject_is_after_target_it_should_throw(int targetSeconds, int subjectSeconds) + public void When_asserting_subject_be_at_least_10_seconds_before_target_but_subject_is_after_target_it_should_throw( + int targetSeconds, int subjectSeconds) { // Arrange var expectation = 1.January(0001).At(0, 0, targetSeconds).WithOffset(0.Hours()); @@ -2390,7 +2415,8 @@ public void When_asserting_subject_be_at_least_10_seconds_before_target_but_subj // Assert action.Should().Throw() - .WithMessage($"Expected subject <00:00:{subjectSeconds} +0h> to be at least 10s before <00:00:30 +0h>, but it is ahead by {Math.Abs(subjectSeconds - targetSeconds)}s."); + .WithMessage( + $"Expected subject <00:00:{subjectSeconds} +0h> to be at least 10s before <00:00:30 +0h>, but it is ahead by {Math.Abs(subjectSeconds - targetSeconds)}s."); } [Fact] @@ -2411,7 +2437,8 @@ public void When_asserting_subject_be_exactly_10_seconds_before_target_but_subje [Theory] [InlineData(30, 40)] // edge case [InlineData(30, 35)] - public void When_asserting_subject_be_within_10_seconds_before_target_but_subject_is_after_target_it_should_throw(int targetSeconds, int subjectSeconds) + public void When_asserting_subject_be_within_10_seconds_before_target_but_subject_is_after_target_it_should_throw( + int targetSeconds, int subjectSeconds) { // Arrange var expectation = 1.January(0001).At(0, 0, targetSeconds).WithOffset(0.Hours()); @@ -2422,7 +2449,8 @@ public void When_asserting_subject_be_within_10_seconds_before_target_but_subjec // Assert action.Should().Throw() - .WithMessage($"Expected subject <00:00:{subjectSeconds} +0h> to be within 10s before <00:00:30 +0h>, but it is ahead by {Math.Abs(subjectSeconds - targetSeconds)}s."); + .WithMessage( + $"Expected subject <00:00:{subjectSeconds} +0h> to be within 10s before <00:00:30 +0h>, but it is ahead by {Math.Abs(subjectSeconds - targetSeconds)}s."); } [Fact] @@ -2437,7 +2465,8 @@ public void When_asserting_subject_be_less_than_10_seconds_before_target_but_sub // Assert action.Should().Throw() - .WithMessage("Expected subject <00:00:45 +0h> to be less than 10s before <00:00:30 +0h>, but it is ahead by 15s."); + .WithMessage( + "Expected subject <00:00:45 +0h> to be less than 10s before <00:00:30 +0h>, but it is ahead by 15s."); } [Fact] @@ -2450,7 +2479,8 @@ public void Should_throw_a_helpful_error_when_accidentally_using_equals_with_a_r Action action = () => someDateTimeOffset.Should().BeLessThan(0.Seconds()).Equals(someDateTimeOffset); // Assert - action.Should().Throw().WithMessage("Equals is not part of Fluent Assertions. Did you mean Before() or After() instead?"); + action.Should().Throw() + .WithMessage("Equals is not part of Fluent Assertions. Did you mean Before() or After() instead?"); } } @@ -2509,10 +2539,11 @@ public void When_a_value_is_not_one_of_the_specified_values_it_should_throw_with public void When_a_value_is_one_of_the_specified_values_it_should_succeed() { // Arrange - DateTimeOffset value = new DateTimeOffset(2016, 12, 30, 23, 58, 57, TimeSpan.FromHours(4)); + DateTimeOffset value = new(2016, 12, 30, 23, 58, 57, TimeSpan.FromHours(4)); // Act - Action action = () => value.Should().BeOneOf(new DateTimeOffset(2216, 1, 30, 0, 5, 7, TimeSpan.FromHours(2)), new DateTimeOffset(2016, 12, 30, 23, 58, 57, TimeSpan.FromHours(4))); + Action action = () => value.Should().BeOneOf(new DateTimeOffset(2216, 1, 30, 0, 5, 7, TimeSpan.FromHours(2)), + new DateTimeOffset(2016, 12, 30, 23, 58, 57, TimeSpan.FromHours(4))); // Assert action.Should().NotThrow(); @@ -2525,7 +2556,8 @@ public void When_a_null_value_is_not_one_of_the_specified_values_it_should_throw DateTimeOffset? value = null; // Act - Action action = () => value.Should().BeOneOf(new DateTimeOffset(2216, 1, 30, 0, 5, 7, TimeSpan.FromHours(1)), new DateTimeOffset(2016, 2, 10, 2, 45, 7, TimeSpan.FromHours(2))); + Action action = () => value.Should().BeOneOf(new DateTimeOffset(2216, 1, 30, 0, 5, 7, TimeSpan.FromHours(1)), + new DateTimeOffset(2016, 2, 10, 2, 45, 7, TimeSpan.FromHours(2))); // Assert action.Should().Throw().WithMessage( @@ -2558,7 +2590,8 @@ public void Should_throw_a_helpful_error_when_accidentally_using_equals() Action action = () => someDateTimeOffset.Should().Equals(someDateTimeOffset); // Assert - action.Should().Throw().WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); + action.Should().Throw() + .WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); } } } diff --git a/Tests/FluentAssertions.Specs/Primitives/EnumAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Primitives/EnumAssertionSpecs.cs index f00823cd9c..13cf11f909 100644 --- a/Tests/FluentAssertions.Specs/Primitives/EnumAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Primitives/EnumAssertionSpecs.cs @@ -56,7 +56,8 @@ public void When_enum_does_not_have_specified_flag_it_should_fail_with_a_descrip // Assert act.Should().Throw() - .WithMessage("Expected*have flag TestEnum.Three {value: 4}*because we want to test the failure message*but found TestEnum.One|Two {value: 3}."); + .WithMessage( + "Expected*have flag TestEnum.Three {value: 4}*because we want to test the failure message*but found TestEnum.One|Two {value: 3}."); } } @@ -83,7 +84,8 @@ public void When_enum_does_have_specified_flag_it_should_fail_with_a_descriptive // Assert act.Should().Throw() - .WithMessage("Expected*someObject*to not have flag TestEnum.Two {value: 2}*because we want to test the failure message*"); + .WithMessage( + "Expected*someObject*to not have flag TestEnum.Two {value: 2}*because we want to test the failure message*"); } [Fact] @@ -766,7 +768,8 @@ public void Throws_when_the_enums_is_not_one_of_the_expected_enums() BindingFlags flags = BindingFlags.DeclaredOnly; // Act / Assert - Action act = () => flags.Should().BeOneOf(new[] { BindingFlags.Public, BindingFlags.ExactBinding }, "that's what we need"); + Action act = () => + flags.Should().BeOneOf(new[] { BindingFlags.Public, BindingFlags.ExactBinding }, "that's what we need"); act.Should() .Throw() @@ -896,7 +899,8 @@ public void Should_throw_a_helpful_error_when_accidentally_using_equals() Action action = () => subject.Should().Equals(subject); // Assert - action.Should().Throw().WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); + action.Should().Throw() + .WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); } } } diff --git a/Tests/FluentAssertions.Specs/Primitives/GuidAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Primitives/GuidAssertionSpecs.cs index 47ce833458..0361c8a209 100644 --- a/Tests/FluentAssertions.Specs/Primitives/GuidAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Primitives/GuidAssertionSpecs.cs @@ -222,7 +222,8 @@ public void Should_throw_a_helpful_error_when_accidentally_using_equals() Action action = () => subject.Should().Equals(subject); // Assert - action.Should().Throw().WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() or BeOneOf() instead?"); + action.Should().Throw() + .WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() or BeOneOf() instead?"); } } } diff --git a/Tests/FluentAssertions.Specs/Primitives/NullableBooleanAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Primitives/NullableBooleanAssertionSpecs.cs index 7d3b3cdeda..6703fb54e9 100644 --- a/Tests/FluentAssertions.Specs/Primitives/NullableBooleanAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Primitives/NullableBooleanAssertionSpecs.cs @@ -127,7 +127,8 @@ public void When_asserting_nullable_boolean_value_with_a_value_to_be_null_it_sho } [Fact] - public void When_asserting_nullable_boolean_value_with_a_value_to_be_not_have_a_value_it_should_fail_with_descriptive_message() + public void + When_asserting_nullable_boolean_value_with_a_value_to_be_not_have_a_value_it_should_fail_with_descriptive_message() { // Arrange bool? nullableBoolean = true; @@ -213,7 +214,8 @@ public void When_asserting_boolean_null_value_not_to_be_equal_to_same_value_shou // Assert action.Should().Throw() - .WithMessage("Expected nullableBoolean not to be because we want to test the failure message, but found ."); + .WithMessage( + "Expected nullableBoolean not to be because we want to test the failure message, but found ."); } [Fact] diff --git a/Tests/FluentAssertions.Specs/Primitives/NullableGuidAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Primitives/NullableGuidAssertionSpecs.cs index 5df1702a40..eeaea7f2f1 100644 --- a/Tests/FluentAssertions.Specs/Primitives/NullableGuidAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Primitives/NullableGuidAssertionSpecs.cs @@ -168,7 +168,8 @@ public void Should_fail_with_descriptive_message_when_asserting_nullable_guid_va // Assert act.Should().Throw() - .WithMessage("Did not expect a value because we want to test the failure message, but found {11111111-aaaa-bbbb-cccc-999999999999}."); + .WithMessage( + "Did not expect a value because we want to test the failure message, but found {11111111-aaaa-bbbb-cccc-999999999999}."); } [Fact] @@ -182,7 +183,8 @@ public void Should_fail_with_descriptive_message_when_asserting_nullable_guid_va // Assert act.Should().Throw() - .WithMessage("Did not expect a value because we want to test the failure message, but found {11111111-aaaa-bbbb-cccc-999999999999}."); + .WithMessage( + "Did not expect a value because we want to test the failure message, but found {11111111-aaaa-bbbb-cccc-999999999999}."); } [Fact] diff --git a/Tests/FluentAssertions.Specs/Primitives/NullableSimpleTimeSpanAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Primitives/NullableSimpleTimeSpanAssertionSpecs.cs index 4193b58d52..6496a4f529 100644 --- a/Tests/FluentAssertions.Specs/Primitives/NullableSimpleTimeSpanAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Primitives/NullableSimpleTimeSpanAssertionSpecs.cs @@ -143,7 +143,8 @@ public void Should_fail_with_descriptive_message_when_asserting_nullable_TimeSpa } [Fact] - public void When_asserting_a_nullable_TimeSpan_is_equal_to_a_different_nullable_TimeSpan_it_should_should_throw_appropriately() + public void + When_asserting_a_nullable_TimeSpan_is_equal_to_a_different_nullable_TimeSpan_it_should_should_throw_appropriately() { // Arrange TimeSpan? nullableTimeSpanA = 1.Seconds(); @@ -157,7 +158,8 @@ public void When_asserting_a_nullable_TimeSpan_is_equal_to_a_different_nullable_ } [Fact] - public void When_asserting_a_nullable_TimeSpan_is_equal_to_another_a_nullable_TimeSpan_but_it_is_null_it_should_fail_with_a_descriptive_message() + public void + When_asserting_a_nullable_TimeSpan_is_equal_to_another_a_nullable_TimeSpan_but_it_is_null_it_should_fail_with_a_descriptive_message() { // Arrange TimeSpan? nullableTimeSpanA = null; diff --git a/Tests/FluentAssertions.Specs/Primitives/ObjectAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Primitives/ObjectAssertionSpecs.cs index eb1c298c12..342224cf15 100644 --- a/Tests/FluentAssertions.Specs/Primitives/ObjectAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Primitives/ObjectAssertionSpecs.cs @@ -1,9 +1,12 @@ using System; +using System.Collections.Generic; using System.Globalization; using System.Runtime.Serialization; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; +using AssemblyA; +using AssemblyB; using FluentAssertions.Execution; using FluentAssertions.Extensions; using Xunit; @@ -159,7 +162,8 @@ public void When_a_value_is_not_one_of_the_specified_values_it_should_throw() // Assert act .Should().Throw() - .WithMessage("Expected value to be one of {ClassWithCustomEqualMethod(4), ClassWithCustomEqualMethod(5)}, but found ClassWithCustomEqualMethod(3)."); + .WithMessage( + "Expected value to be one of {ClassWithCustomEqualMethod(4), ClassWithCustomEqualMethod(5)}, but found ClassWithCustomEqualMethod(3)."); } [Fact] @@ -169,12 +173,15 @@ public void When_a_value_is_not_one_of_the_specified_values_it_should_throw_with var value = new ClassWithCustomEqualMethod(3); // Act - Action act = () => value.Should().BeOneOf(new[] { new ClassWithCustomEqualMethod(4), new ClassWithCustomEqualMethod(5) }, "because those are the valid values"); + Action act = () => + value.Should().BeOneOf(new[] { new ClassWithCustomEqualMethod(4), new ClassWithCustomEqualMethod(5) }, + "because those are the valid values"); // Assert act .Should().Throw() - .WithMessage("Expected value to be one of {ClassWithCustomEqualMethod(4), ClassWithCustomEqualMethod(5)} because those are the valid values, but found ClassWithCustomEqualMethod(3)."); + .WithMessage( + "Expected value to be one of {ClassWithCustomEqualMethod(4), ClassWithCustomEqualMethod(5)} because those are the valid values, but found ClassWithCustomEqualMethod(3)."); } [Fact] @@ -343,7 +350,8 @@ public void When_null_object_is_matched_against_a_type_it_should_throw() int? valueTypeObject = null; // Act - Action act = () => valueTypeObject.Should().BeOfType(typeof(int), "because we want to test the failure {0}", "message"); + Action act = () => + valueTypeObject.Should().BeOfType(typeof(int), "because we want to test the failure {0}", "message"); // Assert act.Should().Throw() @@ -361,7 +369,8 @@ public void When_object_type_is_value_type_and_doesnt_match_received_type_should Action act = () => valueTypeObject.Should().BeOfType(doubleType); // Assert - act.Should().Throw().WithMessage($"Expected type to be {doubleType}, but found {valueTypeObject.GetType()}."); + act.Should().Throw() + .WithMessage($"Expected type to be {doubleType}, but found {valueTypeObject.GetType()}."); } [Fact] @@ -406,23 +415,25 @@ public void When_asserting_the_type_of_a_null_object_it_should_throw() } [Fact] - public void When_object_type_is_same_as_expected_type_but_in_different_assembly_it_should_fail_with_assembly_qualified_name() + public void + When_object_type_is_same_as_expected_type_but_in_different_assembly_it_should_fail_with_assembly_qualified_name() { // Arrange var typeFromOtherAssembly = - new AssemblyA.ClassA().ReturnClassC(); + new ClassA().ReturnClassC(); // Act #pragma warning disable 436 // disable the warning on conflicting types, as this is the intention for the spec Action act = () => - typeFromOtherAssembly.Should().BeOfType(); + typeFromOtherAssembly.Should().BeOfType(); #pragma warning restore 436 // Assert act.Should().Throw() - .WithMessage("Expected type to be [AssemblyB.ClassC, FluentAssertions.Specs*], but found [AssemblyB.ClassC, AssemblyB*]."); + .WithMessage( + "Expected type to be [AssemblyB.ClassC, FluentAssertions.Specs*], but found [AssemblyB.ClassC, AssemblyB*]."); } [Fact] @@ -471,7 +482,8 @@ public void When_object_is_matched_negatively_against_a_null_type_it_should_thro } [Fact] - public void When_object_type_is_value_type_and_doesnt_match_received_type_as_expected_should_not_fail_and_assert_correctly() + public void + When_object_type_is_value_type_and_doesnt_match_received_type_as_expected_should_not_fail_and_assert_correctly() { // Arrange int valueTypeObject = 42; @@ -490,7 +502,8 @@ public void When_null_object_is_matched_negatively_against_a_type_it_should_thro int? valueTypeObject = null; // Act - Action act = () => valueTypeObject.Should().NotBeOfType(typeof(int), "because we want to test the failure {0}", "message"); + Action act = () => + valueTypeObject.Should().NotBeOfType(typeof(int), "because we want to test the failure {0}", "message"); // Assert act.Should().Throw() @@ -508,7 +521,8 @@ public void When_object_type_is_value_type_and_matches_received_type_not_as_expe Action act = () => valueTypeObject.Should().NotBeOfType(expectedType); // Assert - act.Should().Throw().WithMessage($"Expected type not to be [{expectedType.AssemblyQualifiedName}], but it is."); + act.Should().Throw() + .WithMessage($"Expected type not to be [{expectedType.AssemblyQualifiedName}], but it is."); } } @@ -635,10 +649,10 @@ public void When_an_implemented_interface_type_instance_it_should_succeed() public void When_an_implemented_open_generic_interface_type_instance_it_should_succeed() { // Arrange - var someObject = new System.Collections.Generic.List(); + var someObject = new List(); // Act / Assert - someObject.Should().BeAssignableTo(typeof(System.Collections.Generic.IList<>)); + someObject.Should().BeAssignableTo(typeof(IList<>)); } [Fact] @@ -664,7 +678,9 @@ public void When_an_unrelated_type_instance_it_should_fail_with_a_descriptive_me { // Arrange var someObject = new DummyImplementingClass(); - Action act = () => someObject.Should().BeAssignableTo(typeof(DateTime), "because we want to test the failure {0}", "message"); + + Action act = () => + someObject.Should().BeAssignableTo(typeof(DateTime), "because we want to test the failure {0}", "message"); // Act / Assert act.Should().Throw() @@ -676,11 +692,13 @@ public void When_unrelated_to_open_generic_type_it_should_fail_with_a_descriptiv { // Arrange var someObject = new DummyImplementingClass(); - Action act = () => someObject.Should().BeAssignableTo(typeof(System.Collections.Generic.IList<>), "because we want to test the failure {0}", "message"); + + Action act = () => + someObject.Should().BeAssignableTo(typeof(IList<>), "because we want to test the failure {0}", "message"); // Act / Assert act.Should().Throw() - .WithMessage($"*assignable to {typeof(System.Collections.Generic.IList<>)}*failure message*{typeof(DummyImplementingClass)} is not*"); + .WithMessage($"*assignable to {typeof(IList<>)}*failure message*{typeof(DummyImplementingClass)} is not*"); } [Fact] @@ -698,8 +716,8 @@ public void When_an_assertion_fails_on_BeAssignableTo_succeeding_message_should_ // Assert act.Should().Throw() .WithMessage( - "Expected * to be assignable to System.Int32, but System.String is not.*" + - "Expected * to be assignable to System.Int64, but System.String is not."); + "Expected * to be assignable to System.Int32, but System.String is not.*" + + "Expected * to be assignable to System.Int64, but System.String is not."); } } @@ -724,11 +742,15 @@ public void When_its_own_type_and_asserting_not_assignable_it_should_fail_with_a { // Arrange var someObject = new DummyImplementingClass(); - Action act = () => someObject.Should().NotBeAssignableTo("because we want to test the failure {0}", "message"); + + Action act = () => + someObject.Should() + .NotBeAssignableTo("because we want to test the failure {0}", "message"); // Act / Assert act.Should().Throw() - .WithMessage($"*not be assignable to {typeof(DummyImplementingClass)}*failure message*{typeof(DummyImplementingClass)} is*"); + .WithMessage( + $"*not be assignable to {typeof(DummyImplementingClass)}*failure message*{typeof(DummyImplementingClass)} is*"); } [Fact] @@ -736,11 +758,14 @@ public void When_its_base_type_and_asserting_not_assignable_it_should_fail_with_ { // Arrange var someObject = new DummyImplementingClass(); - Action act = () => someObject.Should().NotBeAssignableTo("because we want to test the failure {0}", "message"); + + Action act = () => + someObject.Should().NotBeAssignableTo("because we want to test the failure {0}", "message"); // Act / Assert act.Should().Throw() - .WithMessage($"*not be assignable to {typeof(DummyBaseClass)}*failure message*{typeof(DummyImplementingClass)} is*"); + .WithMessage( + $"*not be assignable to {typeof(DummyBaseClass)}*failure message*{typeof(DummyImplementingClass)} is*"); } [Fact] @@ -748,7 +773,9 @@ public void When_an_implemented_interface_type_and_asserting_not_assignable_it_s { // Arrange var someObject = new DummyImplementingClass(); - Action act = () => someObject.Should().NotBeAssignableTo("because we want to test the failure {0}", "message"); + + Action act = () => + someObject.Should().NotBeAssignableTo("because we want to test the failure {0}", "message"); // Act / Assert act.Should().Throw() @@ -766,7 +793,8 @@ public void When_an_unrelated_type_and_asserting_not_assignable_it_should_succee } [Fact] - public void When_not_to_the_unexpected_type_and_asserting_not_assignable_it_should_not_cast_the_returned_object_for_chaining() + public void + When_not_to_the_unexpected_type_and_asserting_not_assignable_it_should_not_cast_the_returned_object_for_chaining() { // Arrange var someObject = new Exception("Actual Message"); @@ -785,11 +813,15 @@ public void When_its_own_type_instance_and_asserting_not_assignable_it_should_fa { // Arrange var someObject = new DummyImplementingClass(); - Action act = () => someObject.Should().NotBeAssignableTo(typeof(DummyImplementingClass), "because we want to test the failure {0}", "message"); + + Action act = () => + someObject.Should().NotBeAssignableTo(typeof(DummyImplementingClass), "because we want to test the failure {0}", + "message"); // Act / Assert act.Should().Throw() - .WithMessage($"*not be assignable to {typeof(DummyImplementingClass)}*failure message*{typeof(DummyImplementingClass)} is*"); + .WithMessage( + $"*not be assignable to {typeof(DummyImplementingClass)}*failure message*{typeof(DummyImplementingClass)} is*"); } [Fact] @@ -797,19 +829,26 @@ public void When_its_base_type_instance_and_asserting_not_assignable_it_should_f { // Arrange var someObject = new DummyImplementingClass(); - Action act = () => someObject.Should().NotBeAssignableTo(typeof(DummyBaseClass), "because we want to test the failure {0}", "message"); + + Action act = () => + someObject.Should() + .NotBeAssignableTo(typeof(DummyBaseClass), "because we want to test the failure {0}", "message"); // Act / Assert act.Should().Throw() - .WithMessage($"*not be assignable to {typeof(DummyBaseClass)}*failure message*{typeof(DummyImplementingClass)} is*"); + .WithMessage( + $"*not be assignable to {typeof(DummyBaseClass)}*failure message*{typeof(DummyImplementingClass)} is*"); } [Fact] - public void When_an_implemented_interface_type_instance_and_asserting_not_assignable_it_should_fail_with_a_useful_message() + public void + When_an_implemented_interface_type_instance_and_asserting_not_assignable_it_should_fail_with_a_useful_message() { // Arrange var someObject = new DummyImplementingClass(); - Action act = () => someObject.Should().NotBeAssignableTo(typeof(IDisposable), "because we want to test the failure {0}", "message"); + + Action act = () => + someObject.Should().NotBeAssignableTo(typeof(IDisposable), "because we want to test the failure {0}", "message"); // Act / Assert act.Should().Throw() @@ -817,15 +856,18 @@ public void When_an_implemented_interface_type_instance_and_asserting_not_assign } [Fact] - public void When_an_implemented_open_generic_interface_type_instance_and_asserting_not_assignable_it_should_fail_with_a_useful_message() + public void + When_an_implemented_open_generic_interface_type_instance_and_asserting_not_assignable_it_should_fail_with_a_useful_message() { // Arrange - var someObject = new System.Collections.Generic.List(); - Action act = () => someObject.Should().NotBeAssignableTo(typeof(System.Collections.Generic.IList<>), "because we want to test the failure {0}", "message"); + var someObject = new List(); + + Action act = () => + someObject.Should().NotBeAssignableTo(typeof(IList<>), "because we want to test the failure {0}", "message"); // Act / Assert act.Should().Throw() - .WithMessage($"*not be assignable to {typeof(System.Collections.Generic.IList<>)}*failure message*{typeof(System.Collections.Generic.List)} is*"); + .WithMessage($"*not be assignable to {typeof(IList<>)}*failure message*{typeof(List)} is*"); } [Fact] @@ -863,7 +905,7 @@ public void When_unrelated_to_open_generic_type_and_asserting_not_assignable_it_ var someObject = new DummyImplementingClass(); // Act / Assert - someObject.Should().NotBeAssignableTo(typeof(System.Collections.Generic.IList<>), "because we want to test the failure {0}", "message"); + someObject.Should().NotBeAssignableTo(typeof(IList<>), "because we want to test the failure {0}", "message"); } } @@ -892,7 +934,8 @@ public void Should_throw_a_helpful_error_when_accidentally_using_equals() Action action = () => someObject.Should().Equals(someObject); // Assert - action.Should().Throw().WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() or BeSameAs() instead?"); + action.Should().Throw() + .WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() or BeSameAs() instead?"); } } @@ -919,7 +962,7 @@ public void When_an_object_is_binary_serializable_it_should_succeed() public void When_an_object_is_binary_serializable_with_non_serializable_members_it_should_succeed() { // Arrange - var subject = new SerializableClassWithNonSerializableMember() + var subject = new SerializableClassWithNonSerializableMember { Name = "John", NonSerializable = "Nonserializable value" @@ -961,7 +1004,8 @@ public void When_an_object_is_not_binary_serializable_it_should_fail() // Assert act.Should().Throw() - .WithMessage("*to be serializable because we need to store it on disk, but serialization failed with:*UnserializableClass*"); + .WithMessage( + "*to be serializable because we need to store it on disk, but serialization failed with:*UnserializableClass*"); } [Fact] @@ -979,7 +1023,8 @@ public void When_an_object_is_binary_serializable_but_not_deserializable_it_shou // Assert act.Should().Throw() - .WithMessage("*to be serializable, but serialization failed with:*BinarySerializableClassMissingDeserializationConstructor*"); + .WithMessage( + "*to be serializable, but serialization failed with:*BinarySerializableClassMissingDeserializationConstructor*"); } [Fact] @@ -1109,7 +1154,8 @@ public void When_an_object_is_not_xml_serializable_it_should_fail() // Assert act.Should().Throw() - .WithMessage("*to be serializable because we need to store it on disk, but serialization failed with:*NonPublicClass*"); + .WithMessage( + "*to be serializable because we need to store it on disk, but serialization failed with:*NonPublicClass*"); } [Fact] @@ -1228,8 +1274,9 @@ public void When_a_data_contract_serializable_object_doesnt_restore_an_ignored_p }; // Act - Action act = () => subject.Should().BeDataContractSerializable( - options => options.Excluding(x => x.Name)); + Action act = () => subject.Should() + .BeDataContractSerializable( + options => options.Excluding(x => x.Name)); // Assert act.Should().NotThrow(); @@ -1242,8 +1289,9 @@ public void When_injecting_null_options_to_BeDataContractSerializable_it_should_ var subject = new DataContractSerializableClassNotRestoringAllProperties(); // Act - Action act = () => subject.Should().BeDataContractSerializable( - options: null); + Action act = () => subject.Should() + .BeDataContractSerializable( + options: null); // Assert act.Should().ThrowExactly() diff --git a/Tests/FluentAssertions.Specs/Primitives/ReferenceTypeAssertionsSpecs.cs b/Tests/FluentAssertions.Specs/Primitives/ReferenceTypeAssertionsSpecs.cs index 9f3256ee1d..81318cfc55 100644 --- a/Tests/FluentAssertions.Specs/Primitives/ReferenceTypeAssertionsSpecs.cs +++ b/Tests/FluentAssertions.Specs/Primitives/ReferenceTypeAssertionsSpecs.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using FluentAssertions.Execution; using FluentAssertions.Extensions; using FluentAssertions.Primitives; @@ -88,10 +89,10 @@ public void When_object_is_of_the_expected_type_it_should_not_throw() public void When_object_is_of_the_expected_open_generic_type_it_should_not_throw() { // Arrange - var aList = new System.Collections.Generic.List(); + var aList = new List(); // Act - Action action = () => aList.Should().BeOfType(typeof(System.Collections.Generic.List<>)); + Action action = () => aList.Should().BeOfType(typeof(List<>)); // Assert action.Should().NotThrow(); @@ -101,14 +102,14 @@ public void When_object_is_of_the_expected_open_generic_type_it_should_not_throw public void When_object_is_not_of_the_expected_open_generic_type_it_should_throw() { // Arrange - var aList = new System.Collections.Generic.List(); + var aList = new List(); // Act - Action action = () => aList.Should().BeOfType(typeof(System.Collections.Generic.Dictionary<,>)); + Action action = () => aList.Should().BeOfType(typeof(Dictionary<,>)); // Assert action.Should().Throw() - .WithMessage($"Expected type to be {typeof(System.Collections.Generic.Dictionary<,>).FullName}, but found {typeof(System.Collections.Generic.List<>).FullName}."); + .WithMessage($"Expected type to be {typeof(Dictionary<,>).FullName}, but found {typeof(List<>).FullName}."); } [Fact] @@ -158,8 +159,8 @@ public void When_an_assertion_fails_on_BeOfType_succeeding_message_should_be_inc // Assert act.Should().Throw() .WithMessage( - "Expected type to be System.Int32, but found System.String.*" + - "Expected type to be System.Int64, but found System.String."); + "Expected type to be System.Int32, but found System.String.*" + + "Expected type to be System.Int64, but found System.String."); } [Fact] @@ -194,14 +195,14 @@ public void When_object_is_of_the_unexpected_generic_type_it_should_throw() public void When_object_is_of_the_unexpected_open_generic_type_it_should_throw() { // Arrange - var aList = new System.Collections.Generic.List(); + var aList = new List(); // Act - Action action = () => aList.Should().NotBeOfType(typeof(System.Collections.Generic.List<>)); + Action action = () => aList.Should().NotBeOfType(typeof(List<>)); // Assert action.Should().Throw() - .WithMessage("Expected type not to be [" + typeof(System.Collections.Generic.List<>).AssemblyQualifiedName + "], but it is."); + .WithMessage("Expected type not to be [" + typeof(List<>).AssemblyQualifiedName + "], but it is."); } [Fact] @@ -221,10 +222,10 @@ public void When_object_is_not_of_the_expected_type_it_should_not_throw() public void When_object_is_not_of_the_unexpected_open_generic_type_it_should_not_throw() { // Arrange - var aList = new System.Collections.Generic.List(); + var aList = new List(); // Act - Action action = () => aList.Should().NotBeOfType(typeof(System.Collections.Generic.Dictionary<,>)); + Action action = () => aList.Should().NotBeOfType(typeof(Dictionary<,>)); // Assert action.Should().NotThrow(); @@ -234,7 +235,7 @@ public void When_object_is_not_of_the_unexpected_open_generic_type_it_should_not public void When_generic_object_is_not_of_the_unexpected_type_it_should_not_throw() { // Arrange - var aList = new System.Collections.Generic.List(); + var aList = new List(); // Act Action action = () => aList.Should().NotBeOfType(); @@ -250,7 +251,7 @@ public void When_non_generic_object_is_not_of_the_unexpected_open_generic_type_i var aString = "blah"; // Act - Action action = () => aString.Should().NotBeOfType(typeof(System.Collections.Generic.Dictionary<,>)); + Action action = () => aString.Should().NotBeOfType(typeof(Dictionary<,>)); // Assert action.Should().NotThrow(); @@ -372,8 +373,8 @@ public void When_an_assertion_on_two_objects_fails_it_should_show_the_properties // Assert act.Should().Throw().WithMessage( "Expected subject to be*FluentAssertions*SomeDto*{*Age = 2*Birthdate = <2009-02-22>*" + - " Name = \"Teddie\"*}, but found*FluentAssertions*SomeDto*{*Age = 37*" + - " Birthdate = <1973-09-20>*Name = \"Dennis\"*}."); + " Name = \"Teddie\"*}, but found*FluentAssertions*SomeDto*{*Age = 37*" + + " Birthdate = <1973-09-20>*Name = \"Dennis\"*}."); } [Fact] @@ -404,7 +405,7 @@ public void When_an_assertion_on_two_unknown_objects_fails_it_should_report_the_ // Assert act.Should().Throw() .WithMessage($"Expected subject to be System.Object (HashCode={other.GetHashCode()}), " + - $"but found System.Object (HashCode={subject.GetHashCode()})."); + $"but found System.Object (HashCode={subject.GetHashCode()})."); } #endregion @@ -421,13 +422,16 @@ public void Should_throw_a_helpful_error_when_accidentally_using_equals() Action action = () => subject.Equals(subject); // Assert - action.Should().Throw().WithMessage("Equals is not part of Fluent Assertions. Did you mean BeSameAs() instead?"); + action.Should().Throw() + .WithMessage("Equals is not part of Fluent Assertions. Did you mean BeSameAs() instead?"); } public class ReferenceTypeAssertionsDummy : ReferenceTypeAssertions { public ReferenceTypeAssertionsDummy(object subject) - : base(subject) { } + : base(subject) + { + } protected override string Identifier => string.Empty; } @@ -450,7 +454,7 @@ public ClassWithCustomEqualMethod(int key) Key = key; } - private int Key { get; set; } + private int Key { get; } private bool Equals(ClassWithCustomEqualMethod other) { diff --git a/Tests/FluentAssertions.Specs/Primitives/SimpleTimeSpanAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Primitives/SimpleTimeSpanAssertionSpecs.cs index c1440c927f..e208d68d20 100644 --- a/Tests/FluentAssertions.Specs/Primitives/SimpleTimeSpanAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Primitives/SimpleTimeSpanAssertionSpecs.cs @@ -339,7 +339,8 @@ public void When_asserting_null_value_to_be_greater_than_or_equal_to_other_value TimeSpan expected = 1.Seconds(); // Act - Action act = () => nullTimeSpan.Should().BeGreaterThanOrEqualTo(expected, "because we want to test the failure {0}", "message"); + Action act = () => + nullTimeSpan.Should().BeGreaterThanOrEqualTo(expected, "because we want to test the failure {0}", "message"); // Assert act.Should().Throw().WithMessage( @@ -377,7 +378,8 @@ public void When_asserting_value_to_be_greater_than_or_equal_to_greater_value_it TimeSpan actual = 1.Seconds(); // Act - Action act = () => actual.Should().BeGreaterThanOrEqualTo(2.Seconds(), "because we want to test the failure {0}", "message"); + Action act = () => + actual.Should().BeGreaterThanOrEqualTo(2.Seconds(), "because we want to test the failure {0}", "message"); // Assert act.Should().Throw().WithMessage( @@ -470,7 +472,8 @@ public void When_asserting_null_value_to_be_less_than_or_equal_to_other_value_it TimeSpan expected = 1.Seconds(); // Act - Action act = () => nullTimeSpan.Should().BeLessThanOrEqualTo(expected, "because we want to test the failure {0}", "message"); + Action act = () => + nullTimeSpan.Should().BeLessThanOrEqualTo(expected, "because we want to test the failure {0}", "message"); // Assert act.Should().Throw().WithMessage( @@ -525,7 +528,8 @@ public void When_accidentally_using_equals_it_should_throw_a_helpful_error() Action act = () => someTimeSpan.Should().Equals(someTimeSpan); // Assert - act.Should().Throw().WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); + act.Should().Throw() + .WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); } #region Be Close To @@ -643,7 +647,8 @@ public void When_time_away_from_another_value_it_should_throw_with_descriptive_m var nearbyTime = new TimeSpan(1, 12, 15, 31, 000); // Act - Action act = () => time.Should().BeCloseTo(nearbyTime, TimeSpan.FromMilliseconds(20), "we want to test the error message"); + Action act = () => + time.Should().BeCloseTo(nearbyTime, TimeSpan.FromMilliseconds(20), "we want to test the error message"); // Assert act.Should().Throw() @@ -682,7 +687,8 @@ public void When_asserting_subject_time_is_not_close_to_a_later_time_it_should_t Action act = () => time.Should().NotBeCloseTo(nearbyTime, 20.Milliseconds()); // Assert - act.Should().Throw().WithMessage("Expected time to not be within 20ms from 1d, 12h, 15m and 31s, but found 1d, 12h, 15m, 30s and 980ms."); + act.Should().Throw() + .WithMessage("Expected time to not be within 20ms from 1d, 12h, 15m and 31s, but found 1d, 12h, 15m, 30s and 980ms."); } [Fact] @@ -696,7 +702,8 @@ public void When_asserting_subject_time_is_not_close_to_an_earlier_time_it_shoul Action act = () => time.Should().NotBeCloseTo(nearbyTime, 20.Milliseconds()); // Assert - act.Should().Throw().WithMessage("Expected time to not be within 20ms from 1d, 12h, 15m and 31s, but found 1d, 12h, 15m, 31s and 20ms."); + act.Should().Throw() + .WithMessage("Expected time to not be within 20ms from 1d, 12h, 15m and 31s, but found 1d, 12h, 15m, 31s and 20ms."); } [Fact] @@ -710,7 +717,8 @@ public void When_asserting_subject_time_is_not_close_to_an_earlier_time_by_a_20m Action act = () => time.Should().NotBeCloseTo(nearbyTime, TimeSpan.FromMilliseconds(20)); // Assert - act.Should().Throw().WithMessage("Expected time to not be within 20ms from 1d, 12h, 15m and 31s, but found 1d, 12h, 15m, 31s and 20ms."); + act.Should().Throw() + .WithMessage("Expected time to not be within 20ms from 1d, 12h, 15m and 31s, but found 1d, 12h, 15m, 31s and 20ms."); } [Fact] @@ -752,7 +760,8 @@ public void When_asserting_subject_time_is_not_close_to_an_earlier_time_by_35ms_ Action act = () => time.Should().NotBeCloseTo(nearbyTime, 35.Milliseconds()); // Assert - act.Should().Throw().WithMessage("Expected time to not be within 35ms from 1d, 12h, 15m and 31s, but found 1d, 12h, 15m, 31s and 35ms."); + act.Should().Throw() + .WithMessage("Expected time to not be within 35ms from 1d, 12h, 15m and 31s, but found 1d, 12h, 15m, 31s and 35ms."); } [Fact] diff --git a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.Be.cs b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.Be.cs index f1caf0a34f..30de5f6751 100644 --- a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.Be.cs +++ b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.Be.cs @@ -155,7 +155,8 @@ public void When_the_expected_string_is_the_same_but_with_trailing_spaces_it_sho } [Fact] - public void When_the_actual_string_is_the_same_as_the_expected_but_with_trailing_spaces_it_should_throw_with_clear_error_message() + public void + When_the_actual_string_is_the_same_as_the_expected_but_with_trailing_spaces_it_should_throw_with_clear_error_message() { // Act Action act = () => "ABC ".Should().Be("ABC", "because I say {0}", "so"); diff --git a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.BeEquivalentTo.cs b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.BeEquivalentTo.cs index fc53dde779..5bdf8fbe81 100644 --- a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.BeEquivalentTo.cs +++ b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.BeEquivalentTo.cs @@ -82,7 +82,8 @@ public void When_string_equivalence_is_asserted_and_actual_value_is_null_then_it } [Fact] - public void When_the_expected_string_is_equivalent_to_the_actual_string_but_with_trailing_spaces_it_should_throw_with_clear_error_message() + public void + When_the_expected_string_is_equivalent_to_the_actual_string_but_with_trailing_spaces_it_should_throw_with_clear_error_message() { // Act Action act = () => "ABC".Should().BeEquivalentTo("abc ", "because I say {0}", "so"); @@ -93,7 +94,8 @@ public void When_the_expected_string_is_equivalent_to_the_actual_string_but_with } [Fact] - public void When_the_actual_string_equivalent_to_the_expected_but_with_trailing_spaces_it_should_throw_with_clear_error_message() + public void + When_the_actual_string_equivalent_to_the_expected_but_with_trailing_spaces_it_should_throw_with_clear_error_message() { // Act Action act = () => "ABC ".Should().BeEquivalentTo("abc", "because I say {0}", "so"); diff --git a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.BeOneOf.cs b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.BeOneOf.cs index 90c6955644..39d7e24c2a 100644 --- a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.BeOneOf.cs +++ b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.BeOneOf.cs @@ -36,7 +36,8 @@ public void When_a_value_is_not_one_of_the_specified_values_it_should_throw_with // Assert action.Should().Throw() - .WithMessage("Expected value to be one of {\"def\", \"xyz\"} because those are the valid values, but found \"abc\"."); + .WithMessage( + "Expected value to be one of {\"def\", \"xyz\"} because those are the valid values, but found \"abc\"."); } [Fact] diff --git a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.Contain.cs b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.Contain.cs index c0f169cb1b..e3ef772c1f 100644 --- a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.Contain.cs +++ b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.Contain.cs @@ -77,7 +77,8 @@ public void When_string_containment_is_asserted_and_actual_value_is_null_then_it public class ContainExactly { [Fact] - public void When_string_containment_once_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_throw() + public void + When_string_containment_once_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_throw() { // Arrange string actual = "ABCDEF"; @@ -88,7 +89,8 @@ public void When_string_containment_once_is_asserted_and_actual_value_does_not_c // Assert act.Should().Throw() - .WithMessage("Expected * \"ABCDEF\" to contain \"XYS\" exactly 1 time because that is required, but found it 0 times."); + .WithMessage( + "Expected * \"ABCDEF\" to contain \"XYS\" exactly 1 time because that is required, but found it 0 times."); } [Fact] @@ -138,7 +140,8 @@ public void When_string_containment_exactly_is_asserted_and_expected_value_is_ne } [Fact] - public void When_string_containment_exactly_is_asserted_and_actual_value_contains_the_expected_string_exactly_expected_times_it_should_not_throw() + public void + When_string_containment_exactly_is_asserted_and_actual_value_contains_the_expected_string_exactly_expected_times_it_should_not_throw() { // Arrange string actual = "ABCDEBCDF"; @@ -152,7 +155,8 @@ public void When_string_containment_exactly_is_asserted_and_actual_value_contain } [Fact] - public void When_string_containment_exactly_is_asserted_and_actual_value_contains_the_expected_string_but_not_exactly_expected_times_it_should_throw() + public void + When_string_containment_exactly_is_asserted_and_actual_value_contains_the_expected_string_but_not_exactly_expected_times_it_should_throw() { // Arrange string actual = "ABCDEBCDF"; @@ -170,7 +174,8 @@ public void When_string_containment_exactly_is_asserted_and_actual_value_contain public class ContainAtLeast { [Fact] - public void When_string_containment_at_least_is_asserted_and_actual_value_contains_the_expected_string_at_least_expected_times_it_should_not_throw() + public void + When_string_containment_at_least_is_asserted_and_actual_value_contains_the_expected_string_at_least_expected_times_it_should_not_throw() { // Arrange string actual = "ABCDEBCDF"; @@ -184,7 +189,8 @@ public void When_string_containment_at_least_is_asserted_and_actual_value_contai } [Fact] - public void When_string_containment_at_least_is_asserted_and_actual_value_contains_the_expected_string_but_not_at_least_expected_times_it_should_throw() + public void + When_string_containment_at_least_is_asserted_and_actual_value_contains_the_expected_string_but_not_at_least_expected_times_it_should_throw() { // Arrange string actual = "ABCDEBCDF"; @@ -199,7 +205,8 @@ public void When_string_containment_at_least_is_asserted_and_actual_value_contai } [Fact] - public void When_string_containment_at_least_once_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_throw_earlier() + public void + When_string_containment_at_least_once_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_throw_earlier() { // Arrange string actual = "ABCDEF"; @@ -232,7 +239,8 @@ public void When_string_containment_at_least_once_is_asserted_and_actual_value_i public class ContainMoreThan { [Fact] - public void When_string_containment_more_than_is_asserted_and_actual_value_contains_the_expected_string_more_than_expected_times_it_should_not_throw() + public void + When_string_containment_more_than_is_asserted_and_actual_value_contains_the_expected_string_more_than_expected_times_it_should_not_throw() { // Arrange string actual = "ABCDEBCDF"; @@ -246,7 +254,8 @@ public void When_string_containment_more_than_is_asserted_and_actual_value_conta } [Fact] - public void When_string_containment_more_than_is_asserted_and_actual_value_contains_the_expected_string_but_not_more_than_expected_times_it_should_throw() + public void + When_string_containment_more_than_is_asserted_and_actual_value_contains_the_expected_string_but_not_more_than_expected_times_it_should_throw() { // Arrange string actual = "ABCDEBCDF"; @@ -261,7 +270,8 @@ public void When_string_containment_more_than_is_asserted_and_actual_value_conta } [Fact] - public void When_string_containment_more_than_once_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_throw() + public void + When_string_containment_more_than_once_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_throw() { // Arrange string actual = "ABCDEF"; @@ -294,7 +304,8 @@ public void When_string_containment_more_than_once_is_asserted_and_actual_value_ public class ContainAtMost { [Fact] - public void When_string_containment_at_most_is_asserted_and_actual_value_contains_the_expected_string_at_most_expected_times_it_should_not_throw() + public void + When_string_containment_at_most_is_asserted_and_actual_value_contains_the_expected_string_at_most_expected_times_it_should_not_throw() { // Arrange string actual = "ABCDEBCDF"; @@ -308,7 +319,8 @@ public void When_string_containment_at_most_is_asserted_and_actual_value_contain } [Fact] - public void When_string_containment_at_most_is_asserted_and_actual_value_contains_the_expected_string_but_not_at_most_expected_times_it_should_throw() + public void + When_string_containment_at_most_is_asserted_and_actual_value_contains_the_expected_string_but_not_at_most_expected_times_it_should_throw() { // Arrange string actual = "ABCDEBCDF"; @@ -323,7 +335,8 @@ public void When_string_containment_at_most_is_asserted_and_actual_value_contain } [Fact] - public void When_string_containment_at_most_once_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_not_throw() + public void + When_string_containment_at_most_once_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_not_throw() { // Arrange string actual = "ABCDEF"; @@ -354,7 +367,8 @@ public void When_string_containment_at_most_once_is_asserted_and_actual_value_is public class ContainsLessThan { [Fact] - public void When_string_containment_less_than_is_asserted_and_actual_value_contains_the_expected_string_less_than_expected_times_it_should_not_throw() + public void + When_string_containment_less_than_is_asserted_and_actual_value_contains_the_expected_string_less_than_expected_times_it_should_not_throw() { // Arrange string actual = "ABCDEBCDF"; @@ -368,7 +382,8 @@ public void When_string_containment_less_than_is_asserted_and_actual_value_conta } [Fact] - public void When_string_containment_less_than_is_asserted_and_actual_value_contains_the_expected_string_but_not_less_than_expected_times_it_should_throw() + public void + When_string_containment_less_than_is_asserted_and_actual_value_contains_the_expected_string_but_not_less_than_expected_times_it_should_throw() { // Arrange string actual = "ABCDEBCDF"; @@ -383,7 +398,8 @@ public void When_string_containment_less_than_is_asserted_and_actual_value_conta } [Fact] - public void When_string_containment_less_than_twice_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_not_throw() + public void + When_string_containment_less_than_twice_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_not_throw() { // Arrange string actual = "ABCDEF"; diff --git a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.ContainAll.cs b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.ContainAll.cs index 3fc0ab8eec..1bf0a1b4a4 100644 --- a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.ContainAll.cs +++ b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.ContainAll.cs @@ -52,7 +52,8 @@ public void When_containment_of_all_strings_in_a_collection_is_asserted_and_all_ } [Fact] - public void When_containment_of_all_strings_in_a_collection_is_asserted_and_equivalent_but_not_exact_matches_exist_for_all_it_should_throw() + public void + When_containment_of_all_strings_in_a_collection_is_asserted_and_equivalent_but_not_exact_matches_exist_for_all_it_should_throw() { // Arrange const string redLowerCase = "red"; @@ -71,7 +72,8 @@ public void When_containment_of_all_strings_in_a_collection_is_asserted_and_equi } [Fact] - public void When_containment_of_all_strings_in_a_collection_is_asserted_and_none_of_the_strings_are_present_it_should_throw() + public void + When_containment_of_all_strings_in_a_collection_is_asserted_and_none_of_the_strings_are_present_it_should_throw() { // Arrange const string red = "red"; @@ -90,7 +92,8 @@ public void When_containment_of_all_strings_in_a_collection_is_asserted_and_none } [Fact] - public void When_containment_of_all_strings_in_a_collection_is_asserted_with_reason_and_assertion_fails_then_failure_message_should_contain_reason() + public void + When_containment_of_all_strings_in_a_collection_is_asserted_with_reason_and_assertion_fails_then_failure_message_should_contain_reason() { // Arrange const string red = "red"; @@ -109,7 +112,8 @@ public void When_containment_of_all_strings_in_a_collection_is_asserted_with_rea } [Fact] - public void When_containment_of_all_strings_in_a_collection_is_asserted_and_only_some_of_the_strings_are_present_it_should_throw() + public void + When_containment_of_all_strings_in_a_collection_is_asserted_and_only_some_of_the_strings_are_present_it_should_throw() { // Arrange const string red = "red"; @@ -155,7 +159,8 @@ public void When_exclusion_of_all_strings_in_an_empty_collection_is_asserted_it_ } [Fact] - public void When_exclusion_of_all_strings_in_a_collection_is_asserted_and_all_strings_in_collection_are_present_it_should_throw() + public void + When_exclusion_of_all_strings_in_a_collection_is_asserted_and_all_strings_in_collection_are_present_it_should_throw() { // Arrange const string red = "red"; @@ -191,7 +196,8 @@ public void When_exclusion_of_all_strings_is_asserted_with_reason_and_assertion_ } [Fact] - public void When_exclusion_of_all_strings_in_a_collection_is_asserted_and_only_some_of_the_strings_in_collection_are_present_it_should_succeed() + public void + When_exclusion_of_all_strings_in_a_collection_is_asserted_and_only_some_of_the_strings_in_collection_are_present_it_should_succeed() { // Arrange const string red = "red"; @@ -208,7 +214,8 @@ public void When_exclusion_of_all_strings_in_a_collection_is_asserted_and_only_s } [Fact] - public void When_exclusion_of_all_strings_in_a_collection_is_asserted_and_none_of_the_strings_in_the_collection_are_present_it_should_succeed() + public void + When_exclusion_of_all_strings_in_a_collection_is_asserted_and_none_of_the_strings_in_the_collection_are_present_it_should_succeed() { // Arrange const string red = "red"; @@ -225,7 +232,8 @@ public void When_exclusion_of_all_strings_in_a_collection_is_asserted_and_none_o } [Fact] - public void When_exclusion_of_all_strings_in_a_collection_is_asserted_and_equivalent_but_not_exact_strings_are_present_in_collection_it_should_succeed() + public void + When_exclusion_of_all_strings_in_a_collection_is_asserted_and_equivalent_but_not_exact_strings_are_present_in_collection_it_should_succeed() { // Arrange const string redWithoutWhitespace = "red"; diff --git a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.ContainAny.cs b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.ContainAny.cs index 39d90bdf1b..4fb6232cbb 100644 --- a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.ContainAny.cs +++ b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.ContainAny.cs @@ -36,7 +36,8 @@ public void When_containment_of_any_string_in_an_empty_collection_is_asserted_it } [Fact] - public void When_containment_of_any_string_in_a_collection_is_asserted_and_all_of_the_strings_are_present_it_should_succeed() + public void + When_containment_of_any_string_in_a_collection_is_asserted_and_all_of_the_strings_are_present_it_should_succeed() { // Arrange const string red = "red"; @@ -52,7 +53,8 @@ public void When_containment_of_any_string_in_a_collection_is_asserted_and_all_o } [Fact] - public void When_containment_of_any_string_in_a_collection_is_asserted_and_only_some_of_the_strings_are_present_it_should_succeed() + public void + When_containment_of_any_string_in_a_collection_is_asserted_and_only_some_of_the_strings_are_present_it_should_succeed() { // Arrange const string red = "red"; @@ -68,7 +70,8 @@ public void When_containment_of_any_string_in_a_collection_is_asserted_and_only_ } [Fact] - public void When_containment_of_any_string_in_a_collection_is_asserted_and_none_of_the_strings_are_present_it_should_throw() + public void + When_containment_of_any_string_in_a_collection_is_asserted_and_none_of_the_strings_are_present_it_should_throw() { // Arrange const string red = "red"; @@ -87,7 +90,8 @@ public void When_containment_of_any_string_in_a_collection_is_asserted_and_none_ } [Fact] - public void When_containment_of_any_string_in_a_collection_is_asserted_and_there_are_equivalent_but_not_exact_matches_it_should_throw() + public void + When_containment_of_any_string_in_a_collection_is_asserted_and_there_are_equivalent_but_not_exact_matches_it_should_throw() { // Arrange const string redLowerCase = "red"; @@ -106,7 +110,8 @@ public void When_containment_of_any_string_in_a_collection_is_asserted_and_there } [Fact] - public void When_containment_of_any_string_in_a_collection_is_asserted_with_reason_and_assertion_fails_then_failure_message_contains_reason() + public void + When_containment_of_any_string_in_a_collection_is_asserted_with_reason_and_assertion_fails_then_failure_message_contains_reason() { // Arrange const string red = "red"; @@ -170,7 +175,8 @@ public void When_exclusion_of_any_string_in_a_collection_is_asserted_and_all_of_ } [Fact] - public void When_exclusion_of_any_string_in_a_collection_is_asserted_and_only_some_of_the_strings_are_present_it_should_throw() + public void + When_exclusion_of_any_string_in_a_collection_is_asserted_and_only_some_of_the_strings_are_present_it_should_throw() { // Arrange const string red = "red"; @@ -207,7 +213,8 @@ public void When_exclusion_of_any_strings_is_asserted_with_reason_and_assertion_ } [Fact] - public void When_exclusion_of_any_string_in_a_collection_is_asserted_and_there_are_equivalent_but_not_exact_matches_it_should_succeed() + public void + When_exclusion_of_any_string_in_a_collection_is_asserted_and_there_are_equivalent_but_not_exact_matches_it_should_succeed() { // Arrange const string redLowerCase = "red"; @@ -224,7 +231,8 @@ public void When_exclusion_of_any_string_in_a_collection_is_asserted_and_there_a } [Fact] - public void When_exclusion_of_any_string_in_a_collection_is_asserted_and_none_of_the_strings_are_present_it_should_succeed() + public void + When_exclusion_of_any_string_in_a_collection_is_asserted_and_none_of_the_strings_are_present_it_should_succeed() { // Arrange const string red = "red"; diff --git a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.ContainEquivalentOf.cs b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.ContainEquivalentOf.cs index e01b02acec..69c7796239 100644 --- a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.ContainEquivalentOf.cs +++ b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.ContainEquivalentOf.cs @@ -77,22 +77,26 @@ public void When_containment_equivalent_of_once_is_asserted_against_null_it_shou } [Fact] - public void When_string_containment_equivalent_of_exactly_once_is_asserted_and_actual_value_is_null_then_it_should_throw_earlier() + public void + When_string_containment_equivalent_of_exactly_once_is_asserted_and_actual_value_is_null_then_it_should_throw_earlier() { // Arrange string actual = null; string expectedSubstring = "XyZ"; // Act - Action act = () => actual.Should().ContainEquivalentOf(expectedSubstring, Exactly.Once(), "that is {0}", "required"); + Action act = () => + actual.Should().ContainEquivalentOf(expectedSubstring, Exactly.Once(), "that is {0}", "required"); // Assert act.Should().Throw() - .WithMessage("Expected * to contain equivalent of \"XyZ\" exactly 1 time because that is required, but found it 0 times."); + .WithMessage( + "Expected * to contain equivalent of \"XyZ\" exactly 1 time because that is required, but found it 0 times."); } [Fact] - public void When_string_containment_equivalent_of_exactly_is_asserted_and_actual_value_contains_the_expected_string_exactly_expected_times_it_should_not_throw() + public void + When_string_containment_equivalent_of_exactly_is_asserted_and_actual_value_contains_the_expected_string_exactly_expected_times_it_should_not_throw() { // Arrange string actual = "abCDEBcDF"; @@ -106,7 +110,8 @@ public void When_string_containment_equivalent_of_exactly_is_asserted_and_actual } [Fact] - public void When_string_containment_equivalent_of_exactly_is_asserted_and_actual_value_contains_the_expected_string_but_not_exactly_expected_times_it_should_throw() + public void + When_string_containment_equivalent_of_exactly_is_asserted_and_actual_value_contains_the_expected_string_but_not_exactly_expected_times_it_should_throw() { // Arrange string actual = "abCDEBcDF"; @@ -117,11 +122,13 @@ public void When_string_containment_equivalent_of_exactly_is_asserted_and_actual // Assert act.Should().Throw() - .WithMessage("Expected * \"abCDEBcDF\" to contain equivalent of \"Bcd\" exactly 3 times, but found it 2 times."); + .WithMessage( + "Expected * \"abCDEBcDF\" to contain equivalent of \"Bcd\" exactly 3 times, but found it 2 times."); } [Fact] - public void When_string_containment_equivalent_of_exactly_once_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_throw() + public void + When_string_containment_equivalent_of_exactly_once_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_throw() { // Arrange string actual = "abCDEf"; @@ -156,7 +163,8 @@ public void When_containment_equivalent_of_exactly_once_is_asserted_against_an_e public class ContainEquivalentOfAtLeast { [Fact] - public void When_string_containment_equivalent_of_at_least_is_asserted_and_actual_value_contains_the_expected_string_at_least_expected_times_it_should_not_throw() + public void + When_string_containment_equivalent_of_at_least_is_asserted_and_actual_value_contains_the_expected_string_at_least_expected_times_it_should_not_throw() { // Arrange string actual = "abCDEBcDF"; @@ -170,7 +178,8 @@ public void When_string_containment_equivalent_of_at_least_is_asserted_and_actua } [Fact] - public void When_string_containment_equivalent_of_at_least_is_asserted_and_actual_value_contains_the_expected_string_but_not_at_least_expected_times_it_should_throw() + public void + When_string_containment_equivalent_of_at_least_is_asserted_and_actual_value_contains_the_expected_string_but_not_at_least_expected_times_it_should_throw() { // Arrange string actual = "abCDEBcDF"; @@ -185,7 +194,8 @@ public void When_string_containment_equivalent_of_at_least_is_asserted_and_actua } [Fact] - public void When_string_containment_equivalent_of_at_least_once_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_throw_earlier() + public void + When_string_containment_equivalent_of_at_least_once_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_throw_earlier() { // Arrange string actual = "abCDEf"; @@ -200,7 +210,8 @@ public void When_string_containment_equivalent_of_at_least_once_is_asserted_and_ } [Fact] - public void When_string_containment_equivalent_of_at_least_once_is_asserted_and_actual_value_is_null_then_it_should_throw_earlier() + public void + When_string_containment_equivalent_of_at_least_once_is_asserted_and_actual_value_is_null_then_it_should_throw_earlier() { // Arrange string actual = null; @@ -218,7 +229,8 @@ public void When_string_containment_equivalent_of_at_least_once_is_asserted_and_ public class ContainEquivalentOfMoreThan { [Fact] - public void When_string_containment_equivalent_of_more_than_is_asserted_and_actual_value_contains_the_expected_string_more_than_expected_times_it_should_not_throw() + public void + When_string_containment_equivalent_of_more_than_is_asserted_and_actual_value_contains_the_expected_string_more_than_expected_times_it_should_not_throw() { // Arrange string actual = "abCDEBcDF"; @@ -232,7 +244,8 @@ public void When_string_containment_equivalent_of_more_than_is_asserted_and_actu } [Fact] - public void When_string_containment_equivalent_of_more_than_is_asserted_and_actual_value_contains_the_expected_string_but_not_more_than_expected_times_it_should_throw() + public void + When_string_containment_equivalent_of_more_than_is_asserted_and_actual_value_contains_the_expected_string_but_not_more_than_expected_times_it_should_throw() { // Arrange string actual = "abCDEBcDF"; @@ -243,11 +256,13 @@ public void When_string_containment_equivalent_of_more_than_is_asserted_and_actu // Assert act.Should().Throw() - .WithMessage("Expected * \"abCDEBcDF\" to contain equivalent of \"Bcd\" more than 2 times, but found it 2 times."); + .WithMessage( + "Expected * \"abCDEBcDF\" to contain equivalent of \"Bcd\" more than 2 times, but found it 2 times."); } [Fact] - public void When_string_containment_equivalent_of_more_than_once_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_throw_earlier() + public void + When_string_containment_equivalent_of_more_than_once_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_throw_earlier() { // Arrange string actual = "abCDEf"; @@ -262,7 +277,8 @@ public void When_string_containment_equivalent_of_more_than_once_is_asserted_and } [Fact] - public void When_string_containment_equivalent_of_more_than_once_is_asserted_and_actual_value_is_null_then_it_should_throw_earlier() + public void + When_string_containment_equivalent_of_more_than_once_is_asserted_and_actual_value_is_null_then_it_should_throw_earlier() { // Arrange string actual = null; @@ -280,7 +296,8 @@ public void When_string_containment_equivalent_of_more_than_once_is_asserted_and public class ContainEquivalentOfAtMost { [Fact] - public void When_string_containment_equivalent_of_at_most_is_asserted_and_actual_value_contains_the_expected_string_at_most_expected_times_it_should_not_throw() + public void + When_string_containment_equivalent_of_at_most_is_asserted_and_actual_value_contains_the_expected_string_at_most_expected_times_it_should_not_throw() { // Arrange string actual = "abCDEBcDF"; @@ -294,7 +311,8 @@ public void When_string_containment_equivalent_of_at_most_is_asserted_and_actual } [Fact] - public void When_string_containment_equivalent_of_at_most_is_asserted_and_actual_value_contains_the_expected_string_but_not_at_most_expected_times_it_should_throw() + public void + When_string_containment_equivalent_of_at_most_is_asserted_and_actual_value_contains_the_expected_string_but_not_at_most_expected_times_it_should_throw() { // Arrange string actual = "abCDEBcDF"; @@ -309,7 +327,8 @@ public void When_string_containment_equivalent_of_at_most_is_asserted_and_actual } [Fact] - public void When_string_containment_equivalent_of_at_most_once_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_not_throw() + public void + When_string_containment_equivalent_of_at_most_once_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_not_throw() { // Arrange string actual = "abCDEf"; @@ -323,7 +342,8 @@ public void When_string_containment_equivalent_of_at_most_once_is_asserted_and_a } [Fact] - public void When_string_containment_equivalent_of_at_most_once_is_asserted_and_actual_value_is_null_then_it_should_not_throw() + public void + When_string_containment_equivalent_of_at_most_once_is_asserted_and_actual_value_is_null_then_it_should_not_throw() { // Arrange string actual = null; @@ -340,7 +360,8 @@ public void When_string_containment_equivalent_of_at_most_once_is_asserted_and_a public class ContainEquivalentOfLessThan { [Fact] - public void When_string_containment_equivalent_of_less_than_is_asserted_and_actual_value_contains_the_expected_string_less_than_expected_times_it_should_not_throw() + public void + When_string_containment_equivalent_of_less_than_is_asserted_and_actual_value_contains_the_expected_string_less_than_expected_times_it_should_not_throw() { // Arrange string actual = "abCDEBcDF"; @@ -354,7 +375,8 @@ public void When_string_containment_equivalent_of_less_than_is_asserted_and_actu } [Fact] - public void When_string_containment_equivalent_of_less_than_is_asserted_and_actual_value_contains_the_expected_string_but_not_less_than_expected_times_it_should_throw() + public void + When_string_containment_equivalent_of_less_than_is_asserted_and_actual_value_contains_the_expected_string_but_not_less_than_expected_times_it_should_throw() { // Arrange string actual = "abCDEBcDF"; @@ -365,11 +387,13 @@ public void When_string_containment_equivalent_of_less_than_is_asserted_and_actu // Assert act.Should().Throw() - .WithMessage("Expected * \"abCDEBcDF\" to contain equivalent of \"Bcd\" less than 2 times, but found it 2 times."); + .WithMessage( + "Expected * \"abCDEBcDF\" to contain equivalent of \"Bcd\" less than 2 times, but found it 2 times."); } [Fact] - public void When_string_containment_equivalent_of_less_than_twice_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_throw() + public void + When_string_containment_equivalent_of_less_than_twice_is_asserted_and_actual_value_does_not_contain_the_expected_string_it_should_throw() { // Arrange string actual = "abCDEf"; @@ -383,7 +407,8 @@ public void When_string_containment_equivalent_of_less_than_twice_is_asserted_an } [Fact] - public void When_string_containment_equivalent_of_less_than_twice_is_asserted_and_actual_value_is_null_then_it_should_not_throw() + public void + When_string_containment_equivalent_of_less_than_twice_is_asserted_and_actual_value_is_null_then_it_should_not_throw() { // Arrange string actual = null; diff --git a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.EndWith.cs b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.EndWith.cs index af77511010..768baf7af0 100644 --- a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.EndWith.cs +++ b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.EndWith.cs @@ -79,8 +79,8 @@ public void When_string_ending_is_compared_with_string_that_is_longer_it_should_ // Assert act.Should().Throw().WithMessage( "Expected string to end with " + - "\"00ABC\", but " + - "\"ABC\" is too short."); + "\"00ABC\", but " + + "\"ABC\" is too short."); } [Fact] diff --git a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.EndWithEquivalentOf.cs b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.EndWithEquivalentOf.cs index b12922a447..e4d9e3e247 100644 --- a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.EndWithEquivalentOf.cs +++ b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.EndWithEquivalentOf.cs @@ -75,8 +75,8 @@ public void When_string_ending_is_compared_with_equivalent_of_string_that_is_lon // Assert act.Should().Throw().WithMessage( "Expected string to end with equivalent of " + - "\"00abc\", but " + - "\"ABC\" is too short."); + "\"00abc\", but " + + "\"ABC\" is too short."); } [Fact] @@ -115,7 +115,8 @@ public void When_asserting_string_does_not_end_with_equivalent_of_a_value_and_it } [Fact] - public void When_asserting_string_does_not_end_with_equivalent_of_a_value_but_it_does_it_should_fail_with_a_descriptive_message() + public void + When_asserting_string_does_not_end_with_equivalent_of_a_value_but_it_does_it_should_fail_with_a_descriptive_message() { // Arrange string value = "ABC"; diff --git a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.Match.cs b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.Match.cs index a32dea22b2..acea709500 100644 --- a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.Match.cs +++ b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.Match.cs @@ -22,7 +22,8 @@ public void When_a_string_does_not_match_a_wildcard_pattern_it_should_throw() // Assert act.Should().Throw() - .WithMessage("Expected subject to match*\"h*earth!\" because that's the universal greeting, but*\"hello world!\" does not."); + .WithMessage( + "Expected subject to match*\"h*earth!\" because that's the universal greeting, but*\"hello world!\" does not."); } [Fact] @@ -106,7 +107,8 @@ public void When_a_string_is_matched_against_an_empty_string_it_should_throw_wit // Assert act.Should().ThrowExactly() - .WithMessage("Cannot match string against an empty string. Provide a wildcard pattern or use the BeEmpty method.*") + .WithMessage( + "Cannot match string against an empty string. Provide a wildcard pattern or use the BeEmpty method.*") .WithParameterName("wildcardPattern"); } } @@ -167,7 +169,8 @@ public void When_a_string_is_negatively_matched_against_an_empty_string_it_shoul // Assert act.Should().ThrowExactly() - .WithMessage("Cannot match string against an empty string. Provide a wildcard pattern or use the NotBeEmpty method.*") + .WithMessage( + "Cannot match string against an empty string. Provide a wildcard pattern or use the NotBeEmpty method.*") .WithParameterName("wildcardPattern"); } } diff --git a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.MatchEquivalentOf.cs b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.MatchEquivalentOf.cs index 1d85483e7c..1d3c3e9d88 100644 --- a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.MatchEquivalentOf.cs +++ b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.MatchEquivalentOf.cs @@ -78,7 +78,8 @@ public void When_a_string_is_matched_against_the_equivalent_of_an_empty_string_i // Assert act.Should().ThrowExactly() - .WithMessage("Cannot match string against an empty string. Provide a wildcard pattern or use the BeEmpty method.*") + .WithMessage( + "Cannot match string against an empty string. Provide a wildcard pattern or use the BeEmpty method.*") .WithParameterName("wildcardPattern"); } } @@ -111,7 +112,7 @@ public void When_a_string_does_match_the_equivalent_of_a_pattern_but_it_shouldnt act .Should().Throw() .WithMessage("Did not expect subject to match the equivalent of*\"*world*\" because that's illegal, " + - "but*\"hello WORLD\" matches."); + "but*\"hello WORLD\" matches."); } [Fact] @@ -128,7 +129,8 @@ public void When_a_string_with_newlines_does_match_the_equivalent_of_a_pattern_b } [Fact] - public void When_a_string_is_negatively_matched_against_the_equivalent_of_null_pattern_it_should_throw_with_a_clear_explanation() + public void + When_a_string_is_negatively_matched_against_the_equivalent_of_null_pattern_it_should_throw_with_a_clear_explanation() { // Arrange string subject = "hello world"; @@ -143,7 +145,8 @@ public void When_a_string_is_negatively_matched_against_the_equivalent_of_null_p } [Fact] - public void When_a_string_is_negatively_matched_against_the_equivalent_of_an_empty_string_it_should_throw_with_a_clear_explanation() + public void + When_a_string_is_negatively_matched_against_the_equivalent_of_an_empty_string_it_should_throw_with_a_clear_explanation() { // Arrange string subject = "hello world"; @@ -153,7 +156,8 @@ public void When_a_string_is_negatively_matched_against_the_equivalent_of_an_emp // Assert act.Should().ThrowExactly() - .WithMessage("Cannot match string against an empty string. Provide a wildcard pattern or use the NotBeEmpty method.*") + .WithMessage( + "Cannot match string against an empty string. Provide a wildcard pattern or use the NotBeEmpty method.*") .WithParameterName("wildcardPattern"); } } diff --git a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.MatchRegex.cs b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.MatchRegex.cs index 675af777c6..a80ec3e027 100644 --- a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.MatchRegex.cs +++ b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.MatchRegex.cs @@ -40,7 +40,8 @@ public void When_a_string_does_not_match_a_regular_expression_string_it_should_t // Assert act.Should().Throw() - .WithMessage("Expected subject to match regex*\"h.*\\sworld?$\" because that's the universal greeting, but*\"hello world!\" does not match."); + .WithMessage( + "Expected subject to match regex*\"h.*\\sworld?$\" because that's the universal greeting, but*\"hello world!\" does not match."); } [Fact] @@ -54,7 +55,7 @@ public void When_a_null_string_is_matched_against_a_regex_string_it_should_throw // Assert act.Should().Throw() - .WithMessage("Expected subject to match regex*\".*\" because it should be a string, but it was ."); + .WithMessage("Expected subject to match regex*\".*\" because it should be a string, but it was ."); } [Fact] @@ -68,8 +69,8 @@ public void When_a_string_is_matched_against_a_null_regex_string_it_should_throw // Assert act.Should().Throw() - .WithMessage("Cannot match string against . Provide a regex pattern or use the BeNull method.*") - .WithParameterName("regularExpression"); + .WithMessage("Cannot match string against . Provide a regex pattern or use the BeNull method.*") + .WithParameterName("regularExpression"); } [Fact] @@ -84,7 +85,7 @@ public void When_a_string_is_matched_against_an_invalid_regex_string_it_should_t // Assert act.Should().Throw() - .WithMessage("Cannot match subject against \".**\" because it is not a valid regular expression.*"); + .WithMessage("Cannot match subject against \".**\" because it is not a valid regular expression.*"); } [Fact] @@ -104,7 +105,7 @@ public void When_a_string_is_matched_against_an_invalid_regex_string_it_should_o // Assert act.Should().Throw() .Which.Message.Should().Contain("is not a valid regular expression") - .And.NotContain("does not match"); + .And.NotContain("does not match"); } [Fact] @@ -148,7 +149,8 @@ public void When_a_string_does_not_match_a_regular_expression_it_should_throw() // Assert act.Should().Throw() - .WithMessage("Expected subject to match regex*\"h.*\\sworld?$\" because that's the universal greeting, but*\"hello world!\" does not match."); + .WithMessage( + "Expected subject to match regex*\"h.*\\sworld?$\" because that's the universal greeting, but*\"hello world!\" does not match."); } [Fact] @@ -180,8 +182,8 @@ public void When_a_string_is_matched_against_a_null_regex_it_should_throw_with_a // Assert act.Should().Throw() - .WithMessage("Cannot match string against . Provide a regex pattern or use the BeNull method.*") - .WithParameterName("regularExpression"); + .WithMessage("Cannot match string against . Provide a regex pattern or use the BeNull method.*") + .WithParameterName("regularExpression"); } [Fact] @@ -225,7 +227,7 @@ public void When_a_string_is_matched_and_the_count_of_matches_do_not_fit_the_exp // Assert act.Should().Throw() - .WithMessage($"Expected subject*Lorem*to match regex*\"Lorem.*\" exactly 2 times, but found it 1 time*"); + .WithMessage("Expected subject*Lorem*to match regex*\"Lorem.*\" exactly 2 times, but found it 1 time*"); } [Fact] @@ -252,7 +254,7 @@ public void When_a_string_is_matched_and_the_expected_count_is_zero_and_string_m // Assert act.Should().Throw() - .WithMessage($"Expected subject*a*to match regex*\"a\" exactly 0 times, but found it 1 time*"); + .WithMessage("Expected subject*a*to match regex*\"a\" exactly 0 times, but found it 1 time*"); } [Fact] @@ -305,7 +307,7 @@ public void When_the_subject_is_empty_and_expected_count_is_more_than_zero_it_fa // Assert act.Should().Throw() - .WithMessage($"Expected subject*to match regex* at least 1 time, but found it 0 times*"); + .WithMessage("Expected subject*to match regex* at least 1 time, but found it 0 times*"); } [Fact] @@ -379,7 +381,8 @@ public void When_a_string_matches_a_regular_expression_string_but_it_shouldnt_it // Assert act.Should().Throw() - .WithMessage("Did not expect subject to match regex*\".*world.*\" because that's illegal, but*\"hello world!\" matches."); + .WithMessage( + "Did not expect subject to match regex*\".*world.*\" because that's illegal, but*\"hello world!\" matches."); } [Fact] @@ -393,7 +396,7 @@ public void When_a_null_string_is_negatively_matched_against_a_regex_string_it_s // Assert act.Should().Throw() - .WithMessage("Expected subject to not match regex*\".*\" because it should not be a string, but it was ."); + .WithMessage("Expected subject to not match regex*\".*\" because it should not be a string, but it was ."); } [Fact] @@ -407,8 +410,8 @@ public void When_a_string_is_negatively_matched_against_a_null_regex_string_it_s // Assert act.Should().Throw() - .WithMessage("Cannot match string against . Provide a regex pattern or use the NotBeNull method.*") - .WithParameterName("regularExpression"); + .WithMessage("Cannot match string against . Provide a regex pattern or use the NotBeNull method.*") + .WithParameterName("regularExpression"); } [Fact] @@ -423,7 +426,7 @@ public void When_a_string_is_negatively_matched_against_an_invalid_regex_string_ // Assert act.Should().Throw() - .WithMessage("Cannot match subject against \".**\" because it is not a valid regular expression.*"); + .WithMessage("Cannot match subject against \".**\" because it is not a valid regular expression.*"); } [Fact] @@ -443,7 +446,7 @@ public void When_a_string_is_negatively_matched_against_an_invalid_regex_string_ // Assert act.Should().Throw() .Which.Message.Should().Contain("is not a valid regular expression") - .And.NotContain("matches"); + .And.NotContain("matches"); } [Fact] @@ -457,7 +460,8 @@ public void When_a_string_is_negatively_matched_against_an_empty_regex_string_it // Assert act.Should().ThrowExactly() - .WithMessage("Cannot match string against an empty regex pattern. Provide a regex pattern or use the NotBeEmpty method.*") + .WithMessage( + "Cannot match string against an empty regex pattern. Provide a regex pattern or use the NotBeEmpty method.*") .WithParameterName("regularExpression"); } @@ -485,7 +489,8 @@ public void When_a_string_matches_a_regular_expression_but_it_shouldnt_it_should // Assert act.Should().Throw() - .WithMessage("Did not expect subject to match regex*\".*world.*\" because that's illegal, but*\"hello world!\" matches."); + .WithMessage( + "Did not expect subject to match regex*\".*world.*\" because that's illegal, but*\"hello world!\" matches."); } [Fact] @@ -517,8 +522,8 @@ public void When_a_string_is_negatively_matched_against_a_null_regex_it_should_t // Assert act.Should().Throw() - .WithMessage("Cannot match string against . Provide a regex pattern or use the NotBeNull method.*") - .WithParameterName("regularExpression"); + .WithMessage("Cannot match string against . Provide a regex pattern or use the NotBeNull method.*") + .WithParameterName("regularExpression"); } [Fact] @@ -532,7 +537,8 @@ public void When_a_string_is_negatively_matched_against_an_empty_regex_it_should // Assert act.Should().ThrowExactly() - .WithMessage("Cannot match string against an empty regex pattern. Provide a regex pattern or use the NotBeEmpty method.*") + .WithMessage( + "Cannot match string against an empty regex pattern. Provide a regex pattern or use the NotBeEmpty method.*") .WithParameterName("regularExpression"); } } diff --git a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.StartWith.cs b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.StartWith.cs index 09e9454da2..1ffccec4f7 100644 --- a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.StartWith.cs +++ b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.StartWith.cs @@ -35,12 +35,13 @@ public void When_string_does_not_start_with_expected_phrase_it_should_throw() // Assert act.Should().Throw().WithMessage( "Expected string to start with \"ABB\" because it should start," + - " but \"ABC\" differs near \"C\" (index 2)."); + " but \"ABC\" differs near \"C\" (index 2)."); } [Fact] [SuppressMessage("ReSharper", "StringLiteralTypo")] - public void When_string_does_not_start_with_expected_phrase_and_one_of_them_is_long_it_should_display_both_strings_on_separate_line() + public void + When_string_does_not_start_with_expected_phrase_and_one_of_them_is_long_it_should_display_both_strings_on_separate_line() { // Act Action act = () => "ABCDEFGHI".Should().StartWith("ABCDDFGHI", "it should {0}", "start"); @@ -48,7 +49,7 @@ public void When_string_does_not_start_with_expected_phrase_and_one_of_them_is_l // Assert act.Should().Throw().WithMessage( "Expected string to start with " + - "*\"ABCDDFGHI\" because it should start, but " + + "*\"ABCDDFGHI\" because it should start, but " + "*\"ABCDEFGHI\" differs near \"EFG\" (index 4)."); } diff --git a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.StartWithEquivalentOf.cs b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.StartWithEquivalentOf.cs index 7f9f18eecd..5a092d8785 100644 --- a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.StartWithEquivalentOf.cs +++ b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.StartWithEquivalentOf.cs @@ -36,7 +36,8 @@ public void When_start_of_string_does_not_meet_equivalent_it_should_throw() [Fact] [SuppressMessage("ReSharper", "StringLiteralTypo")] - public void When_start_of_string_does_not_meet_equivalent_and_one_of_them_is_long_it_should_display_both_strings_on_separate_line() + public void + When_start_of_string_does_not_meet_equivalent_and_one_of_them_is_long_it_should_display_both_strings_on_separate_line() { // Act Action act = () => "ABCDEFGHI".Should().StartWithEquivalentOf("abcddfghi", "it should {0}", "start"); @@ -44,8 +45,8 @@ public void When_start_of_string_does_not_meet_equivalent_and_one_of_them_is_lon // Assert act.Should().Throw().WithMessage( "Expected string to start with equivalent of " + - "*\"abcddfghi\" because it should start, but " + - "*\"ABCDEFGHI\" differs near \"EFG\" (index 4)."); + "*\"abcddfghi\" because it should start, but " + + "*\"ABCDEFGHI\" differs near \"EFG\" (index 4)."); } [Fact] @@ -79,8 +80,8 @@ public void When_start_of_string_is_compared_with_equivalent_of_string_that_is_l // Assert act.Should().Throw().WithMessage( "Expected string to start with equivalent of " + - "\"abcdef\", but " + - "\"ABC\" is too short."); + "\"abcdef\", but " + + "\"ABC\" is too short."); } [Fact] @@ -113,7 +114,8 @@ public void When_asserting_string_does_not_start_with_equivalent_of_a_value_and_ } [Fact] - public void When_asserting_string_does_not_start_with_equivalent_of_a_value_but_it_does_it_should_fail_with_a_descriptive_message() + public void + When_asserting_string_does_not_start_with_equivalent_of_a_value_but_it_does_it_should_fail_with_a_descriptive_message() { // Arrange string value = "ABC"; diff --git a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.cs index 3c415fbd67..5a51095fd0 100644 --- a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.cs @@ -3,9 +3,6 @@ namespace FluentAssertions.Specs.Primitives; -/// public partial class StringAssertionSpecs { [Fact] diff --git a/Tests/FluentAssertions.Specs/Primitives/StringComparisonSpecs.cs b/Tests/FluentAssertions.Specs/Primitives/StringComparisonSpecs.cs index 2fc1a46187..bb936f0b06 100644 --- a/Tests/FluentAssertions.Specs/Primitives/StringComparisonSpecs.cs +++ b/Tests/FluentAssertions.Specs/Primitives/StringComparisonSpecs.cs @@ -269,7 +269,7 @@ public void When_formatting_reason_arguments_it_should_ignore_culture() // Act scope.BecauseOf("{0}", 1.234) - .FailWith("{reason}"); + .FailWith("{reason}"); // Assert scope.Invoking(e => e.Dispose()).Should().Throw -/// assertion specs. -/// () @@ -314,6 +314,7 @@ public void When_formatting_the_context_it_should_ignore_culture() { ["FOO"] = 1.234 }; + var strategy = new CollectingAssertionStrategy(); strategy.HandleFailure(string.Empty); @@ -337,6 +338,7 @@ public void Matching_strings_for_equivalence_ignores_the_culture(string subject, public void Culture_is_ignored_when_sorting_strings() { using var _ = new AssertionScope(); + new[] { "A", "a" }.Should().BeInAscendingOrder() .And.BeInAscendingOrder(e => e) .And.ThenBeInAscendingOrder(e => e) @@ -369,4 +371,6 @@ public void Culture_is_ignored_when_sorting_strings() // Due to CulturedTheory changing CultureInfo [CollectionDefinition(nameof(StringComparisonSpecs), DisableParallelization = true)] -public class StringComparisonDefinition { } +public class StringComparisonDefinition +{ +} diff --git a/Tests/FluentAssertions.Specs/Primitives/TimeOnlyAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Primitives/TimeOnlyAssertionSpecs.cs index 608704a3cf..5e66cb8b7c 100644 --- a/Tests/FluentAssertions.Specs/Primitives/TimeOnlyAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Primitives/TimeOnlyAssertionSpecs.cs @@ -5,7 +5,6 @@ using Xunit.Sdk; #if NET6_0_OR_GREATER - namespace FluentAssertions.Specs.Primitives; public class TimeOnlyAssertionSpecs @@ -238,8 +237,8 @@ public void When_subject_time_is_close_to_the_maximum_time_it_should_succeed() public void When_subject_time_is_close_to_another_value_that_is_later_by_more_than_20ms_it_should_throw() { // Arrange - TimeOnly time = new TimeOnly(12, 15, 30, 979); - TimeOnly nearbyTime = new TimeOnly(12, 15, 31); + TimeOnly time = new(12, 15, 30, 979); + TimeOnly nearbyTime = new(12, 15, 31); // Act Action act = () => time.Should().BeCloseTo(nearbyTime, 20.Milliseconds()); @@ -254,8 +253,8 @@ public void When_subject_time_is_close_to_another_value_that_is_later_by_more_th public void When_subject_time_is_close_to_another_value_that_is_earlier_by_more_than_20ms_it_should_throw() { // Arrange - TimeOnly time = new TimeOnly(12, 15, 31, 021); - TimeOnly nearbyTime = new TimeOnly(12, 15, 31); + TimeOnly time = new(12, 15, 31, 021); + TimeOnly nearbyTime = new(12, 15, 31); // Act Action act = () => time.Should().BeCloseTo(nearbyTime, 20.Milliseconds()); @@ -270,8 +269,8 @@ public void When_subject_time_is_close_to_another_value_that_is_earlier_by_more_ public void When_subject_time_is_close_to_an_earlier_time_by_35ms_it_should_succeed() { // Arrange - TimeOnly time = new TimeOnly(12, 15, 31, 035); - TimeOnly nearbyTime = new TimeOnly(12, 15, 31); + TimeOnly time = new(12, 15, 31, 035); + TimeOnly nearbyTime = new(12, 15, 31); // Act / Assert time.Should().BeCloseTo(nearbyTime, 35.Milliseconds()); @@ -281,8 +280,8 @@ public void When_subject_time_is_close_to_an_earlier_time_by_35ms_it_should_succ public void A_time_is_close_to_a_later_time_when_passing_midnight() { // Arrange - TimeOnly time = new TimeOnly(23, 59, 0); - TimeOnly nearbyTime = new TimeOnly(0, 1, 0); + TimeOnly time = new(23, 59, 0); + TimeOnly nearbyTime = new(0, 1, 0); // Act / Assert time.Should().BeCloseTo(nearbyTime, 2.Minutes()); @@ -292,8 +291,8 @@ public void A_time_is_close_to_a_later_time_when_passing_midnight() public void A_time_is_close_to_an_earlier_time_when_passing_midnight() { // Arrange - TimeOnly time = new TimeOnly(0, 1, 0); - TimeOnly nearbyTime = new TimeOnly(23, 59, 0); + TimeOnly time = new(0, 1, 0); + TimeOnly nearbyTime = new(23, 59, 0); // Act / Assert time.Should().BeCloseTo(nearbyTime, 2.Minutes()); @@ -303,8 +302,8 @@ public void A_time_is_close_to_an_earlier_time_when_passing_midnight() public void A_time_outside_of_the_precision_to_a_later_time_when_passing_midnight_fails() { // Arrange - TimeOnly time = new TimeOnly(23, 58, 59); - TimeOnly nearbyTime = new TimeOnly(0, 1, 0); + TimeOnly time = new(23, 58, 59); + TimeOnly nearbyTime = new(0, 1, 0); // Act Action act = () => time.Should().BeCloseTo(nearbyTime, 2.Minutes()); @@ -318,8 +317,8 @@ public void A_time_outside_of_the_precision_to_a_later_time_when_passing_midnigh public void A_time_outside_of_the_precision_to_an_earlier_time_when_passing_midnight_fails() { // Arrange - TimeOnly time = new TimeOnly(0, 1, 0); - TimeOnly nearbyTime = new TimeOnly(23, 58, 59); + TimeOnly time = new(0, 1, 0); + TimeOnly nearbyTime = new(23, 58, 59); // Act Action act = () => time.Should().BeCloseTo(nearbyTime, 2.Minutes()); @@ -334,7 +333,7 @@ public void When_subject_nulltime_is_close_to_another_it_should_throw() { // Arrange TimeOnly? time = null; - TimeOnly nearbyTime = new TimeOnly(12, 15, 31); + TimeOnly nearbyTime = new(12, 15, 31); // Act Action act = () => time.Should().BeCloseTo(nearbyTime, 35.Milliseconds()); @@ -349,7 +348,7 @@ public void A_null_time_inside_an_assertion_scope_fails() { // Arrange TimeOnly? time = null; - TimeOnly nearbyTime = new TimeOnly(12, 15, 31); + TimeOnly nearbyTime = new(12, 15, 31); // Act Action act = () => @@ -371,7 +370,7 @@ public void A_null_time_is_never_unclose_to_an_other_time() { // Arrange TimeOnly? time = null; - TimeOnly nearbyTime = new TimeOnly(12, 15, 31); + TimeOnly nearbyTime = new(12, 15, 31); // Act Action act = () => time.Should().NotBeCloseTo(nearbyTime, 35.Milliseconds()); @@ -386,7 +385,7 @@ public void A_null_time_inside_an_assertion_scope_is_never_unclose_to_an_other_t { // Arrange TimeOnly? time = null; - TimeOnly nearbyTime = new TimeOnly(12, 15, 31); + TimeOnly nearbyTime = new(12, 15, 31); // Act Action act = () => @@ -476,8 +475,8 @@ public void When_a_time_is_close_to_a_max_value_by_one_tick_it_should_fail() public void When_asserting_subject_time_is_not_close_to_an_earlier_time_it_should_throw() { // Arrange - TimeOnly time = new TimeOnly(12, 15, 31, 020); - TimeOnly nearbyTime = new TimeOnly(12, 15, 31); + TimeOnly time = new(12, 15, 31, 020); + TimeOnly nearbyTime = new(12, 15, 31); // Act Action act = () => time.Should().NotBeCloseTo(nearbyTime, 20.Milliseconds()); @@ -491,8 +490,8 @@ public void When_asserting_subject_time_is_not_close_to_an_earlier_time_it_shoul public void When_asserting_subject_time_is_not_close_to_an_earlier_time_by_a_20ms_timespan_it_should_throw() { // Arrange - TimeOnly time = new TimeOnly(12, 15, 31, 020); - TimeOnly nearbyTime = new TimeOnly(12, 15, 31); + TimeOnly time = new(12, 15, 31, 020); + TimeOnly nearbyTime = new(12, 15, 31); // Act Action act = () => time.Should().NotBeCloseTo(nearbyTime, TimeSpan.FromMilliseconds(20)); @@ -506,19 +505,20 @@ public void When_asserting_subject_time_is_not_close_to_an_earlier_time_by_a_20m public void When_asserting_subject_time_is_not_close_to_another_value_that_is_later_by_more_than_20ms_it_should_succeed() { // Arrange - TimeOnly time = new TimeOnly(12, 15, 30, 979); - TimeOnly nearbyTime = new TimeOnly(12, 15, 31); + TimeOnly time = new(12, 15, 30, 979); + TimeOnly nearbyTime = new(12, 15, 31); // Act / Assert time.Should().NotBeCloseTo(nearbyTime, 20.Milliseconds()); } [Fact] - public void When_asserting_subject_time_is_not_close_to_another_value_that_is_earlier_by_more_than_20ms_it_should_succeed() + public void + When_asserting_subject_time_is_not_close_to_another_value_that_is_earlier_by_more_than_20ms_it_should_succeed() { // Arrange - TimeOnly time = new TimeOnly(12, 15, 31, 021); - TimeOnly nearbyTime = new TimeOnly(12, 15, 31); + TimeOnly time = new(12, 15, 31, 021); + TimeOnly nearbyTime = new(12, 15, 31); // Act / Assert time.Should().NotBeCloseTo(nearbyTime, 20.Milliseconds()); @@ -528,8 +528,8 @@ public void When_asserting_subject_time_is_not_close_to_another_value_that_is_ea public void When_asserting_subject_datetime_is_not_close_to_an_earlier_datetime_by_35ms_it_should_throw() { // Arrange - TimeOnly time = new TimeOnly(12, 15, 31, 035); - TimeOnly nearbyTime = new TimeOnly(12, 15, 31); + TimeOnly time = new(12, 15, 31, 035); + TimeOnly nearbyTime = new(12, 15, 31); // Act Action act = () => time.Should().NotBeCloseTo(nearbyTime, 35.Milliseconds()); @@ -573,8 +573,8 @@ public void When_asserting_subject_time_is_not_close_to_the_maximum_time_it_shou public void A_time_is_not_close_to_a_later_time_when_passing_midnight() { // Arrange - TimeOnly time = new TimeOnly(23, 58, 0); - TimeOnly nearbyTime = new TimeOnly(0, 1, 0); + TimeOnly time = new(23, 58, 0); + TimeOnly nearbyTime = new(0, 1, 0); // Act / Assert time.Should().NotBeCloseTo(nearbyTime, 2.Minutes()); @@ -584,8 +584,8 @@ public void A_time_is_not_close_to_a_later_time_when_passing_midnight() public void A_time_is_not_close_to_an_earlier_time_when_passing_midnight() { // Arrange - TimeOnly time = new TimeOnly(0, 2, 0); - TimeOnly nearbyTime = new TimeOnly(23, 59, 0); + TimeOnly time = new(0, 2, 0); + TimeOnly nearbyTime = new(23, 59, 0); // Act / Assert time.Should().NotBeCloseTo(nearbyTime, 2.Minutes()); @@ -595,28 +595,30 @@ public void A_time_is_not_close_to_an_earlier_time_when_passing_midnight() public void A_time_inside_of_the_precision_to_a_later_time_when_passing_midnight_fails() { // Arrange - TimeOnly time = new TimeOnly(23, 59, 0); - TimeOnly nearbyTime = new TimeOnly(0, 1, 0); + TimeOnly time = new(23, 59, 0); + TimeOnly nearbyTime = new(0, 1, 0); // Act Action act = () => time.Should().NotBeCloseTo(nearbyTime, 2.Minutes()); // Assert - act.Should().Throw().WithMessage("Did not expect * to be within 2m from <00:01:00.000>*, but it was <23:59:00.000>*"); + act.Should().Throw() + .WithMessage("Did not expect * to be within 2m from <00:01:00.000>*, but it was <23:59:00.000>*"); } [Fact] public void A_time_inside_of_the_precision_to_an_earlier_time_when_passing_midnight_fails() { // Arrange - TimeOnly time = new TimeOnly(0, 1, 0); - TimeOnly nearbyTime = new TimeOnly(23, 59, 0); + TimeOnly time = new(0, 1, 0); + TimeOnly nearbyTime = new(23, 59, 0); // Act Action act = () => time.Should().NotBeCloseTo(nearbyTime, 2.Minutes()); // Assert - act.Should().Throw().WithMessage("Did not expect * to be within 2m from <23:59:00.000>*, but it was <00:01:00.000>*"); + act.Should().Throw() + .WithMessage("Did not expect * to be within 2m from <23:59:00.000>*, but it was <00:01:00.000>*"); } } @@ -1318,7 +1320,8 @@ public void Should_throw_a_helpful_error_when_accidentally_using_equals() Action act = () => someTimeOnly.Should().Equals(someTimeOnly); // Assert - act.Should().Throw().WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); + act.Should().Throw() + .WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); } } } diff --git a/Tests/FluentAssertions.Specs/Specialized/AssemblyAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Specialized/AssemblyAssertionSpecs.cs index 0f298777fd..55f8e375ba 100644 --- a/Tests/FluentAssertions.Specs/Specialized/AssemblyAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Specialized/AssemblyAssertionSpecs.cs @@ -180,7 +180,8 @@ public void When_an_assembly_defines_a_type_and_Should_DefineType_is_asserted_it } [Fact] - public void When_an_assembly_does_not_define_a_type_and_Should_DefineType_is_asserted_it_should_fail_with_a_useful_message() + public void + When_an_assembly_does_not_define_a_type_and_Should_DefineType_is_asserted_it_should_fail_with_a_useful_message() { // Arrange var thisAssembly = GetType().Assembly; @@ -192,8 +193,8 @@ public void When_an_assembly_does_not_define_a_type_and_Should_DefineType_is_ass // Assert act.Should().Throw() .WithMessage($"Expected assembly \"{thisAssembly.FullName}\" " + - "to define type \"FakeNamespace\".\"FakeName\" " + - "because we want to test the failure message, but it does not."); + "to define type \"FakeNamespace\".\"FakeName\" " + + "because we want to test the failure message, but it does not."); } [Fact] diff --git a/Tests/FluentAssertions.Specs/Specialized/ExecutionTimeAssertionsSpecs.cs b/Tests/FluentAssertions.Specs/Specialized/ExecutionTimeAssertionsSpecs.cs index 5fca878e49..8d384a9b09 100644 --- a/Tests/FluentAssertions.Specs/Specialized/ExecutionTimeAssertionsSpecs.cs +++ b/Tests/FluentAssertions.Specs/Specialized/ExecutionTimeAssertionsSpecs.cs @@ -94,7 +94,8 @@ public void Actions_with_brackets_fail_with_correctly_formatted_message() var subject = new List(); // Act - Action act = () => subject.ExecutionTimeOf(s => s.AddRange(new object[] { })).Should().BeLessOrEqualTo(1.Nanoseconds()); + Action act = () => + subject.ExecutionTimeOf(s => s.AddRange(new object[] { })).Should().BeLessOrEqualTo(1.Nanoseconds()); // Assert act.Should().ThrowExactly() @@ -302,7 +303,8 @@ public void Actions_with_brackets_fail_with_correctly_formatted_message() var subject = new List(); // Act - Action act = () => subject.ExecutionTimeOf(s => s.AddRange(new object[] { })).Should().BeGreaterThanOrEqualTo(1.Days()); + Action act = () => + subject.ExecutionTimeOf(s => s.AddRange(new object[] { })).Should().BeGreaterThanOrEqualTo(1.Days()); // Assert act.Should().ThrowExactly() @@ -627,7 +629,8 @@ public void When_accidentally_using_equals_it_should_throw_a_helpful_error() Action act = () => subject.ExecutionTimeOf(s => s.ToString()).Should().Equals(1.Seconds()); // Assert - act.Should().Throw().WithMessage("Equals is not part of Fluent Assertions. Did you mean BeLessThanOrEqualTo() or BeGreaterThanOrEqualTo() instead?"); + act.Should().Throw().WithMessage( + "Equals is not part of Fluent Assertions. Did you mean BeLessThanOrEqualTo() or BeGreaterThanOrEqualTo() instead?"); } } diff --git a/Tests/FluentAssertions.Specs/Specialized/TaskAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Specialized/TaskAssertionSpecs.cs index d0d31c2f3f..79ff89dfdd 100644 --- a/Tests/FluentAssertions.Specs/Specialized/TaskAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Specialized/TaskAssertionSpecs.cs @@ -53,6 +53,7 @@ public async Task When_task_completes_fast_t_should_succeed() // Act Func action = () => taskFactory.Awaiting(t => (Task)t.Task).Should(timer).CompleteWithinAsync(100.Milliseconds()); + taskFactory.SetResult(true); timer.Complete(); @@ -93,7 +94,9 @@ public async Task When_task_completes_late_it_should_fail() var taskFactory = new TaskCompletionSource(); // Act - Func action = () => taskFactory.Awaiting(t => (Task)t.Task).Should(timer).CompleteWithinAsync(100.Milliseconds()); + Func action = () => + taskFactory.Awaiting(t => (Task)t.Task).Should(timer).CompleteWithinAsync(100.Milliseconds()); + timer.Complete(); // Assert @@ -130,6 +133,7 @@ public async Task When_task_completes_fast_it_should_throw() Func action = () => taskFactory .Awaiting(t => (Task)t.Task).Should(timer) .NotCompleteWithinAsync(100.Milliseconds()); + taskFactory.SetResult(true); timer.Complete(); @@ -173,6 +177,7 @@ public async Task When_task_completes_late_it_should_succeed() Func action = () => taskFactory .Awaiting(t => (Task)t.Task).Should(timer) .NotCompleteWithinAsync(100.Milliseconds()); + timer.Complete(); // Assert @@ -193,6 +198,7 @@ public async Task When_task_completes_fast_it_should_succeed() // Act Func action = () => taskFactory.Awaiting(t => (Task)t.Task).Should(timer).CompleteWithinAsync(100.Milliseconds()); + taskFactory.SetResult(true); timer.Complete(); @@ -210,6 +216,7 @@ public async Task When_task_completes_late_it_should_fail() // Act Func action = () => taskFactory.Awaiting(t => (Task)t.Task).Should(timer).CompleteWithinAsync(100.Milliseconds()); + timer.Complete(); // Assert diff --git a/Tests/FluentAssertions.Specs/Specialized/TaskCompletionSourceAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Specialized/TaskCompletionSourceAssertionSpecs.cs index 7520f1a565..087c9b2d51 100644 --- a/Tests/FluentAssertions.Specs/Specialized/TaskCompletionSourceAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Specialized/TaskCompletionSourceAssertionSpecs.cs @@ -9,7 +9,6 @@ namespace FluentAssertions.Specs.Specialized; public class TaskCompletionSourceAssertionSpecs { #if NET6_0_OR_GREATER - public class NonGeneric { [Fact] @@ -113,7 +112,8 @@ public async Task When_accidentally_using_equals_it_should_throw_a_helpful_error Func action = () => Task.FromResult(subject.Should().Equals(subject)); // Assert - await action.Should().ThrowAsync().WithMessage("Equals is not part of Fluent Assertions. Did you mean CompleteWithinAsync() instead?"); + await action.Should().ThrowAsync() + .WithMessage("Equals is not part of Fluent Assertions. Did you mean CompleteWithinAsync() instead?"); } } #endif @@ -178,6 +178,7 @@ public async Task When_it_completes_in_time_and_result_is_not_expected_it_should // Act Func action = async () => (await testSubject.Should(timer).CompleteWithinAsync(1.Seconds())).Which.Should().Be(42); + testSubject.SetResult(99); timer.Complete(); @@ -246,7 +247,8 @@ public async Task When_it_completes_in_time_and_it_is_not_expected_it_should_fai timer.Complete(); // Assert - await action.Should().ThrowAsync().WithMessage("Did not expect*to complete within*because test testArg*"); + await action.Should().ThrowAsync() + .WithMessage("Did not expect*to complete within*because test testArg*"); } [Fact] @@ -288,7 +290,8 @@ public async Task When_accidentally_using_equals_with_generic_it_should_throw_a_ Func> action = () => Task.FromResult(subject.Should().Equals(subject)); // Assert - await action.Should().ThrowAsync().WithMessage("Equals is not part of Fluent Assertions. Did you mean CompleteWithinAsync() instead?"); + await action.Should().ThrowAsync() + .WithMessage("Equals is not part of Fluent Assertions. Did you mean CompleteWithinAsync() instead?"); } } } diff --git a/Tests/FluentAssertions.Specs/Specialized/TaskOfTAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Specialized/TaskOfTAssertionSpecs.cs index 07213ba2b6..13556a228f 100644 --- a/Tests/FluentAssertions.Specs/Specialized/TaskOfTAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Specialized/TaskOfTAssertionSpecs.cs @@ -1,14 +1,13 @@ -using System; +#if NETFRAMEWORK +using FluentAssertions.Specs.Common; +#endif +using System; using System.Threading.Tasks; using FluentAssertions.Execution; using FluentAssertions.Extensions; -#if NETFRAMEWORK -using FluentAssertions.Specs.Common; -#endif using FluentAssertions.Specs.Exceptions; using Xunit; using Xunit.Sdk; - using static FluentAssertions.FluentActions; namespace FluentAssertions.Specs.Specialized; @@ -44,6 +43,7 @@ public async Task When_subject_is_null_with_AssertionScope_it_should_fail() Func testAction = () => { using var _ = new AssertionScope(); + return action.Should().CompleteWithinAsync( timeSpan, "because we want to test the failure {0}", "message"); }; @@ -180,11 +180,13 @@ public async Task When_task_does_not_complete_the_result_extension_does_not_hang using var _ = new AssertionScope(); return func.Should(timer).CompleteWithinAsync(100.Milliseconds()).WithResult(2); }; + timer.Complete(); // Assert var assertionTask = action.Should().ThrowAsync() .WithMessage("Expected*to complete within 100ms.*Expected return*to be 2, but found 0."); + await Awaiting(() => assertionTask).Should().CompleteWithinAsync(200.Seconds()); } @@ -337,6 +339,7 @@ public async Task When_subject_is_null_it_should_fail() Func testAction = async () => { using var _ = new AssertionScope(); + await action.Should().NotThrowAfterAsync(waitTime, pollInterval, "because we want to test the failure {0}", "message"); }; diff --git a/Tests/FluentAssertions.Specs/Streams/StreamAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Streams/StreamAssertionSpecs.cs index 0aff414785..108fcb0cc2 100644 --- a/Tests/FluentAssertions.Specs/Streams/StreamAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Streams/StreamAssertionSpecs.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.IO; using FluentAssertions.Execution; using Xunit; @@ -588,7 +587,7 @@ public void When_a_throwing_stream_should_not_have_a_length_it_should_fail(Excep public static TheoryData GetLengthExceptions => new() { // https://docs.microsoft.com/en-us/dotnet/api/system.io.stream.length#exceptions - new IOException("GetLengthExceptionMessage") , + new IOException("GetLengthExceptionMessage"), new NotSupportedException("GetLengthExceptionMessage"), new ObjectDisposedException("GetLengthExceptionMessage") }; diff --git a/Tests/FluentAssertions.Specs/TypeEnumerableExtensionsSpecs.cs b/Tests/FluentAssertions.Specs/TypeEnumerableExtensionsSpecs.cs index 91650f1d00..b65812c4c2 100644 --- a/Tests/FluentAssertions.Specs/TypeEnumerableExtensionsSpecs.cs +++ b/Tests/FluentAssertions.Specs/TypeEnumerableExtensionsSpecs.cs @@ -13,7 +13,10 @@ public class TypeEnumerableExtensionsSpecs [Fact] public void When_selecting_types_that_decorated_with_attribute_it_should_return_the_correct_type() { - var types = new[] { typeof(JustAClass), typeof(ClassWithSomeAttribute), typeof(ClassDerivedFromClassWithSomeAttribute) }; + var types = new[] + { + typeof(JustAClass), typeof(ClassWithSomeAttribute), typeof(ClassDerivedFromClassWithSomeAttribute) + }; types.ThatAreDecoratedWith() .Should() @@ -24,7 +27,10 @@ public void When_selecting_types_that_decorated_with_attribute_it_should_return_ [Fact] public void When_selecting_types_that_decorated_with_attribute_or_inherit_it_should_return_the_correct_type() { - var types = new[] { typeof(JustAClass), typeof(ClassWithSomeAttribute), typeof(ClassDerivedFromClassWithSomeAttribute) }; + var types = new[] + { + typeof(JustAClass), typeof(ClassWithSomeAttribute), typeof(ClassDerivedFromClassWithSomeAttribute) + }; types.ThatAreDecoratedWithOrInherit() .Should() @@ -36,7 +42,10 @@ public void When_selecting_types_that_decorated_with_attribute_or_inherit_it_sho [Fact] public void When_selecting_types_that_not_decorated_with_attribute_it_should_return_the_correct_type() { - var types = new[] { typeof(JustAClass), typeof(ClassWithSomeAttribute), typeof(ClassDerivedFromClassWithSomeAttribute) }; + var types = new[] + { + typeof(JustAClass), typeof(ClassWithSomeAttribute), typeof(ClassDerivedFromClassWithSomeAttribute) + }; types.ThatAreNotDecoratedWith() .Should() @@ -48,7 +57,10 @@ public void When_selecting_types_that_not_decorated_with_attribute_it_should_ret [Fact] public void When_selecting_types_that_not_decorated_with_attribute_or_inherit_it_should_return_the_correct_type() { - var types = new[] { typeof(JustAClass), typeof(ClassWithSomeAttribute), typeof(ClassDerivedFromClassWithSomeAttribute) }; + var types = new[] + { + typeof(JustAClass), typeof(ClassWithSomeAttribute), typeof(ClassDerivedFromClassWithSomeAttribute) + }; types.ThatAreNotDecoratedWithOrInherit() .Should() @@ -233,9 +245,10 @@ internal class ClassDerivedFromClassWithSomeAttribute : ClassWithSomeAttribute { } - [AttributeUsage(AttributeTargets.Class, Inherited = true)] + [AttributeUsage(AttributeTargets.Class)] internal class SomeAttribute : Attribute { } } + #endregion diff --git a/Tests/FluentAssertions.Specs/Types/MethodBaseAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Types/MethodBaseAssertionSpecs.cs index 0bdf4d9840..84a2bf8dc2 100644 --- a/Tests/FluentAssertions.Specs/Types/MethodBaseAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Types/MethodBaseAssertionSpecs.cs @@ -37,7 +37,7 @@ public void When_asserting_an_int_method_returns_string_it_fails_with_a_useful_m // Assert act.Should().Throw() .WithMessage("Expected the return type of method IntMethod to be System.String because we want to test the " + - "error message, but it is \"System.Int32\"."); + "error message, but it is \"System.Int32\"."); } [Fact] @@ -53,7 +53,7 @@ public void When_asserting_a_void_method_returns_string_it_fails_with_a_useful_m // Assert act.Should().Throw() .WithMessage("Expected the return type of method VoidMethod to be System.String because we want to test the " + - "error message, but it is \"System.Void\"."); + "error message, but it is \"System.Void\"."); } [Fact] @@ -117,7 +117,7 @@ public void When_asserting_an_int_method_does_not_return_int_it_fails_with_a_use // Assert act.Should().Throw() .WithMessage("Expected the return type of*IntMethod*not to be System.Int32*because we want to test the " + - "error message, but it is."); + "error message, but it is."); } [Fact] @@ -132,7 +132,8 @@ public void When_subject_is_null_not_return_should_fail() // Assert act.Should().Throw() - .WithMessage("Expected the return type of method not to be *.String *failure message*, but methodInfo is ."); + .WithMessage( + "Expected the return type of method not to be *.String *failure message*, but methodInfo is ."); } [Fact] @@ -180,7 +181,7 @@ public void When_asserting_an_int_method_returnsOfT_string_it_fails_with_a_usefu // Assert act.Should().Throw() .WithMessage("Expected the return type of method IntMethod to be System.String because we want to test the " + - "error message, but it is \"System.Int32\"."); + "error message, but it is \"System.Int32\"."); } [Fact] @@ -228,7 +229,7 @@ public void When_asserting_an_int_method_does_not_returnsOfT_int_it_fails_with_a // Assert act.Should().Throw() .WithMessage("Expected the return type of*IntMethod*not to be System.Int32*because we want to test the " + - "error message, but it is."); + "error message, but it is."); } [Fact] @@ -243,7 +244,8 @@ public void When_subject_is_null_not_returnOfT_should_fail() // Assert act.Should().Throw() - .WithMessage("Expected the return type of method not to be *.String *failure message*, but methodInfo is ."); + .WithMessage( + "Expected the return type of method not to be *.String *failure message*, but methodInfo is ."); } } @@ -275,8 +277,9 @@ public void When_asserting_an_int_method_returns_void_it_fails_with_a_useful_mes // Assert act.Should().Throw() - .WithMessage("Expected the return type of method IntMethod to be void because we want to test the error message " + - "message, but it is \"System.Int32\"."); + .WithMessage( + "Expected the return type of method IntMethod to be void because we want to test the error message " + + "message, but it is \"System.Int32\"."); } [Fact] @@ -380,12 +383,14 @@ public void When_asserting_a_private_member_is_protected_it_throws_with_a_useful // Act Action act = () => - methodInfo.Should().HaveAccessModifier(CSharpAccessModifier.Protected, "we want to test the error {0}", "message"); + methodInfo.Should() + .HaveAccessModifier(CSharpAccessModifier.Protected, "we want to test the error {0}", "message"); // Assert act.Should().Throw() - .WithMessage("Expected method PrivateMethod to be Protected because we want to test the error message, but it is " + - "Private."); + .WithMessage( + "Expected method PrivateMethod to be Protected because we want to test the error message, but it is " + + "Private."); } [Fact] @@ -420,8 +425,9 @@ public void When_asserting_a_protected_member_is_public_it_throws_with_a_useful_ // Assert act.Should().Throw() - .WithMessage("Expected method set_ProtectedSetProperty to be Public because we want to test the error message, but it" + - " is Protected."); + .WithMessage( + "Expected method set_ProtectedSetProperty to be Public because we want to test the error message, but it" + + " is Protected."); } [Fact] @@ -456,8 +462,9 @@ public void When_asserting_a_public_member_is_internal_it_throws_with_a_useful_m // Assert act.Should().Throw() - .WithMessage("Expected method get_PublicGetProperty to be Internal because we want to test the error message, but it" + - " is Public."); + .WithMessage( + "Expected method get_PublicGetProperty to be Internal because we want to test the error message, but it" + + " is Public."); } [Fact] @@ -483,12 +490,13 @@ public void When_asserting_an_internal_member_is_protectedInternal_it_throws_wit // Act Action act = () => methodInfo.Should().HaveAccessModifier(CSharpAccessModifier.ProtectedInternal, "because we want to test the" + - " error {0}", "message"); + " error {0}", "message"); // Assert act.Should().Throw() - .WithMessage("Expected method InternalMethod to be ProtectedInternal because we want to test the error message, but" + - " it is Internal."); + .WithMessage( + "Expected method InternalMethod to be ProtectedInternal because we want to test the error message, but" + + " it is Internal."); } [Fact] @@ -517,8 +525,9 @@ public void When_asserting_a_protected_internal_member_is_private_it_throws_with // Assert act.Should().Throw() - .WithMessage("Expected method ProtectedInternalMethod to be Private because we want to test the error message, but it is " + - "ProtectedInternal."); + .WithMessage( + "Expected method ProtectedInternalMethod to be Private because we want to test the error message, but it is " + + "ProtectedInternal."); } [Fact] @@ -590,7 +599,8 @@ public void When_asserting_a_private_member_is_not_private_it_throws_with_a_usef // Act Action act = () => - methodInfo.Should().NotHaveAccessModifier(CSharpAccessModifier.Private, "we want to test the error {0}", "message"); + methodInfo.Should() + .NotHaveAccessModifier(CSharpAccessModifier.Private, "we want to test the error {0}", "message"); // Assert act.Should().Throw() @@ -627,7 +637,8 @@ public void When_asserting_a_protected_member_is_not_protected_it_throws_with_a_ // Assert act.Should().Throw() - .WithMessage("Expected method set_ProtectedSetProperty not to be Protected*because we want to test the error message*"); + .WithMessage( + "Expected method set_ProtectedSetProperty not to be Protected*because we want to test the error message*"); } [Fact] @@ -701,7 +712,7 @@ public void When_asserting_an_internal_member_is_not_internal_it_throws_with_a_u // Act Action act = () => methodInfo.Should().NotHaveAccessModifier(CSharpAccessModifier.Internal, "because we want to test the" + - " error {0}", "message"); + " error {0}", "message"); // Assert act.Should().Throw() @@ -730,11 +741,13 @@ public void When_asserting_a_protected_internal_member_is_not_protected_internal // Act Action act = () => - methodInfo.Should().NotHaveAccessModifier(CSharpAccessModifier.ProtectedInternal, "we want to test the error {0}", "message"); + methodInfo.Should().NotHaveAccessModifier(CSharpAccessModifier.ProtectedInternal, "we want to test the error {0}", + "message"); // Assert act.Should().Throw() - .WithMessage("Expected method ProtectedInternalMethod not to be ProtectedInternal*because we want to test the error message*"); + .WithMessage( + "Expected method ProtectedInternalMethod not to be ProtectedInternal*because we want to test the error message*"); } [Fact] diff --git a/Tests/FluentAssertions.Specs/Types/MethodInfoAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Types/MethodInfoAssertionSpecs.cs index 94880a7636..770e490ac5 100644 --- a/Tests/FluentAssertions.Specs/Types/MethodInfoAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Types/MethodInfoAssertionSpecs.cs @@ -114,7 +114,8 @@ public class BeDecoratedWithOfT public void When_asserting_a_method_is_decorated_with_attribute_and_it_is_it_succeeds() { // Arrange - MethodInfo methodInfo = typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); + MethodInfo methodInfo = + typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); // Act Action act = () => @@ -142,7 +143,8 @@ public void When_asserting_a_method_is_decorated_with_MethodImpl_attribute_and_i public void When_asserting_a_constructor_is_decorated_with_MethodImpl_attribute_and_it_is_it_succeeds() { // Arrange - ConstructorInfo constructorMethodInfo = typeof(ClassWithMethodWithImplementationAttribute).GetConstructor(Type.EmptyTypes); + ConstructorInfo constructorMethodInfo = + typeof(ClassWithMethodWithImplementationAttribute).GetConstructor(Type.EmptyTypes); // Act Action act = () => @@ -156,7 +158,8 @@ public void When_asserting_a_constructor_is_decorated_with_MethodImpl_attribute_ public void When_asserting_a_method_is_decorated_with_MethodImpl_attribute_and_it_is_not_it_throws() { // Arrange - MethodInfo methodInfo = typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); + MethodInfo methodInfo = + typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); // Act Action act = () => @@ -166,7 +169,7 @@ public void When_asserting_a_method_is_decorated_with_MethodImpl_attribute_and_i act.Should().Throw() .WithMessage( "Expected method Void FluentAssertions*ClassWithAllMethodsDecoratedWithDummyAttribute.PublicDoNothing to be decorated with " + - "System.Runtime.CompilerServices.MethodImplAttribute, but that attribute was not found."); + "System.Runtime.CompilerServices.MethodImplAttribute, but that attribute was not found."); } [Fact] @@ -183,7 +186,7 @@ public void When_asserting_a_method_is_decorated_with_MethodImpl_attribute_with_ act.Should().Throw() .WithMessage( "Expected method Void FluentAssertions*ClassWithMethodWithImplementationAttribute.NoOptions to be decorated with " + - "System.Runtime.CompilerServices.MethodImplAttribute, but that attribute was not found."); + "System.Runtime.CompilerServices.MethodImplAttribute, but that attribute was not found."); } [Fact] @@ -200,7 +203,7 @@ public void When_asserting_a_method_is_decorated_with_MethodImpl_attribute_with_ act.Should().Throw() .WithMessage( "Expected method Void FluentAssertions*ClassWithMethodWithImplementationAttribute.ZeroOptions to be decorated with " + - "System.Runtime.CompilerServices.MethodImplAttribute, but that attribute was not found."); + "System.Runtime.CompilerServices.MethodImplAttribute, but that attribute was not found."); } [Fact] @@ -217,14 +220,15 @@ public void When_asserting_a_class_is_decorated_with_MethodImpl_attribute_and_it act.Should().Throw() .WithMessage( "Expected type FluentAssertions*ClassWithAllMethodsDecoratedWithDummyAttribute to be decorated with " + - "System.Runtime.CompilerServices.MethodImplAttribute, but the attribute was not found."); + "System.Runtime.CompilerServices.MethodImplAttribute, but the attribute was not found."); } [Fact] public void When_a_method_is_decorated_with_an_attribute_it_should_allow_chaining_assertions_on_it() { // Arrange - MethodInfo methodInfo = typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); + MethodInfo methodInfo = + typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); // Act Action act = () => methodInfo.Should().BeDecoratedWith().Which.Filter.Should().BeFalse(); @@ -237,7 +241,8 @@ public void When_a_method_is_decorated_with_an_attribute_it_should_allow_chainin public void When_asserting_a_method_is_decorated_with_an_attribute_but_it_is_not_it_throws_with_a_useful_message() { // Arrange - MethodInfo methodInfo = typeof(ClassWithMethodsThatAreNotDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); + MethodInfo methodInfo = + typeof(ClassWithMethodsThatAreNotDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); // Act Action act = () => @@ -247,15 +252,16 @@ public void When_asserting_a_method_is_decorated_with_an_attribute_but_it_is_not act.Should().Throw() .WithMessage( "Expected method Void FluentAssertions*ClassWithMethodsThatAreNotDecoratedWithDummyAttribute.PublicDoNothing to be decorated with " + - "FluentAssertions*DummyMethodAttribute because we want to test the error message," + - " but that attribute was not found."); + "FluentAssertions*DummyMethodAttribute because we want to test the error message," + + " but that attribute was not found."); } [Fact] public void When_injecting_a_null_predicate_into_BeDecoratedWith_it_should_throw() { // Arrange - MethodInfo methodInfo = typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); + MethodInfo methodInfo = + typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); // Act Action act = () => methodInfo.Should().BeDecoratedWith(isMatchingAttributePredicate: null); @@ -269,7 +275,8 @@ public void When_injecting_a_null_predicate_into_BeDecoratedWith_it_should_throw public void When_asserting_a_method_is_decorated_with_attribute_matching_a_predicate_and_it_is_it_succeeds() { // Arrange - MethodInfo methodInfo = typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); + MethodInfo methodInfo = + typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); // Act Action act = () => @@ -294,45 +301,52 @@ public void When_asserting_a_method_is_decorated_with_MethodImpl_attribute_match } [Fact] - public void When_asserting_a_method_is_decorated_with_an_attribute_matching_a_predicate_but_it_is_not_it_throws_with_a_useful_message() + public void + When_asserting_a_method_is_decorated_with_an_attribute_matching_a_predicate_but_it_is_not_it_throws_with_a_useful_message() { // Arrange - MethodInfo methodInfo = typeof(ClassWithMethodsThatAreNotDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); + MethodInfo methodInfo = + typeof(ClassWithMethodsThatAreNotDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); // Act Action act = () => - methodInfo.Should().BeDecoratedWith(d => !d.Filter, "because we want to test the error {0}", "message"); + methodInfo.Should() + .BeDecoratedWith(d => !d.Filter, "because we want to test the error {0}", "message"); // Assert act.Should().Throw() .WithMessage( "Expected method Void FluentAssertions*ClassWithMethodsThatAreNotDecoratedWithDummyAttribute.PublicDoNothing to be decorated with " + - "FluentAssertions*DummyMethodAttribute because we want to test the error message," + - " but that attribute was not found."); + "FluentAssertions*DummyMethodAttribute because we want to test the error message," + + " but that attribute was not found."); } [Fact] - public void When_asserting_a_method_is_decorated_with_an_MethodImpl_attribute_matching_a_predicate_but_it_is_not_it_throws() + public void + When_asserting_a_method_is_decorated_with_an_MethodImpl_attribute_matching_a_predicate_but_it_is_not_it_throws() { // Arrange MethodInfo methodInfo = typeof(ClassWithMethodWithImplementationAttribute).GetParameterlessMethod("DoNotInlineMe"); // Act Action act = () => - methodInfo.Should().BeDecoratedWith(x => x.Value == MethodImplOptions.AggressiveInlining); + methodInfo.Should().BeDecoratedWith(x => x.Value == MethodImplOptions.AggressiveInlining); // Assert act.Should().Throw() .WithMessage( "Expected method Void FluentAssertions*ClassWithMethodWithImplementationAttribute.DoNotInlineMe to be decorated with " + - "System.Runtime.CompilerServices.MethodImplAttribute, but that attribute was not found."); + "System.Runtime.CompilerServices.MethodImplAttribute, but that attribute was not found."); } [Fact] - public void When_asserting_a_method_is_decorated_with_an_attribute_and_multiple_attributes_match_continuation_using_the_matched_value_should_fail() + public void + When_asserting_a_method_is_decorated_with_an_attribute_and_multiple_attributes_match_continuation_using_the_matched_value_should_fail() { // Arrange - MethodInfo methodInfo = typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothingWithSameAttributeTwice"); + MethodInfo methodInfo = + typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod( + "PublicDoNothingWithSameAttributeTwice"); // Act Action act = @@ -369,7 +383,8 @@ public class NotBeDecoratedWithOfT public void When_asserting_a_method_is_not_decorated_with_attribute_and_it_is_not_it_succeeds() { // Arrange - MethodInfo methodInfo = typeof(ClassWithMethodsThatAreNotDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); + MethodInfo methodInfo = + typeof(ClassWithMethodsThatAreNotDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); // Act Action act = () => @@ -383,7 +398,8 @@ public void When_asserting_a_method_is_not_decorated_with_attribute_and_it_is_no public void When_asserting_a_method_is_not_decorated_with_MethodImpl_attribute_and_it_is_not_it_succeeds() { // Arrange - MethodInfo methodInfo = typeof(ClassWithMethodsThatAreNotDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); + MethodInfo methodInfo = + typeof(ClassWithMethodsThatAreNotDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); // Act Action act = () => @@ -397,7 +413,8 @@ public void When_asserting_a_method_is_not_decorated_with_MethodImpl_attribute_a public void When_asserting_a_constructor_is_not_decorated_with_MethodImpl_attribute_and_it_is_not_it_succeeds() { // Arrange - ConstructorInfo constructorMethodInfo = typeof(ClassWithMethodWithImplementationAttribute).GetConstructor(new[] { typeof(string) }); + ConstructorInfo constructorMethodInfo = + typeof(ClassWithMethodWithImplementationAttribute).GetConstructor(new[] { typeof(string) }); // Act Action act = () => @@ -411,7 +428,8 @@ public void When_asserting_a_constructor_is_not_decorated_with_MethodImpl_attrib public void When_asserting_a_method_is_not_decorated_with_an_attribute_but_it_is_it_throws_with_a_useful_message() { // Arrange - MethodInfo methodInfo = typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); + MethodInfo methodInfo = + typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); // Act Action act = () => @@ -421,8 +439,8 @@ public void When_asserting_a_method_is_not_decorated_with_an_attribute_but_it_is act.Should().Throw() .WithMessage( "Expected method Void FluentAssertions*ClassWithAllMethodsDecoratedWithDummyAttribute.PublicDoNothing to not be decorated with " + - "FluentAssertions*DummyMethodAttribute because we want to test the error message," + - " but that attribute was found."); + "FluentAssertions*DummyMethodAttribute because we want to test the error message," + + " but that attribute was found."); } [Fact] @@ -437,8 +455,8 @@ public void When_asserting_a_method_is_not_decorated_with_MethodImpl_attribute_a // Assert act.Should().Throw() - .WithMessage( - "Expected method Void FluentAssertions*ClassWithMethodWithImplementationAttribute.DoNotInlineMe to not be decorated with " + + .WithMessage( + "Expected method Void FluentAssertions*ClassWithMethodWithImplementationAttribute.DoNotInlineMe to not be decorated with " + "System.Runtime.CompilerServices.MethodImplAttribute, but that attribute was found."); } @@ -446,7 +464,8 @@ public void When_asserting_a_method_is_not_decorated_with_MethodImpl_attribute_a public void When_asserting_a_method_is_not_decorated_with_attribute_matching_a_predicate_and_it_is_not_it_succeeds() { // Arrange - MethodInfo methodInfo = typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); + MethodInfo methodInfo = + typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); // Act Action act = () => @@ -460,7 +479,8 @@ public void When_asserting_a_method_is_not_decorated_with_attribute_matching_a_p public void When_injecting_a_null_predicate_into_NotBeDecoratedWith_it_should_throw() { // Arrange - MethodInfo methodInfo = typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); + MethodInfo methodInfo = + typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); // Act Action act = () => methodInfo.Should().NotBeDecoratedWith(isMatchingAttributePredicate: null); @@ -471,21 +491,24 @@ public void When_injecting_a_null_predicate_into_NotBeDecoratedWith_it_should_th } [Fact] - public void When_asserting_a_method_is_not_decorated_with_an_attribute_matching_a_predicate_but_it_is_it_throws_with_a_useful_message() + public void + When_asserting_a_method_is_not_decorated_with_an_attribute_matching_a_predicate_but_it_is_it_throws_with_a_useful_message() { // Arrange - MethodInfo methodInfo = typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); + MethodInfo methodInfo = + typeof(ClassWithAllMethodsDecoratedWithDummyAttribute).GetParameterlessMethod("PublicDoNothing"); // Act Action act = () => - methodInfo.Should().NotBeDecoratedWith(d => d.Filter, "because we want to test the error {0}", "message"); + methodInfo.Should() + .NotBeDecoratedWith(d => d.Filter, "because we want to test the error {0}", "message"); // Assert act.Should().Throw() .WithMessage( "Expected method Void FluentAssertions*ClassWithAllMethodsDecoratedWithDummyAttribute.PublicDoNothing to not be decorated with " + - "FluentAssertions*DummyMethodAttribute because we want to test the error message," + - " but that attribute was found."); + "FluentAssertions*DummyMethodAttribute because we want to test the error message," + + " but that attribute was found."); } [Fact] diff --git a/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorAssertionSpecs.cs index 33a4988b19..ceeb249806 100644 --- a/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorAssertionSpecs.cs @@ -39,7 +39,8 @@ public void When_asserting_methods_are_virtual_but_non_virtual_methods_are_found } [Fact] - public void When_asserting_methods_are_virtual_but_non_virtual_methods_are_found_it_should_throw_with_descriptive_message() + public void + When_asserting_methods_are_virtual_but_non_virtual_methods_are_found_it_should_throw_with_descriptive_message() { // Arrange var methodSelector = new MethodInfoSelector(typeof(ClassWithNonVirtualPublicMethods)); @@ -51,11 +52,11 @@ public void When_asserting_methods_are_virtual_but_non_virtual_methods_are_found // Assert act.Should().Throw() .WithMessage("Expected all selected methods" + - " to be virtual because we want to test the error message," + - " but the following methods are not virtual:*" + - "Void FluentAssertions*ClassWithNonVirtualPublicMethods.PublicDoNothing*" + - "Void FluentAssertions*ClassWithNonVirtualPublicMethods.InternalDoNothing*" + - "Void FluentAssertions*ClassWithNonVirtualPublicMethods.ProtectedDoNothing"); + " to be virtual because we want to test the error message," + + " but the following methods are not virtual:*" + + "Void FluentAssertions*ClassWithNonVirtualPublicMethods.PublicDoNothing*" + + "Void FluentAssertions*ClassWithNonVirtualPublicMethods.InternalDoNothing*" + + "Void FluentAssertions*ClassWithNonVirtualPublicMethods.ProtectedDoNothing"); } } @@ -90,7 +91,8 @@ public void When_asserting_methods_are_not_virtual_but_virtual_methods_are_found } [Fact] - public void When_asserting_methods_are_not_virtual_but_virtual_methods_are_found_it_should_throw_with_descriptive_message() + public void + When_asserting_methods_are_not_virtual_but_virtual_methods_are_found_it_should_throw_with_descriptive_message() { // Arrange var methodSelector = new MethodInfoSelector(typeof(ClassWithAllMethodsVirtual)); @@ -102,11 +104,11 @@ public void When_asserting_methods_are_not_virtual_but_virtual_methods_are_found // Assert act.Should().Throw() .WithMessage("Expected all selected methods" + - " not to be virtual because we want to test the error message," + - " but the following methods are virtual" + - "*ClassWithAllMethodsVirtual.PublicVirtualDoNothing" + - "*ClassWithAllMethodsVirtual.InternalVirtualDoNothing" + - "*ClassWithAllMethodsVirtual.ProtectedVirtualDoNothing*"); + " not to be virtual because we want to test the error message," + + " but the following methods are virtual" + + "*ClassWithAllMethodsVirtual.PublicVirtualDoNothing" + + "*ClassWithAllMethodsVirtual.InternalVirtualDoNothing" + + "*ClassWithAllMethodsVirtual.ProtectedVirtualDoNothing*"); } } @@ -158,7 +160,8 @@ public void When_asserting_methods_are_decorated_with_attribute_but_they_are_not } [Fact] - public void When_asserting_methods_are_decorated_with_attribute_but_they_are_not_it_should_throw_with_descriptive_message() + public void + When_asserting_methods_are_decorated_with_attribute_but_they_are_not_it_should_throw_with_descriptive_message() { // Arrange var methodSelector = new MethodInfoSelector(typeof(ClassWithMethodsThatAreNotDecoratedWithDummyAttribute)); @@ -170,11 +173,11 @@ public void When_asserting_methods_are_decorated_with_attribute_but_they_are_not // Assert act.Should().Throw() .WithMessage("Expected all selected methods to be decorated with" + - " FluentAssertions*DummyMethodAttribute because we want to test the error message," + - " but the following methods are not:*" + - "Void FluentAssertions*ClassWithMethodsThatAreNotDecoratedWithDummyAttribute.PublicDoNothing*" + - "Void FluentAssertions*ClassWithMethodsThatAreNotDecoratedWithDummyAttribute.ProtectedDoNothing*" + - "Void FluentAssertions*ClassWithMethodsThatAreNotDecoratedWithDummyAttribute.PrivateDoNothing"); + " FluentAssertions*DummyMethodAttribute because we want to test the error message," + + " but the following methods are not:*" + + "Void FluentAssertions*ClassWithMethodsThatAreNotDecoratedWithDummyAttribute.PublicDoNothing*" + + "Void FluentAssertions*ClassWithMethodsThatAreNotDecoratedWithDummyAttribute.ProtectedDoNothing*" + + "Void FluentAssertions*ClassWithMethodsThatAreNotDecoratedWithDummyAttribute.PrivateDoNothing"); } } @@ -226,22 +229,24 @@ public void When_asserting_methods_are_not_decorated_with_attribute_but_they_are } [Fact] - public void When_asserting_methods_are_not_decorated_with_attribute_but_they_are_it_should_throw_with_descriptive_message() + public void + When_asserting_methods_are_not_decorated_with_attribute_but_they_are_it_should_throw_with_descriptive_message() { // Arrange var methodSelector = new MethodInfoSelector(typeof(ClassWithAllMethodsDecoratedWithDummyAttribute)); // Act - Action act = () => - methodSelector.Should().NotBeDecoratedWith("because we want to test the error {0}", "message"); + Action act = () => methodSelector.Should() + .NotBeDecoratedWith("because we want to test the error {0}", "message"); // Assert act.Should().Throw() - .WithMessage("Expected all selected methods to not be decorated*DummyMethodAttribute*because we want to test the error message" + - "*ClassWithAllMethodsDecoratedWithDummyAttribute.PublicDoNothing*" + - "*ClassWithAllMethodsDecoratedWithDummyAttribute.PublicDoNothingWithSameAttributeTwice*" + - "*ClassWithAllMethodsDecoratedWithDummyAttribute.ProtectedDoNothing*" + - "*ClassWithAllMethodsDecoratedWithDummyAttribute.PrivateDoNothing"); + .WithMessage( + "Expected all selected methods to not be decorated*DummyMethodAttribute*because we want to test the error message" + + "*ClassWithAllMethodsDecoratedWithDummyAttribute.PublicDoNothing*" + + "*ClassWithAllMethodsDecoratedWithDummyAttribute.PublicDoNothingWithSameAttributeTwice*" + + "*ClassWithAllMethodsDecoratedWithDummyAttribute.ProtectedDoNothing*" + + "*ClassWithAllMethodsDecoratedWithDummyAttribute.PrivateDoNothing"); } } @@ -274,10 +279,10 @@ public void When_not_all_methods_have_specified_accessor_it_should_throw() // Assert act.Should().Throw() .WithMessage("Expected all selected methods to be Public" + - ", but the following methods are not:*" + - "Void FluentAssertions*ClassWithNonPublicMethods.PublicDoNothing*" + - "Void FluentAssertions*ClassWithNonPublicMethods.DoNothingWithParameter*" + - "Void FluentAssertions*ClassWithNonPublicMethods.DoNothingWithAnotherParameter"); + ", but the following methods are not:*" + + "Void FluentAssertions*ClassWithNonPublicMethods.PublicDoNothing*" + + "Void FluentAssertions*ClassWithNonPublicMethods.DoNothingWithParameter*" + + "Void FluentAssertions*ClassWithNonPublicMethods.DoNothingWithAnotherParameter"); } [Fact] @@ -293,11 +298,11 @@ public void When_not_all_methods_have_specified_accessor_it_should_throw_with_de // Assert act.Should().Throw() .WithMessage("Expected all selected methods to be Public" + - " because we want to test the error message" + - ", but the following methods are not:*" + - "Void FluentAssertions*ClassWithNonPublicMethods.PublicDoNothing*" + - "Void FluentAssertions*ClassWithNonPublicMethods.DoNothingWithParameter*" + - "Void FluentAssertions*ClassWithNonPublicMethods.DoNothingWithAnotherParameter"); + " because we want to test the error message" + + ", but the following methods are not:*" + + "Void FluentAssertions*ClassWithNonPublicMethods.PublicDoNothing*" + + "Void FluentAssertions*ClassWithNonPublicMethods.DoNothingWithParameter*" + + "Void FluentAssertions*ClassWithNonPublicMethods.DoNothingWithAnotherParameter"); } } @@ -330,8 +335,8 @@ public void When_any_method_have_specified_accessor_it_should_throw() // Assert act.Should().Throw() .WithMessage("Expected all selected methods to not be Public" + - ", but the following methods are:*" + - "Void FluentAssertions*ClassWithPublicMethods.PublicDoNothing*"); + ", but the following methods are:*" + + "Void FluentAssertions*ClassWithPublicMethods.PublicDoNothing*"); } [Fact] @@ -347,9 +352,9 @@ public void When_any_method_have_specified_accessor_it_should_throw_with_descrip // Assert act.Should().Throw() .WithMessage("Expected all selected methods to not be Public" + - " because we want to test the error message" + - ", but the following methods are:*" + - "Void FluentAssertions*ClassWithPublicMethods.PublicDoNothing*"); + " because we want to test the error message" + + ", but the following methods are:*" + + "Void FluentAssertions*ClassWithPublicMethods.PublicDoNothing*"); } } diff --git a/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs b/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs index 5d7fd435bc..cbe47fb470 100644 --- a/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs +++ b/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs @@ -196,7 +196,8 @@ public void When_selecting_methods_decorated_with_an_inheritable_attribute_it_sh } [Fact] - public void When_selecting_methods_decorated_with_or_inheriting_an_inheritable_attribute_it_should_only_return_the_applicable_methods() + public void + When_selecting_methods_decorated_with_or_inheriting_an_inheritable_attribute_it_should_only_return_the_applicable_methods() { // Arrange Type type = typeof(TestClassForMethodSelectorWithInheritableAttributeDerived); @@ -222,7 +223,8 @@ public void When_selecting_methods_not_decorated_with_an_inheritable_attribute_i } [Fact] - public void When_selecting_methods_not_decorated_with_or_inheriting_an_inheritable_attribute_it_should_only_return_the_applicable_methods() + public void + When_selecting_methods_not_decorated_with_or_inheriting_an_inheritable_attribute_it_should_only_return_the_applicable_methods() { // Arrange Type type = typeof(TestClassForMethodSelectorWithInheritableAttributeDerived); @@ -241,33 +243,38 @@ public void When_selecting_methods_decorated_with_a_noninheritable_attribute_it_ Type type = typeof(TestClassForMethodSelectorWithNonInheritableAttributeDerived); // Act - IEnumerable methods = type.Methods().ThatAreDecoratedWith().ToArray(); + IEnumerable methods = type.Methods().ThatAreDecoratedWith() + .ToArray(); // Assert methods.Should().BeEmpty(); } [Fact] - public void When_selecting_methods_decorated_with_or_inheriting_a_noninheritable_attribute_it_should_only_return_the_applicable_methods() + public void + When_selecting_methods_decorated_with_or_inheriting_a_noninheritable_attribute_it_should_only_return_the_applicable_methods() { // Arrange Type type = typeof(TestClassForMethodSelectorWithNonInheritableAttributeDerived); // Act - IEnumerable methods = type.Methods().ThatAreDecoratedWithOrInherit().ToArray(); + IEnumerable methods = + type.Methods().ThatAreDecoratedWithOrInherit().ToArray(); // Assert methods.Should().BeEmpty(); } [Fact] - public void When_selecting_methods_not_decorated_with_a_noninheritable_attribute_it_should_only_return_the_applicable_methods() + public void + When_selecting_methods_not_decorated_with_a_noninheritable_attribute_it_should_only_return_the_applicable_methods() { // Arrange Type type = typeof(TestClassForMethodSelectorWithNonInheritableAttributeDerived); // Act - IEnumerable methods = type.Methods().ThatAreNotDecoratedWith().ToArray(); + IEnumerable methods = type.Methods().ThatAreNotDecoratedWith() + .ToArray(); // Assert methods.Should().ContainSingle(); @@ -388,13 +395,15 @@ public void When_selecting_methods_that_are_not_static_it_should_only_return_the } [Fact] - public void When_selecting_methods_not_decorated_with_or_inheriting_a_noninheritable_attribute_it_should_only_return_the_applicable_methods() + public void + When_selecting_methods_not_decorated_with_or_inheriting_a_noninheritable_attribute_it_should_only_return_the_applicable_methods() { // Arrange Type type = typeof(TestClassForMethodSelectorWithNonInheritableAttributeDerived); // Act - IEnumerable methods = type.Methods().ThatAreNotDecoratedWithOrInherit().ToArray(); + IEnumerable methods = + type.Methods().ThatAreNotDecoratedWithOrInherit().ToArray(); // Assert methods.Should().ContainSingle(); @@ -427,7 +436,8 @@ public void When_accidentally_using_equals_it_should_throw_a_helpful_error() Action action = () => type.Methods().Should().Equals(null); // Assert - action.Should().Throw().WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); + action.Should().Throw() + .WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); } } @@ -490,7 +500,8 @@ internal class TestClassForMethodSelectorWithInheritableAttributeDerived : TestC public override void PublicVirtualVoidMethodWithAttribute() { } } -internal class TestClassForMethodSelectorWithNonInheritableAttributeDerived : TestClassForMethodSelectorWithNonInheritableAttribute +internal class TestClassForMethodSelectorWithNonInheritableAttributeDerived + : TestClassForMethodSelectorWithNonInheritableAttribute { public override void PublicVirtualVoidMethodWithAttribute() { } } @@ -524,7 +535,7 @@ public class DummyMethodNonInheritableAttributeAttribute : Attribute public bool Filter { get; set; } } -[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)] +[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] public class DummyMethodAttribute : Attribute { public bool Filter { get; set; } diff --git a/Tests/FluentAssertions.Specs/Types/PropertyInfoAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Types/PropertyInfoAssertionSpecs.cs index 1020926507..bffbe31bbc 100644 --- a/Tests/FluentAssertions.Specs/Types/PropertyInfoAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Types/PropertyInfoAssertionSpecs.cs @@ -29,7 +29,8 @@ public void When_asserting_that_a_property_is_virtual_and_it_is_then_it_succeeds public void When_asserting_that_a_property_is_virtual_and_it_is_not_then_it_fails_with_useful_message() { // Arrange - PropertyInfo propertyInfo = typeof(ClassWithNonVirtualPublicProperties).GetRuntimeProperty("PublicNonVirtualProperty"); + PropertyInfo propertyInfo = + typeof(ClassWithNonVirtualPublicProperties).GetRuntimeProperty("PublicNonVirtualProperty"); // Act Action act = () => @@ -37,10 +38,10 @@ public void When_asserting_that_a_property_is_virtual_and_it_is_not_then_it_fail // Assert act.Should().Throw() - .WithMessage( - "Expected property String FluentAssertions*ClassWithNonVirtualPublicProperties.PublicNonVirtualProperty" + - " to be virtual because we want to test the error message," + - " but it is not."); + .WithMessage( + "Expected property String FluentAssertions*ClassWithNonVirtualPublicProperties.PublicNonVirtualProperty" + + " to be virtual because we want to test the error message," + + " but it is not."); } [Fact] @@ -65,7 +66,8 @@ public class NotBeVirtual public void When_asserting_that_a_property_is_not_virtual_and_it_is_not_then_it_succeeds() { // Arrange - PropertyInfo propertyInfo = typeof(ClassWithNonVirtualPublicProperties).GetRuntimeProperty("PublicNonVirtualProperty"); + PropertyInfo propertyInfo = + typeof(ClassWithNonVirtualPublicProperties).GetRuntimeProperty("PublicNonVirtualProperty"); // Act Action act = () => @@ -87,10 +89,10 @@ public void When_asserting_that_a_property_is_not_virtual_and_it_is_then_it_fail // Assert act.Should().Throw() - .WithMessage( - "Expected property *ClassWithAllPropertiesVirtual.PublicVirtualProperty" + - " not to be virtual because we want to test the error message," + - " but it is."); + .WithMessage( + "Expected property *ClassWithAllPropertiesVirtual.PublicVirtualProperty" + + " not to be virtual because we want to test the error message," + + " but it is."); } [Fact] @@ -115,7 +117,8 @@ public class BeDecortatedWithOfT public void When_asserting_a_property_is_decorated_with_attribute_and_it_is_it_succeeds() { // Arrange - PropertyInfo propertyInfo = typeof(ClassWithAllPropertiesDecoratedWithDummyAttribute).GetRuntimeProperty("PublicProperty"); + PropertyInfo propertyInfo = + typeof(ClassWithAllPropertiesDecoratedWithDummyAttribute).GetRuntimeProperty("PublicProperty"); // Act Action act = () => @@ -129,7 +132,8 @@ public void When_asserting_a_property_is_decorated_with_attribute_and_it_is_it_s public void When_a_property_is_decorated_with_an_attribute_it_allow_chaining_assertions() { // Arrange - PropertyInfo propertyInfo = typeof(ClassWithAllPropertiesDecoratedWithDummyAttribute).GetRuntimeProperty("PublicProperty"); + PropertyInfo propertyInfo = + typeof(ClassWithAllPropertiesDecoratedWithDummyAttribute).GetRuntimeProperty("PublicProperty"); // Act Action act = () => @@ -140,10 +144,12 @@ public void When_a_property_is_decorated_with_an_attribute_it_allow_chaining_ass } [Fact] - public void When_a_property_is_decorated_with_an_attribute_and_multiple_attributes_match_continuation_using_the_matched_value_fail() + public void + When_a_property_is_decorated_with_an_attribute_and_multiple_attributes_match_continuation_using_the_matched_value_fail() { // Arrange - PropertyInfo propertyInfo = typeof(ClassWithAllPropertiesDecoratedWithDummyAttribute).GetRuntimeProperty("PublicPropertyWithSameAttributeTwice"); + PropertyInfo propertyInfo = typeof(ClassWithAllPropertiesDecoratedWithDummyAttribute).GetRuntimeProperty( + "PublicPropertyWithSameAttributeTwice"); // Act Action act = () => @@ -157,7 +163,8 @@ public void When_a_property_is_decorated_with_an_attribute_and_multiple_attribut public void When_asserting_a_property_is_decorated_with_attribute_and_it_is_not_it_throw_with_useful_message() { // Arrange - PropertyInfo propertyInfo = typeof(ClassWithPropertiesThatAreNotDecoratedWithDummyAttribute).GetRuntimeProperty("PublicProperty"); + PropertyInfo propertyInfo = + typeof(ClassWithPropertiesThatAreNotDecoratedWithDummyAttribute).GetRuntimeProperty("PublicProperty"); // Act Action act = () => @@ -165,38 +172,41 @@ public void When_asserting_a_property_is_decorated_with_attribute_and_it_is_not_ // Assert act.Should().Throw() - .WithMessage("Expected property String " + - "FluentAssertions*ClassWithPropertiesThatAreNotDecoratedWithDummyAttribute.PublicProperty to be decorated with " + - "FluentAssertions*DummyPropertyAttribute because we want to test the error message, but that attribute was not found."); + .WithMessage("Expected property String " + + "FluentAssertions*ClassWithPropertiesThatAreNotDecoratedWithDummyAttribute.PublicProperty to be decorated with " + + "FluentAssertions*DummyPropertyAttribute because we want to test the error message, but that attribute was not found."); } [Fact] - public void When_asserting_a_property_is_decorated_with_an_attribute_matching_a_predicate_but_it_is_not_it_throw_with_useful_message() + public void + When_asserting_a_property_is_decorated_with_an_attribute_matching_a_predicate_but_it_is_not_it_throw_with_useful_message() { // Arrange - PropertyInfo propertyInfo = typeof(ClassWithPropertiesThatAreNotDecoratedWithDummyAttribute).GetRuntimeProperty("PublicProperty"); + PropertyInfo propertyInfo = + typeof(ClassWithPropertiesThatAreNotDecoratedWithDummyAttribute).GetRuntimeProperty("PublicProperty"); // Act Action act = () => - propertyInfo.Should().BeDecoratedWith(d => d.Value == "NotARealValue", "because we want to test the error {0}", "message"); + propertyInfo.Should().BeDecoratedWith(d => d.Value == "NotARealValue", + "because we want to test the error {0}", "message"); // Assert act.Should().Throw() .WithMessage( "Expected property String FluentAssertions*ClassWithPropertiesThatAreNotDecoratedWithDummyAttribute.PublicProperty to be decorated with " + - "FluentAssertions*DummyPropertyAttribute because we want to test the error message," + - " but that attribute was not found."); + "FluentAssertions*DummyPropertyAttribute because we want to test the error message," + + " but that attribute was not found."); } [Fact] public void When_asserting_a_property_is_decorated_with_attribute_matching_a_predicate_and_it_is_it_succeeds() { // Arrange - PropertyInfo propertyInfo = typeof(ClassWithAllPropertiesDecoratedWithDummyAttribute).GetRuntimeProperty("PublicProperty"); + PropertyInfo propertyInfo = + typeof(ClassWithAllPropertiesDecoratedWithDummyAttribute).GetRuntimeProperty("PublicProperty"); // Act - Action act = () => - propertyInfo.Should().BeDecoratedWith(d => d.Value == "Value"); + Action act = () => propertyInfo.Should().BeDecoratedWith(d => d.Value == "Value"); // Assert act.Should().NotThrow(); @@ -214,14 +224,16 @@ public void When_subject_is_null_be_decorated_withOfT_should_fail() // Assert act.Should().Throw() - .WithMessage("Expected property to be decorated with *.DummyPropertyAttribute *failure message*, but propertyInfo is ."); + .WithMessage( + "Expected property to be decorated with *.DummyPropertyAttribute *failure message*, but propertyInfo is ."); } [Fact] public void When_asserting_property_is_decorated_with_null_it_should_throw() { // Arrange - PropertyInfo propertyInfo = typeof(ClassWithAllPropertiesDecoratedWithDummyAttribute).GetRuntimeProperty("PublicProperty"); + PropertyInfo propertyInfo = + typeof(ClassWithAllPropertiesDecoratedWithDummyAttribute).GetRuntimeProperty("PublicProperty"); // Act Action act = () => @@ -247,7 +259,8 @@ public void When_subject_is_null_not_be_decorated_withOfT_should_fail() // Assert act.Should().Throw() - .WithMessage("Expected property to not be decorated with *.DummyPropertyAttribute *failure message*, but propertyInfo is ."); + .WithMessage( + "Expected property to not be decorated with *.DummyPropertyAttribute *failure message*, but propertyInfo is ."); } [Fact] @@ -280,7 +293,8 @@ public void When_asserting_a_readonly_property_is_writable_it_fails_with_useful_ // Assert action .Should().Throw() - .WithMessage("Expected propertyInfo ReadOnlyProperty to have a setter because we want to test the error message."); + .WithMessage( + "Expected propertyInfo ReadOnlyProperty to have a setter because we want to test the error message."); } [Fact] @@ -365,7 +379,8 @@ public void When_asserting_a_writeonly_property_is_readable_it_fails_with_useful // Assert action .Should().Throw() - .WithMessage("Expected property WriteOnlyProperty to have a getter because we want to test the error message, but it does not."); + .WithMessage( + "Expected property WriteOnlyProperty to have a getter because we want to test the error message, but it does not."); } [Fact] @@ -411,7 +426,8 @@ public void When_asserting_a_readwrite_property_is_not_writable_it_fails_with_us // Assert action .Should().Throw() - .WithMessage("Expected propertyInfo ReadWriteProperty not to have a setter because we want to test the error message."); + .WithMessage( + "Expected propertyInfo ReadWriteProperty not to have a setter because we want to test the error message."); } [Fact] @@ -426,7 +442,8 @@ public void When_asserting_a_writeonly_property_is_not_writable_it_fails_with_us // Assert action .Should().Throw() - .WithMessage("Expected propertyInfo WriteOnlyProperty not to have a setter because we want to test the error message."); + .WithMessage( + "Expected propertyInfo WriteOnlyProperty not to have a setter because we want to test the error message."); } [Fact] @@ -459,7 +476,8 @@ public void When_asserting_a_readonly_property_is_not_readable_it_fails_with_use // Assert action .Should().Throw() - .WithMessage("Expected propertyInfo ReadOnlyProperty not to have a getter because we want to test the error message."); + .WithMessage( + "Expected propertyInfo ReadOnlyProperty not to have a getter because we want to test the error message."); } [Fact] @@ -474,7 +492,8 @@ public void When_asserting_a_readwrite_property_is_not_readable_it_fails_with_us // Assert action .Should().Throw() - .WithMessage("Expected propertyInfo ReadWriteProperty not to have a getter because we want to test the error message."); + .WithMessage( + "Expected propertyInfo ReadWriteProperty not to have a getter because we want to test the error message."); } [Fact] @@ -528,11 +547,13 @@ public void When_asserting_a_private_read_public_write_property_is_public_readab PropertyInfo propertyInfo = typeof(ClassWithProperties).GetRuntimeProperty("WritePrivateReadProperty"); // Act - Action action = () => propertyInfo.Should().BeReadable(CSharpAccessModifier.Public, "we want to test the error {0}", "message"); + Action action = () => + propertyInfo.Should().BeReadable(CSharpAccessModifier.Public, "we want to test the error {0}", "message"); // Assert action.Should().Throw() - .WithMessage("Expected method get_WritePrivateReadProperty to be Public because we want to test the error message, but it is Private."); + .WithMessage( + "Expected method get_WritePrivateReadProperty to be Public because we want to test the error message, but it is Private."); } [Fact] @@ -588,11 +609,13 @@ public void When_asserting_a_private_write_public_read_property_is_public_writab PropertyInfo propertyInfo = typeof(ClassWithProperties).GetRuntimeProperty("ReadPrivateWriteProperty"); // Act - Action action = () => propertyInfo.Should().BeWritable(CSharpAccessModifier.Public, "we want to test the error {0}", "message"); + Action action = () => + propertyInfo.Should().BeWritable(CSharpAccessModifier.Public, "we want to test the error {0}", "message"); // Assert action.Should().Throw() - .WithMessage("Expected method set_ReadPrivateWriteProperty to be Public because we want to test the error message, but it is Private."); + .WithMessage( + "Expected method set_ReadPrivateWriteProperty to be Public because we want to test the error message, but it is Private."); } [Fact] @@ -653,7 +676,7 @@ public void When_asserting_a_String_property_returns_an_Int32_it_throw_with_a_us // Assert action.Should().Throw() .WithMessage("Expected Type of property StringProperty to be System.Int32 because we want to test the error " + - "message, but it is System.String."); + "message, but it is System.String."); } [Fact] @@ -714,7 +737,7 @@ public void When_asserting_a_String_property_returnsOfT_an_Int32_it_throw_with_a // Assert action.Should().Throw() .WithMessage("Expected Type of property StringProperty to be System.Int32 because we want to test the error " + - "message, but it is System.String."); + "message, but it is System.String."); } } @@ -745,7 +768,7 @@ public void When_asserting_a_String_property_does_not_return_a_String_it_throw_w // Assert action.Should().Throw() .WithMessage("Expected Type of property StringProperty not to be*String*because we want to test the error " + - "message, but it is."); + "message, but it is."); } [Fact] @@ -806,7 +829,7 @@ public void When_asserting_a_String_property_does_not_returnsOfT_a_String_it_thr // Assert action.Should().Throw() .WithMessage("Expected Type of property StringProperty not to be*String*because we want to test the error " + - "message, but it is."); + "message, but it is."); } } diff --git a/Tests/FluentAssertions.Specs/Types/PropertyInfoSelectorAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Types/PropertyInfoSelectorAssertionSpecs.cs index 3f775420ae..e099ae79e2 100644 --- a/Tests/FluentAssertions.Specs/Types/PropertyInfoSelectorAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Types/PropertyInfoSelectorAssertionSpecs.cs @@ -50,12 +50,12 @@ public void // Assert act.Should().Throw() - .WithMessage("Expected all selected properties" + - " to be virtual because we want to test the error message," + - " but the following properties are not virtual:*" + - "String FluentAssertions*ClassWithNonVirtualPublicProperties.PublicNonVirtualProperty*" + - "String FluentAssertions*ClassWithNonVirtualPublicProperties.InternalNonVirtualProperty*" + - "String FluentAssertions*ClassWithNonVirtualPublicProperties.ProtectedNonVirtualProperty"); + .WithMessage("Expected all selected properties" + + " to be virtual because we want to test the error message," + + " but the following properties are not virtual:*" + + "String FluentAssertions*ClassWithNonVirtualPublicProperties.PublicNonVirtualProperty*" + + "String FluentAssertions*ClassWithNonVirtualPublicProperties.InternalNonVirtualProperty*" + + "String FluentAssertions*ClassWithNonVirtualPublicProperties.ProtectedNonVirtualProperty"); } } @@ -102,12 +102,12 @@ public void // Assert act.Should().Throw() - .WithMessage("Expected all selected properties" + - " not to be virtual because we want to test the error message," + - " but the following properties are virtual*" + - "*ClassWithAllPropertiesVirtual.PublicVirtualProperty" + - "*ClassWithAllPropertiesVirtual.InternalVirtualProperty" + - "*ClassWithAllPropertiesVirtual.ProtectedVirtualProperty"); + .WithMessage("Expected all selected properties" + + " not to be virtual because we want to test the error message," + + " but the following properties are virtual*" + + "*ClassWithAllPropertiesVirtual.PublicVirtualProperty" + + "*ClassWithAllPropertiesVirtual.InternalVirtualProperty" + + "*ClassWithAllPropertiesVirtual.ProtectedVirtualProperty"); } } @@ -152,16 +152,16 @@ public void // Act Action act = () => propertyInfoSelector.Should() - .BeDecoratedWith("because we want to test the error {0}", "message"); + .BeDecoratedWith("because we want to test the error {0}", "message"); // Assert act.Should().Throw() .WithMessage("Expected all selected properties to be decorated with" + - " FluentAssertions*DummyPropertyAttribute because we want to test the error message," + - " but the following properties are not:*" + - "String FluentAssertions*ClassWithPropertiesThatAreNotDecoratedWithDummyAttribute.PublicProperty*" + - "String FluentAssertions*ClassWithPropertiesThatAreNotDecoratedWithDummyAttribute.InternalProperty*" + - "String FluentAssertions*ClassWithPropertiesThatAreNotDecoratedWithDummyAttribute.ProtectedProperty"); + " FluentAssertions*DummyPropertyAttribute because we want to test the error message," + + " but the following properties are not:*" + + "String FluentAssertions*ClassWithPropertiesThatAreNotDecoratedWithDummyAttribute.PublicProperty*" + + "String FluentAssertions*ClassWithPropertiesThatAreNotDecoratedWithDummyAttribute.InternalProperty*" + + "String FluentAssertions*ClassWithPropertiesThatAreNotDecoratedWithDummyAttribute.ProtectedProperty"); } } @@ -206,16 +206,16 @@ public void // Act Action act = () => propertyInfoSelector.Should() - .NotBeDecoratedWith("because we want to test the error {0}", "message"); + .NotBeDecoratedWith("because we want to test the error {0}", "message"); // Assert act.Should().Throw() .WithMessage("Expected all selected properties not to be decorated*" + - "DummyPropertyAttribute*" + - "because we want to test the error message*" + - "ClassWithAllPropertiesDecoratedWithDummyAttribute.PublicProperty*" + - "ClassWithAllPropertiesDecoratedWithDummyAttribute.InternalProperty*" + - "ClassWithAllPropertiesDecoratedWithDummyAttribute.ProtectedProperty*"); + "DummyPropertyAttribute*" + + "because we want to test the error message*" + + "ClassWithAllPropertiesDecoratedWithDummyAttribute.PublicProperty*" + + "ClassWithAllPropertiesDecoratedWithDummyAttribute.InternalProperty*" + + "ClassWithAllPropertiesDecoratedWithDummyAttribute.ProtectedProperty*"); } } @@ -301,7 +301,8 @@ public void When_accidentally_using_equals_it_should_throw_a_helpful_error() Action action = () => someObject.Equals(someObject); // Assert - action.Should().Throw().WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); + action.Should().Throw() + .WithMessage("Equals is not part of Fluent Assertions. Did you mean Be() instead?"); } } } @@ -385,4 +386,5 @@ internal class ClassWithPropertiesThatAreNotDecoratedWithDummyAttribute protected string ProtectedProperty { get; set; } } + #endregion diff --git a/Tests/FluentAssertions.Specs/Types/PropertyInfoSelectorSpecs.cs b/Tests/FluentAssertions.Specs/Types/PropertyInfoSelectorSpecs.cs index dd612bb0fd..4517255b21 100644 --- a/Tests/FluentAssertions.Specs/Types/PropertyInfoSelectorSpecs.cs +++ b/Tests/FluentAssertions.Specs/Types/PropertyInfoSelectorSpecs.cs @@ -216,7 +216,8 @@ public void When_selecting_methods_that_do_not_return_a_specific_type_it_should_ } [Fact] - public void When_selecting_properties_decorated_with_an_inheritable_attribute_it_should_only_return_the_applicable_properties() + public void + When_selecting_properties_decorated_with_an_inheritable_attribute_it_should_only_return_the_applicable_properties() { // Arrange Type type = typeof(TestClassForPropertySelectorWithInheritableAttributeDerived); @@ -229,20 +230,23 @@ public void When_selecting_properties_decorated_with_an_inheritable_attribute_it } [Fact] - public void When_selecting_properties_decorated_with_or_inheriting_an_inheritable_attribute_it_should_only_return_the_applicable_properties() + public void + When_selecting_properties_decorated_with_or_inheriting_an_inheritable_attribute_it_should_only_return_the_applicable_properties() { // Arrange Type type = typeof(TestClassForPropertySelectorWithInheritableAttributeDerived); // Act - IEnumerable properties = type.Properties().ThatAreDecoratedWithOrInherit().ToArray(); + IEnumerable properties = + type.Properties().ThatAreDecoratedWithOrInherit().ToArray(); // Assert properties.Should().ContainSingle(); } [Fact] - public void When_selecting_properties_not_decorated_with_an_inheritable_attribute_it_should_only_return_the_applicable_properties() + public void + When_selecting_properties_not_decorated_with_an_inheritable_attribute_it_should_only_return_the_applicable_properties() { // Arrange Type type = typeof(TestClassForPropertySelectorWithInheritableAttributeDerived); @@ -255,65 +259,75 @@ public void When_selecting_properties_not_decorated_with_an_inheritable_attribut } [Fact] - public void When_selecting_properties_not_decorated_with_or_inheriting_an_inheritable_attribute_it_should_only_return_the_applicable_properties() + public void + When_selecting_properties_not_decorated_with_or_inheriting_an_inheritable_attribute_it_should_only_return_the_applicable_properties() { // Arrange Type type = typeof(TestClassForPropertySelectorWithInheritableAttributeDerived); // Act - IEnumerable properties = type.Properties().ThatAreNotDecoratedWithOrInherit().ToArray(); + IEnumerable properties = + type.Properties().ThatAreNotDecoratedWithOrInherit().ToArray(); // Assert properties.Should().BeEmpty(); } [Fact] - public void When_selecting_properties_decorated_with_a_noninheritable_attribute_it_should_only_return_the_applicable_properties() + public void + When_selecting_properties_decorated_with_a_noninheritable_attribute_it_should_only_return_the_applicable_properties() { // Arrange Type type = typeof(TestClassForPropertySelectorWithNonInheritableAttributeDerived); // Act - IEnumerable properties = type.Properties().ThatAreDecoratedWith().ToArray(); + IEnumerable properties = + type.Properties().ThatAreDecoratedWith().ToArray(); // Assert properties.Should().BeEmpty(); } [Fact] - public void When_selecting_properties_decorated_with_or_inheriting_a_noninheritable_attribute_it_should_only_return_the_applicable_properties() + public void + When_selecting_properties_decorated_with_or_inheriting_a_noninheritable_attribute_it_should_only_return_the_applicable_properties() { // Arrange Type type = typeof(TestClassForPropertySelectorWithNonInheritableAttributeDerived); // Act - IEnumerable properties = type.Properties().ThatAreDecoratedWithOrInherit().ToArray(); + IEnumerable properties = type.Properties() + .ThatAreDecoratedWithOrInherit().ToArray(); // Assert properties.Should().BeEmpty(); } [Fact] - public void When_selecting_properties_not_decorated_with_a_noninheritable_attribute_it_should_only_return_the_applicable_properties() + public void + When_selecting_properties_not_decorated_with_a_noninheritable_attribute_it_should_only_return_the_applicable_properties() { // Arrange Type type = typeof(TestClassForPropertySelectorWithNonInheritableAttributeDerived); // Act - IEnumerable properties = type.Properties().ThatAreNotDecoratedWith().ToArray(); + IEnumerable properties = + type.Properties().ThatAreNotDecoratedWith().ToArray(); // Assert properties.Should().ContainSingle(); } [Fact] - public void When_selecting_properties_not_decorated_with_or_inheriting_a_noninheritable_attribute_it_should_only_return_the_applicable_properties() + public void + When_selecting_properties_not_decorated_with_or_inheriting_a_noninheritable_attribute_it_should_only_return_the_applicable_properties() { // Arrange Type type = typeof(TestClassForPropertySelectorWithNonInheritableAttributeDerived); // Act - IEnumerable properties = type.Properties().ThatAreNotDecoratedWithOrInherit().ToArray(); + IEnumerable properties = type.Properties() + .ThatAreNotDecoratedWithOrInherit().ToArray(); // Assert properties.Should().ContainSingle(); @@ -332,9 +346,8 @@ public void When_selecting_properties_return_types_it_should_return_the_correct_ returnTypes.Should() .BeEquivalentTo(new[] { - typeof(string), typeof(string), typeof(string), typeof(string) - , typeof(string), typeof(string), typeof(string) - , typeof(string), typeof(int), typeof(int), typeof(int), typeof(int) + typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), + typeof(string), typeof(int), typeof(int), typeof(int), typeof(int) }); } @@ -505,4 +518,5 @@ public DummyPropertyAttribute(string value) public string Value { get; private set; } } + #endregion diff --git a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.Be.cs b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.Be.cs index 04c3659be6..60cf3ad011 100644 --- a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.Be.cs +++ b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.Be.cs @@ -1,6 +1,6 @@ using System; -using FluentAssertions.Primitives; -using FluentAssertions.Types; +using AssemblyA; +using AssemblyB; using Xunit; using Xunit.Sdk; @@ -96,10 +96,10 @@ public void When_type_is_equal_to_same_type_from_different_assembly_it_fails_wit // Arrange #pragma warning disable 436 // disable the warning on conflicting types, as this is the intention for the spec - Type typeFromThisAssembly = typeof(AssemblyB.ClassC); + Type typeFromThisAssembly = typeof(ClassC); Type typeFromOtherAssembly = - new AssemblyA.ClassA().ReturnClassC().GetType(); + new ClassA().ReturnClassC().GetType(); #pragma warning restore 436 @@ -109,7 +109,8 @@ public void When_type_is_equal_to_same_type_from_different_assembly_it_fails_wit // Assert act.Should().Throw() - .WithMessage("Expected type to be [AssemblyB.ClassC, AssemblyB*] *failure message*, but found [AssemblyB.ClassC, FluentAssertions.Specs*]."); + .WithMessage( + "Expected type to be [AssemblyB.ClassC, AssemblyB*] *failure message*, but found [AssemblyB.ClassC, FluentAssertions.Specs*]."); } [Fact] diff --git a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.BeAssignableTo.cs b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.BeAssignableTo.cs index 9b55b7e39b..b5fab5b14d 100644 --- a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.BeAssignableTo.cs +++ b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.BeAssignableTo.cs @@ -126,6 +126,7 @@ public void When_unrelated_to_open_generic_type_it_fails() { // Arrange Type someType = typeof(ClassWithAttribute); + Action act = () => someType.Should().BeAssignableTo(typeof(DummyBaseType<>), "we want to test the failure {0}", "message"); diff --git a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.BeDecoratedWith.cs b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.BeDecoratedWith.cs index 08e84120e3..24788e98e8 100644 --- a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.BeDecoratedWith.cs +++ b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.BeDecoratedWith.cs @@ -81,7 +81,7 @@ public void When_type_is_decorated_with_expected_attribute_with_the_expected_pro // Act Action act = () => typeWithAttribute.Should() - .BeDecoratedWith(a => (a.Name == "Expected") && a.IsEnabled); + .BeDecoratedWith(a => a.Name == "Expected" && a.IsEnabled); // Assert act.Should().NotThrow(); @@ -97,7 +97,7 @@ public void When_type_is_decorated_with_expected_attribute_with_the_expected_pro Action act = () => typeWithAttribute.Should() .BeDecoratedWith(a => a.Name == "Expected") - .Which.IsEnabled.Should().BeTrue(); + .Which.IsEnabled.Should().BeTrue(); // Assert act.Should().NotThrow(); @@ -112,7 +112,7 @@ public void When_type_is_decorated_with_expected_attribute_that_has_an_unexpecte // Act Action act = () => typeWithAttribute.Should() - .BeDecoratedWith(a => (a.Name == "Unexpected") && a.IsEnabled); + .BeDecoratedWith(a => a.Name == "Unexpected" && a.IsEnabled); // Assert act.Should().Throw() @@ -179,7 +179,7 @@ public void When_type_is_not_decorated_with_unexpected_attribute_with_the_expect // Act Action act = () => typeWithoutAttribute.Should() - .NotBeDecoratedWith(a => (a.Name == "Unexpected") && a.IsEnabled); + .NotBeDecoratedWith(a => a.Name == "Unexpected" && a.IsEnabled); // Assert act.Should().NotThrow(); @@ -194,7 +194,7 @@ public void When_type_is_not_decorated_with_expected_attribute_that_has_an_unexp // Act Action act = () => typeWithoutAttribute.Should() - .NotBeDecoratedWith(a => (a.Name == "Expected") && a.IsEnabled); + .NotBeDecoratedWith(a => a.Name == "Expected" && a.IsEnabled); // Assert act.Should().Throw() diff --git a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.BeDecoratedWithOrInherit.cs b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.BeDecoratedWithOrInherit.cs index 99a0a6fa6c..895aa60e64 100644 --- a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.BeDecoratedWithOrInherit.cs +++ b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.BeDecoratedWithOrInherit.cs @@ -81,7 +81,7 @@ public void When_type_inherits_expected_attribute_with_the_expected_properties_i // Act Action act = () => typeWithAttribute.Should() - .BeDecoratedWithOrInherit(a => (a.Name == "Expected") && a.IsEnabled); + .BeDecoratedWithOrInherit(a => a.Name == "Expected" && a.IsEnabled); // Assert act.Should().NotThrow(); @@ -97,7 +97,7 @@ public void When_type_inherits_expected_attribute_with_the_expected_properties_i Action act = () => typeWithAttribute.Should() .BeDecoratedWithOrInherit(a => a.Name == "Expected") - .Which.IsEnabled.Should().BeTrue(); + .Which.IsEnabled.Should().BeTrue(); // Assert act.Should().NotThrow(); @@ -112,7 +112,7 @@ public void When_type_inherits_expected_attribute_that_has_an_unexpected_propert // Act Action act = () => typeWithAttribute.Should() - .BeDecoratedWithOrInherit(a => (a.Name == "Unexpected") && a.IsEnabled); + .BeDecoratedWithOrInherit(a => a.Name == "Unexpected" && a.IsEnabled); // Assert act.Should().Throw() @@ -180,7 +180,7 @@ public void When_type_does_not_inherit_unexpected_attribute_with_the_expected_pr // Act Action act = () => typeWithoutAttribute.Should() - .NotBeDecoratedWithOrInherit(a => (a.Name == "Unexpected") && a.IsEnabled); + .NotBeDecoratedWithOrInherit(a => a.Name == "Unexpected" && a.IsEnabled); // Assert act.Should().NotThrow(); @@ -195,7 +195,7 @@ public void When_type_does_not_inherit_expected_attribute_that_has_an_unexpected // Act Action act = () => typeWithoutAttribute.Should() - .NotBeDecoratedWithOrInherit(a => (a.Name == "Expected") && a.IsEnabled); + .NotBeDecoratedWithOrInherit(a => a.Name == "Expected" && a.IsEnabled); // Assert act.Should().Throw() diff --git a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveConstructor.cs b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveConstructor.cs index 9477fe674f..f02269e598 100644 --- a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveConstructor.cs +++ b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveConstructor.cs @@ -21,9 +21,8 @@ public void When_asserting_a_type_has_a_constructor_which_it_does_it_succeeds() // Act Action act = () => type.Should() - .HaveConstructor(new Type[] { typeof(string) }) - .Which.Should() - .HaveAccessModifier(CSharpAccessModifier.Private); + .HaveConstructor(new[] { typeof(string) }) + .Which.Should().HaveAccessModifier(CSharpAccessModifier.Private); // Assert act.Should().NotThrow(); @@ -88,7 +87,7 @@ public void When_asserting_a_type_does_not_have_a_constructor_which_it_does_not_ // Act Action act = () => type.Should() - .NotHaveConstructor(new Type[] { typeof(string) }); + .NotHaveConstructor(new[] { typeof(string) }); // Assert act.Should().NotThrow(); diff --git a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveDefaultConstructor.cs b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveDefaultConstructor.cs index 7a9dcc6f12..126639b843 100644 --- a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveDefaultConstructor.cs +++ b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveDefaultConstructor.cs @@ -23,7 +23,7 @@ public void When_asserting_a_type_has_a_default_constructor_which_it_does_it_suc type.Should() .HaveDefaultConstructor() .Which.Should() - .HaveAccessModifier(CSharpAccessModifier.ProtectedInternal); + .HaveAccessModifier(CSharpAccessModifier.ProtectedInternal); // Assert act.Should().NotThrow(); @@ -40,7 +40,7 @@ public void When_asserting_a_type_has_a_default_constructor_which_it_does_not_it type.Should() .HaveDefaultConstructor() .Which.Should() - .HaveAccessModifier(CSharpAccessModifier.Public); + .HaveAccessModifier(CSharpAccessModifier.Public); // Assert act.Should().NotThrow(); @@ -54,14 +54,15 @@ public void When_asserting_a_type_has_a_default_constructor_which_it_does_not_an // Act type.Should() - .HaveDefaultConstructor() - .Which.Should() - .HaveAccessModifier(CSharpAccessModifier.Public); + .HaveDefaultConstructor() + .Which.Should() + .HaveAccessModifier(CSharpAccessModifier.Public); + Action act = () => type.Should() .HaveDefaultConstructor() .Which.Should() - .HaveAccessModifier(CSharpAccessModifier.Public); + .HaveAccessModifier(CSharpAccessModifier.Public); // Assert act.Should().NotThrow(); @@ -184,13 +185,10 @@ internal class ClassWithNoMembers internal class ClassWithCctor { - static ClassWithCctor() { } } internal class ClassWithCctorAndNonDefaultConstructor { - static ClassWithCctorAndNonDefaultConstructor() { } - public ClassWithCctorAndNonDefaultConstructor(int _) { } } } diff --git a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveExplicitConversionOperator.cs b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveExplicitConversionOperator.cs index 2303f355e0..5eedb90a94 100644 --- a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveExplicitConversionOperator.cs +++ b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveExplicitConversionOperator.cs @@ -24,7 +24,7 @@ public void When_asserting_a_type_has_an_explicit_conversion_operator_which_it_d type.Should() .HaveExplicitConversionOperator(sourceType, targetType) .Which.Should() - .NotBeNull(); + .NotBeNull(); // Assert act.Should().NotThrow(); @@ -112,7 +112,7 @@ public void When_asserting_a_type_has_an_explicit_conversion_operatorOfT_which_i type.Should() .HaveExplicitConversionOperator() .Which.Should() - .NotBeNull(); + .NotBeNull(); // Assert act.Should().NotThrow(); diff --git a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveExplicitMethod.cs b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveExplicitMethod.cs index 6861b1a8d4..7b3ba3e712 100644 --- a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveExplicitMethod.cs +++ b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveExplicitMethod.cs @@ -29,7 +29,8 @@ public void When_asserting_a_type_explicitly_implements_a_method_which_it_does_i } [Fact] - public void When_asserting_a_type_explicitly_implements_a_method_which_it_implements_implicitly_and_explicitly_it_succeeds() + public void + When_asserting_a_type_explicitly_implements_a_method_which_it_implements_implicitly_and_explicitly_it_succeeds() { // Arrange var type = typeof(ClassExplicitlyImplementingInterface); @@ -288,7 +289,8 @@ public void When_asserting_a_type_does_not_explicitly_implement_a_method_which_i } [Fact] - public void When_asserting_a_type_does_not_explicitly_implement_a_method_which_it_implements_implicitly_and_explicitly_it_fails() + public void + When_asserting_a_type_does_not_explicitly_implement_a_method_which_it_implements_implicitly_and_explicitly_it_fails() { // Arrange var type = typeof(ClassExplicitlyImplementingInterface); diff --git a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveExplicitProperty.cs b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveExplicitProperty.cs index ae3305305f..43e84e67a0 100644 --- a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveExplicitProperty.cs +++ b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveExplicitProperty.cs @@ -29,7 +29,8 @@ public void When_asserting_a_type_explicitly_implements_a_property_which_it_does } [Fact] - public void When_asserting_a_type_explicitly_implements_a_property_which_it_implements_implicitly_and_explicitly_it_succeeds() + public void + When_asserting_a_type_explicitly_implements_a_property_which_it_implements_implicitly_and_explicitly_it_succeeds() { // Arrange var type = typeof(ClassExplicitlyImplementingInterface); @@ -258,7 +259,8 @@ public void When_asserting_a_type_does_not_explicitly_implement_a_property_which } [Fact] - public void When_asserting_a_type_does_not_explicitly_implement_a_property_which_it_implements_implicitly_and_explicitly_it_fails() + public void + When_asserting_a_type_does_not_explicitly_implement_a_property_which_it_implements_implicitly_and_explicitly_it_fails() { // Arrange var type = typeof(ClassExplicitlyImplementingInterface); diff --git a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveImplicitConversionOperator.cs b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveImplicitConversionOperator.cs index 39a8a66571..d5ef12601b 100644 --- a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveImplicitConversionOperator.cs +++ b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveImplicitConversionOperator.cs @@ -24,7 +24,7 @@ public void When_asserting_a_type_has_an_implicit_conversion_operator_which_it_d type.Should() .HaveImplicitConversionOperator(sourceType, targetType) .Which.Should() - .NotBeNull(); + .NotBeNull(); // Assert act.Should().NotThrow(); @@ -112,7 +112,7 @@ public void When_asserting_a_type_has_an_implicit_conversion_operatorOfT_which_i type.Should() .HaveImplicitConversionOperator() .Which.Should() - .NotBeNull(); + .NotBeNull(); // Assert act.Should().NotThrow(); diff --git a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveIndexer.cs b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveIndexer.cs index d689a41472..8e603f7871 100644 --- a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveIndexer.cs +++ b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveIndexer.cs @@ -23,8 +23,8 @@ public void When_asserting_a_type_has_an_indexer_which_it_does_then_it_succeeds( type.Should() .HaveIndexer(typeof(string), new[] { typeof(string) }) .Which.Should() - .BeWritable(CSharpAccessModifier.Internal) - .And.BeReadable(CSharpAccessModifier.Private); + .BeWritable(CSharpAccessModifier.Internal) + .And.BeReadable(CSharpAccessModifier.Private); // Assert act.Should().NotThrow(); diff --git a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveMethod.cs b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveMethod.cs index 70c64d593a..ef6db085ce 100644 --- a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveMethod.cs +++ b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveMethod.cs @@ -23,8 +23,8 @@ public void When_asserting_a_type_has_a_method_which_it_does_it_succeeds() type.Should() .HaveMethod("VoidMethod", new Type[] { }) .Which.Should() - .HaveAccessModifier(CSharpAccessModifier.Private) - .And.ReturnVoid(); + .HaveAccessModifier(CSharpAccessModifier.Private) + .And.ReturnVoid(); // Assert act.Should().NotThrow(); @@ -39,7 +39,7 @@ public void When_asserting_a_type_has_a_method_which_it_does_not_it_fails() // Act Action act = () => type.Should().HaveMethod( - "NonExistentMethod", new[] { typeof(int), typeof(Type) }, "we want to test the failure {0}", "message"); + "NonExistentMethod", new[] { typeof(int), typeof(Type) }, "we want to test the failure {0}", "message"); // Assert act.Should().Throw() diff --git a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveProperty.cs b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveProperty.cs index fa7c2c4075..fe7f4cbb6a 100644 --- a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveProperty.cs +++ b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveProperty.cs @@ -23,8 +23,8 @@ public void When_asserting_a_type_has_a_property_which_it_does_then_it_succeeds( type.Should() .HaveProperty(typeof(string), "PrivateWriteProtectedReadProperty") .Which.Should() - .BeWritable(CSharpAccessModifier.Private) - .And.BeReadable(CSharpAccessModifier.Protected); + .BeWritable(CSharpAccessModifier.Private) + .And.BeReadable(CSharpAccessModifier.Protected); // Assert act.Should().NotThrow(); @@ -137,8 +137,8 @@ public void When_asserting_a_type_has_a_propertyOfT_which_it_does_then_it_succee type.Should() .HaveProperty("PrivateWriteProtectedReadProperty") .Which.Should() - .BeWritable(CSharpAccessModifier.Private) - .And.BeReadable(CSharpAccessModifier.Protected); + .BeWritable(CSharpAccessModifier.Private) + .And.BeReadable(CSharpAccessModifier.Protected); // Assert act.Should().NotThrow(); diff --git a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.cs index ab7d6c249c..fdc767d3f7 100644 --- a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.cs @@ -29,7 +29,7 @@ public class OtherClassWithoutAttribute { } - [AttributeUsage(AttributeTargets.Class, Inherited = true)] + [AttributeUsage(AttributeTargets.Class)] public class DummyClassAttribute : Attribute { public string Name { get; } @@ -132,15 +132,25 @@ public interface IExplicitInterface void ExplicitImplicitMethod(string overload); } - public class ClassWithoutMembers { } + public class ClassWithoutMembers + { + } - public interface IPublicInterface { } + public interface IPublicInterface + { + } - internal interface IInternalInterface { } + internal interface IInternalInterface + { + } - internal class InternalClass { } + internal class InternalClass + { + } - internal struct InternalStruct { } + internal struct InternalStruct + { + } internal enum InternalEnum { @@ -150,15 +160,23 @@ internal enum InternalEnum internal class Nested { - private class PrivateClass { } + private class PrivateClass + { + } protected enum ProtectedEnum { } - public interface IPublicInterface { } + public interface IPublicInterface + { + } - internal class InternalClass { } + internal class InternalClass + { + } - protected internal interface IProtectedInternalInterface { } + protected internal interface IProtectedInternalInterface + { + } } internal readonly struct TypeWithConversionOperators @@ -170,24 +188,38 @@ private TypeWithConversionOperators(int value) this.value = value; } - public static implicit operator int(TypeWithConversionOperators typeWithConversionOperators) => typeWithConversionOperators.value; + public static implicit operator int(TypeWithConversionOperators typeWithConversionOperators) => + typeWithConversionOperators.value; - public static explicit operator byte(TypeWithConversionOperators typeWithConversionOperators) => (byte)typeWithConversionOperators.value; + public static explicit operator byte(TypeWithConversionOperators typeWithConversionOperators) => + (byte)typeWithConversionOperators.value; } - internal sealed class Sealed { } + internal sealed class Sealed + { + } - internal abstract class Abstract { } + internal abstract class Abstract + { + } - internal static class Static { } + internal static class Static + { + } - internal struct Struct { } + internal struct Struct + { + } public delegate void ExampleDelegate(); - internal class ClassNotInDummyNamespace { } + internal class ClassNotInDummyNamespace + { + } - internal class OtherClassNotInDummyNamespace { } + internal class OtherClassNotInDummyNamespace + { + } #endregion } @@ -211,17 +243,23 @@ internal class ClassC namespace DummyNamespace { - internal class ClassInDummyNamespace { } + internal class ClassInDummyNamespace + { + } namespace InnerDummyNamespace { - internal class ClassInInnerDummyNamespace { } + internal class ClassInInnerDummyNamespace + { + } } } namespace DummyNamespaceTwo { - internal class ClassInDummyNamespaceTwo { } + internal class ClassInDummyNamespaceTwo + { + } } #endregion diff --git a/Tests/FluentAssertions.Specs/Types/TypeExtensionsSpecs.cs b/Tests/FluentAssertions.Specs/Types/TypeExtensionsSpecs.cs index bb95403d3d..70a08c66cd 100644 --- a/Tests/FluentAssertions.Specs/Types/TypeExtensionsSpecs.cs +++ b/Tests/FluentAssertions.Specs/Types/TypeExtensionsSpecs.cs @@ -2,6 +2,8 @@ using System.Collections.Immutable; using System.Linq; using System.Reflection; +using System.Runtime.CompilerServices; +using System.Text; using FluentAssertions.Common; using Xunit; @@ -164,16 +166,21 @@ public void When_checking_if_class_with_multiple_equality_methods_is_record_it_s private static MethodInfo GetFakeConversionOperator(Type type, string name, BindingFlags bindingAttr, Type returnType) { MethodInfo[] methods = type.GetMethods(bindingAttr); + return methods.SingleOrDefault(m => m.Name == name && m.ReturnType == returnType && m.GetParameters().Select(p => p.ParameterType).SequenceEqual(new[] { type }) - ); + ); } - private class InheritedType { } + private class InheritedType + { + } - private class InheritingType : InheritedType { } + private class InheritingType : InheritedType + { + } private readonly struct TypeWithFakeConversionOperators { @@ -185,9 +192,11 @@ private TypeWithFakeConversionOperators(int value) } #pragma warning disable IDE1006, SA1300 // These two functions mimic the compiler generated conversion operators - public static int op_Implicit(TypeWithFakeConversionOperators typeWithFakeConversionOperators) => typeWithFakeConversionOperators.value; + public static int op_Implicit(TypeWithFakeConversionOperators typeWithFakeConversionOperators) => + typeWithFakeConversionOperators.value; - public static byte op_Explicit(TypeWithFakeConversionOperators typeWithFakeConversionOperators) => (byte)typeWithFakeConversionOperators.value; + public static byte op_Explicit(TypeWithFakeConversionOperators typeWithFakeConversionOperators) => + (byte)typeWithFakeConversionOperators.value; #pragma warning restore SA1300, IDE1006 } @@ -197,6 +206,7 @@ private record struct MyRecordStruct(int Value); private record struct MyRecordStructWithCustomPrintMembers(int Value) { + // ReSharper disable once RedundantNameQualifier private bool PrintMembers(System.Text.StringBuilder builder) { builder.Append(Value); @@ -228,31 +238,37 @@ private struct MyStructWithFakeCompilerGeneratedEquality : IEquatable Value; - [System.Runtime.CompilerServices.CompilerGenerated] - public static bool operator ==(MyStructWithFakeCompilerGeneratedEquality left, MyStructWithFakeCompilerGeneratedEquality right) => left.Equals(right); + [CompilerGenerated] + public static bool operator ==(MyStructWithFakeCompilerGeneratedEquality left, + MyStructWithFakeCompilerGeneratedEquality right) => left.Equals(right); - public static bool operator !=(MyStructWithFakeCompilerGeneratedEquality left, MyStructWithFakeCompilerGeneratedEquality right) => !left.Equals(right); + public static bool operator !=(MyStructWithFakeCompilerGeneratedEquality left, + MyStructWithFakeCompilerGeneratedEquality right) => !left.Equals(right); } // Note that this struct is mistakenly detected as a record struct by the current version of TypeExtensions.IsRecord. // This cannot be avoided at present, unless something is changed at language level, // or a smarter way to check for record structs is found. - private struct MyStructWithFakeCompilerGeneratedEqualityAndPrintMembers : IEquatable + private struct MyStructWithFakeCompilerGeneratedEqualityAndPrintMembers + : IEquatable { public int Value { get; set; } public bool Equals(MyStructWithFakeCompilerGeneratedEqualityAndPrintMembers other) => Value == other.Value; - public override bool Equals(object obj) => obj is MyStructWithFakeCompilerGeneratedEqualityAndPrintMembers other && Equals(other); + public override bool Equals(object obj) => + obj is MyStructWithFakeCompilerGeneratedEqualityAndPrintMembers other && Equals(other); public override int GetHashCode() => Value; - [System.Runtime.CompilerServices.CompilerGenerated] - public static bool operator ==(MyStructWithFakeCompilerGeneratedEqualityAndPrintMembers left, MyStructWithFakeCompilerGeneratedEqualityAndPrintMembers right) => left.Equals(right); + [CompilerGenerated] + public static bool operator ==(MyStructWithFakeCompilerGeneratedEqualityAndPrintMembers left, + MyStructWithFakeCompilerGeneratedEqualityAndPrintMembers right) => left.Equals(right); - public static bool operator !=(MyStructWithFakeCompilerGeneratedEqualityAndPrintMembers left, MyStructWithFakeCompilerGeneratedEqualityAndPrintMembers right) => !left.Equals(right); + public static bool operator !=(MyStructWithFakeCompilerGeneratedEqualityAndPrintMembers left, + MyStructWithFakeCompilerGeneratedEqualityAndPrintMembers right) => !left.Equals(right); - private bool PrintMembers(System.Text.StringBuilder builder) + private bool PrintMembers(StringBuilder builder) { builder.Append(Value); return true; @@ -269,9 +285,11 @@ private struct MyStructWithOverriddenEquality : IEquatable Value; - public static bool operator ==(MyStructWithOverriddenEquality left, MyStructWithOverriddenEquality right) => left.Equals(right); + public static bool operator ==(MyStructWithOverriddenEquality left, MyStructWithOverriddenEquality right) => + left.Equals(right); - public static bool operator !=(MyStructWithOverriddenEquality left, MyStructWithOverriddenEquality right) => !left.Equals(right); + public static bool operator !=(MyStructWithOverriddenEquality left, MyStructWithOverriddenEquality right) => + !left.Equals(right); } private class MyClass diff --git a/Tests/FluentAssertions.Specs/Types/TypeSelectorAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Types/TypeSelectorAssertionSpecs.cs index 15c6720f5d..786565a4ec 100644 --- a/Tests/FluentAssertions.Specs/Types/TypeSelectorAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Types/TypeSelectorAssertionSpecs.cs @@ -151,7 +151,7 @@ public void When_asserting_a_selection_of_types_with_unexpected_attribute_proper Action act = () => types.Should() .BeDecoratedWith( - a => (a.Name == "Expected") && a.IsEnabled, "we want to test the failure {0}", "message"); + a => a.Name == "Expected" && a.IsEnabled, "we want to test the failure {0}", "message"); // Assert act.Should().Throw() @@ -220,7 +220,8 @@ public void When_injecting_a_null_predicate_into_TypeSelector_BeDecoratedWithOrI } [Fact] - public void When_asserting_a_selection_of_types_with_some_inheriting_attributes_with_unexpected_attribute_property_it_fails() + public void + When_asserting_a_selection_of_types_with_some_inheriting_attributes_with_unexpected_attribute_property_it_fails() { // Arrange var types = new TypeSelector(new[] @@ -235,7 +236,7 @@ public void When_asserting_a_selection_of_types_with_some_inheriting_attributes_ Action act = () => types.Should() .BeDecoratedWithOrInherit( - a => (a.Name == "Expected") && a.IsEnabled, "we want to test the failure {0}", "message"); + a => a.Name == "Expected" && a.IsEnabled, "we want to test the failure {0}", "message"); // Assert act.Should().Throw() @@ -316,7 +317,7 @@ public void When_asserting_a_selection_of_types_with_unexpected_attribute_and_un Action act = () => types.Should() .NotBeDecoratedWith( - a => (a.Name == "Expected") && a.IsEnabled, "we want to test the failure {0}", "message"); + a => a.Name == "Expected" && a.IsEnabled, "we want to test the failure {0}", "message"); // Assert act.Should().Throw() @@ -377,7 +378,7 @@ public void When_a_selection_of_types_do_inherit_unexpected_attribute_with_the_e // Act Action act = () => types.Should() .NotBeDecoratedWithOrInherit( - a => (a.Name == "Expected") && a.IsEnabled, "we want to test the failure {0}", "message"); + a => a.Name == "Expected" && a.IsEnabled, "we want to test the failure {0}", "message"); // Assert act.Should().Throw() @@ -395,7 +396,7 @@ public void When_a_selection_of_types_do_not_inherit_unexpected_attribute_with_t // Act Action act = () => types.Should() - .NotBeDecoratedWithOrInherit(a => (a.Name == "Expected") && a.IsEnabled); + .NotBeDecoratedWithOrInherit(a => a.Name == "Expected" && a.IsEnabled); // Assert act.Should().NotThrow(); @@ -642,7 +643,7 @@ public void When_a_type_only_shares_a_prefix_with_the_expected_namespace_it_shou // Assert act.Should().Throw() - .WithMessage("Expected the namespaces of all types to start with \"DummyNamespace\" *failure message*" + + .WithMessage("Expected the namespaces of all types to start with \"DummyNamespace\" *failure message*" + ", but the namespaces of the following types do not start with it:*\"*.ClassInDummyNamespaceTwo\"."); } @@ -805,7 +806,9 @@ public void When_accidentally_using_equals_it_should_throw_a_helpful_error() Action action = () => types.Should().Equals(types); // Assert - action.Should().Throw().WithMessage("Equals is not part of Fluent Assertions. Did you mean BeInNamespace() or BeDecoratedWith() instead?"); + action.Should().Throw() + .WithMessage( + "Equals is not part of Fluent Assertions. Did you mean BeInNamespace() or BeDecoratedWith() instead?"); } } } diff --git a/Tests/FluentAssertions.Specs/Types/TypeSelectorSpecs.cs b/Tests/FluentAssertions.Specs/Types/TypeSelectorSpecs.cs index 0d0d76e485..ff2687f66c 100644 --- a/Tests/FluentAssertions.Specs/Types/TypeSelectorSpecs.cs +++ b/Tests/FluentAssertions.Specs/Types/TypeSelectorSpecs.cs @@ -15,7 +15,6 @@ using Internal.UnwrapSelectorTestTypes.Test; using Internal.ValueTypesAndNotValueTypes.Test; using Xunit; -using ISomeInterface = Internal.Main.Test.ISomeInterface; namespace FluentAssertions.Specs.Types { @@ -281,7 +280,7 @@ public void When_using_the_single_type_ctor_of_TypeSelector_it_should_contain_th .ToArray() .Should() .ContainSingle() - .Which.Should().Be(type); + .Which.Should().Be(type); } [Fact] @@ -298,7 +297,8 @@ public void When_selecting_types_decorated_with_an_inheritable_attribute_it_shou } [Fact] - public void When_selecting_types_decorated_with_or_inheriting_an_inheritable_attribute_it_should_only_return_the_applicable_types() + public void + When_selecting_types_decorated_with_or_inheriting_an_inheritable_attribute_it_should_only_return_the_applicable_types() { // Arrange Type type = typeof(ClassWithSomeAttributeDerived); @@ -324,7 +324,8 @@ public void When_selecting_types_not_decorated_with_an_inheritable_attribute_it_ } [Fact] - public void When_selecting_types_not_decorated_with_or_inheriting_an_inheritable_attribute_it_should_only_return_the_applicable_types() + public void + When_selecting_types_not_decorated_with_or_inheriting_an_inheritable_attribute_it_should_only_return_the_applicable_types() { // Arrange Type type = typeof(ClassWithSomeAttributeDerived); @@ -350,7 +351,8 @@ public void When_selecting_types_decorated_with_a_noninheritable_attribute_it_sh } [Fact] - public void When_selecting_types_decorated_with_or_inheriting_a_noninheritable_attribute_it_should_only_return_the_applicable_types() + public void + When_selecting_types_decorated_with_or_inheriting_a_noninheritable_attribute_it_should_only_return_the_applicable_types() { // Arrange Type type = typeof(ClassWithSomeNonInheritableAttributeDerived); @@ -363,7 +365,8 @@ public void When_selecting_types_decorated_with_or_inheriting_a_noninheritable_a } [Fact] - public void When_selecting_types_not_decorated_with_a_noninheritable_attribute_it_should_only_return_the_applicable_types() + public void + When_selecting_types_not_decorated_with_a_noninheritable_attribute_it_should_only_return_the_applicable_types() { // Arrange Type type = typeof(ClassWithSomeNonInheritableAttributeDerived); @@ -376,7 +379,8 @@ public void When_selecting_types_not_decorated_with_a_noninheritable_attribute_i } [Fact] - public void When_selecting_types_not_decorated_with_or_inheriting_a_noninheritable_attribute_it_should_only_return_the_applicable_types() + public void + When_selecting_types_not_decorated_with_or_inheriting_a_noninheritable_attribute_it_should_only_return_the_applicable_types() { // Arrange Type type = typeof(ClassWithSomeNonInheritableAttributeDerived); @@ -470,7 +474,10 @@ public void When_deselecting_a_prefix_of_a_namespace_it_should_not_match() public void When_selecting_types_that_are_classes_it_should_return_the_correct_types() { // Arrange - TypeSelector types = new[] { typeof(NotOnlyClassesClass), typeof(NotOnlyClassesEnumeration), typeof(INotOnlyClassesInterface) }.Types(); + TypeSelector types = new[] + { + typeof(NotOnlyClassesClass), typeof(NotOnlyClassesEnumeration), typeof(INotOnlyClassesInterface) + }.Types(); // Act IEnumerable filteredTypes = types.ThatAreClasses(); @@ -744,7 +751,7 @@ internal class ClassImplementingSomeInterface : ISomeInterface { } - [AttributeUsage(AttributeTargets.Class, Inherited = true)] + [AttributeUsage(AttributeTargets.Class)] internal class SomeAttribute : Attribute { } @@ -939,7 +946,9 @@ internal interface InternalInterfaceNotValueType } #pragma warning disable RCS1110 // Declare type inside namespace. -internal class ClassInGlobalNamespace { } +internal class ClassInGlobalNamespace +{ +} #pragma warning restore RCS1110 #endregion diff --git a/Tests/FluentAssertions.Specs/UIFactsDefinition.cs b/Tests/FluentAssertions.Specs/UIFactsDefinition.cs index 128b685be3..26d6621799 100644 --- a/Tests/FluentAssertions.Specs/UIFactsDefinition.cs +++ b/Tests/FluentAssertions.Specs/UIFactsDefinition.cs @@ -4,4 +4,6 @@ namespace FluentAssertions.Specs; // Try to stabilize UIFact tests [CollectionDefinition("UIFacts", DisableParallelization = true)] -public class UIFactsDefinition { } +public class UIFactsDefinition +{ +} diff --git a/Tests/FluentAssertions.Specs/Xml/XAttributeAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Xml/XAttributeAssertionSpecs.cs index b31a653910..407d4f8c0f 100644 --- a/Tests/FluentAssertions.Specs/Xml/XAttributeAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Xml/XAttributeAssertionSpecs.cs @@ -25,7 +25,8 @@ public void When_asserting_an_xml_attribute_is_equal_to_the_same_xml_attribute_i } [Fact] - public void When_asserting_an_xml_attribute_is_equal_to_a_different_xml_attribute_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_attribute_is_equal_to_a_different_xml_attribute_it_should_fail_with_descriptive_message() { // Arrange var theAttribute = new XAttribute("name", "value"); @@ -69,7 +70,7 @@ public void When_the_expected_attribute_is_null_then_it_fails() [Fact] public void When_the_attribute_is_expected_to_equal_null_it_fails() { - XAttribute theAttribute = new XAttribute("name", "value"); + XAttribute theAttribute = new("name", "value"); // Act Action act = () => theAttribute.Should().Be(null, "we want to test the failure {0}", "message"); @@ -114,7 +115,8 @@ public void When_asserting_an_xml_attribute_is_not_equal_to_the_same_xml_attribu } [Fact] - public void When_asserting_an_xml_attribute_is_not_equal_to_the_same_xml_attribute_it_should_throw_with_descriptive_message() + public void + When_asserting_an_xml_attribute_is_not_equal_to_the_same_xml_attribute_it_should_throw_with_descriptive_message() { // Arrange var theAttribute = new XAttribute("name", "value"); @@ -146,7 +148,7 @@ public void When_a_null_attribute_is_not_supposed_to_be_an_attribute_it_succeeds public void When_an_attribute_is_not_supposed_to_be_null_it_succeeds() { // Arrange - XAttribute theAttribute = new XAttribute("name", "value"); + XAttribute theAttribute = new("name", "value"); // Act Action act = () => theAttribute.Should().NotBe(null); @@ -296,7 +298,8 @@ public void When_asserting_attribute_has_a_specific_value_but_it_has_a_different } [Fact] - public void When_asserting_attribute_has_a_specific_value_but_it_has_a_different_value_it_should_throw_with_descriptive_message() + public void + When_asserting_attribute_has_a_specific_value_but_it_has_a_different_value_it_should_throw_with_descriptive_message() { // Arrange var theAttribute = new XAttribute("age", "36"); diff --git a/Tests/FluentAssertions.Specs/Xml/XAttributeFormatterSpecs.cs b/Tests/FluentAssertions.Specs/Xml/XAttributeFormatterSpecs.cs index 5ec0a84e5e..65358a9caf 100644 --- a/Tests/FluentAssertions.Specs/Xml/XAttributeFormatterSpecs.cs +++ b/Tests/FluentAssertions.Specs/Xml/XAttributeFormatterSpecs.cs @@ -1,5 +1,4 @@ using System.Xml.Linq; - using FluentAssertions.Formatting; using Xunit; diff --git a/Tests/FluentAssertions.Specs/Xml/XDocumentAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Xml/XDocumentAssertionSpecs.cs index f03f392f8b..35ef93c747 100644 --- a/Tests/FluentAssertions.Specs/Xml/XDocumentAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Xml/XDocumentAssertionSpecs.cs @@ -73,7 +73,7 @@ public void When_both_subject_and_expected_documents_are_null_it_succeeds() public void When_a_document_is_expected_to_equal_null_it_fails() { // Arrange - XDocument theDocument = new XDocument(); + XDocument theDocument = new(); // Act Action act = () => theDocument.Should().Be(null, "we want to test the failure {0}", "message"); @@ -150,7 +150,7 @@ public void When_a_null_document_is_not_supposed_to_be_a_document_it_succeeds() public void When_a_document_is_not_supposed_to_be_null_it_succeeds() { // Arrange - XDocument theDocument = new XDocument(); + XDocument theDocument = new(); // Act Action act = () => theDocument.Should().NotBe(null); @@ -208,7 +208,8 @@ public void When_asserting_a_xml_document_is_equivalent_to_the_same_xml_document } [Fact] - public void When_asserting_a_xml_selfclosing_document_is_equivalent_to_a_different_xml_document_with_same_structure_it_should_succeed() + public void + When_asserting_a_xml_selfclosing_document_is_equivalent_to_a_different_xml_document_with_same_structure_it_should_succeed() { // Arrange var document = XDocument.Parse(""); @@ -223,7 +224,8 @@ public void When_asserting_a_xml_selfclosing_document_is_equivalent_to_a_differe } [Fact] - public void When_asserting_a_xml_document_is_equivalent_to_a_different_xml_document_with_same_structure_it_should_succeed() + public void + When_asserting_a_xml_document_is_equivalent_to_a_different_xml_document_with_same_structure_it_should_succeed() { // Arrange var document = XDocument.Parse(""); @@ -270,7 +272,8 @@ public void When_asserting_a_xml_document_is_equivalent_to_a_different_xml_docum } [Fact] - public void When_asserting_a_xml_document_with_selfclosing_child_is_equivalent_to_a_different_xml_document_with_subchild_child_it_should_fail() + public void + When_asserting_a_xml_document_with_selfclosing_child_is_equivalent_to_a_different_xml_document_with_subchild_child_it_should_fail() { // Arrange var theDocument = XDocument.Parse(""); @@ -286,7 +289,8 @@ public void When_asserting_a_xml_document_with_selfclosing_child_is_equivalent_t } [Fact] - public void When_asserting_a_xml_document_is_equivalent_to_a_different_xml_document_elements_missing_it_should_fail_with_descriptive_message() + public void + When_asserting_a_xml_document_is_equivalent_to_a_different_xml_document_elements_missing_it_should_fail_with_descriptive_message() { // Arrange var theDocument = XDocument.Parse(""); @@ -303,7 +307,8 @@ public void When_asserting_a_xml_document_is_equivalent_to_a_different_xml_docum } [Fact] - public void When_asserting_a_xml_document_is_equivalent_to_a_different_xml_document_with_extra_elements_it_should_fail_with_descriptive_message() + public void + When_asserting_a_xml_document_is_equivalent_to_a_different_xml_document_with_extra_elements_it_should_fail_with_descriptive_message() { // Arrange var theDocument = XDocument.Parse(""); @@ -365,7 +370,8 @@ public void When_a_document_is_equivalent_to_null_it_fails() } [Fact] - public void When_assertion_an_xml_document_is_equivalent_to_a_different_xml_document_with_different_namespace_prefix_it_should_succeed() + public void + When_assertion_an_xml_document_is_equivalent_to_a_different_xml_document_with_different_namespace_prefix_it_should_succeed() { // Arrange var subject = XDocument.Parse(""); @@ -380,7 +386,8 @@ public void When_assertion_an_xml_document_is_equivalent_to_a_different_xml_docu } [Fact] - public void When_asserting_an_xml_document_is_equivalent_to_a_different_xml_document_which_differs_only_on_unused_namespace_declaration_it_should_succeed() + public void + When_asserting_an_xml_document_is_equivalent_to_a_different_xml_document_which_differs_only_on_unused_namespace_declaration_it_should_succeed() { // Arrange var subject = XDocument.Parse(""); @@ -395,7 +402,8 @@ public void When_asserting_an_xml_document_is_equivalent_to_a_different_xml_docu } [Fact] - public void When_asserting_an_xml_document_is_equivalent_to_different_xml_document_which_lacks_attributes_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_document_is_equivalent_to_different_xml_document_which_lacks_attributes_it_should_fail_with_descriptive_message() { // Arrange var theDocument = XDocument.Parse(""); @@ -411,7 +419,8 @@ public void When_asserting_an_xml_document_is_equivalent_to_different_xml_docume } [Fact] - public void When_asserting_an_xml_document_is_equivalent_to_different_xml_document_which_has_extra_attributes_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_document_is_equivalent_to_different_xml_document_which_has_extra_attributes_it_should_fail_with_descriptive_message() { // Arrange var theDocument = XDocument.Parse(""); @@ -427,7 +436,8 @@ public void When_asserting_an_xml_document_is_equivalent_to_different_xml_docume } [Fact] - public void When_asserting_an_xml_document_is_equivalent_to_different_xml_document_which_has_different_attribute_values_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_document_is_equivalent_to_different_xml_document_which_has_different_attribute_values_it_should_fail_with_descriptive_message() { // Arrange var theDocument = XDocument.Parse(""); @@ -443,7 +453,8 @@ public void When_asserting_an_xml_document_is_equivalent_to_different_xml_docume } [Fact] - public void When_asserting_an_xml_document_is_equivalent_to_different_xml_document_which_has_attribute_with_different_namespace_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_document_is_equivalent_to_different_xml_document_which_has_attribute_with_different_namespace_it_should_fail_with_descriptive_message() { // Arrange var theDocument = XDocument.Parse(""); @@ -459,7 +470,8 @@ public void When_asserting_an_xml_document_is_equivalent_to_different_xml_docume } [Fact] - public void When_asserting_an_xml_document_is_equivalent_to_different_xml_document_which_has_different_text_contents_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_document_is_equivalent_to_different_xml_document_which_has_different_text_contents_it_should_fail_with_descriptive_message() { // Arrange var theDocument = XDocument.Parse(""); @@ -475,7 +487,8 @@ public void When_asserting_an_xml_document_is_equivalent_to_different_xml_docume } [Fact] - public void When_asserting_an_xml_document_is_equivalent_to_different_xml_document_with_different_comments_it_should_succeed() + public void + When_asserting_an_xml_document_is_equivalent_to_different_xml_document_with_different_comments_it_should_succeed() { // Arrange var subject = XDocument.Parse("a"); @@ -489,7 +502,8 @@ public void When_asserting_an_xml_document_is_equivalent_to_different_xml_docume } [Fact] - public void When_asserting_equivalence_of_an_xml_document_but_has_different_attribute_value_it_should_fail_with_xpath_to_difference() + public void + When_asserting_equivalence_of_an_xml_document_but_has_different_attribute_value_it_should_fail_with_xpath_to_difference() { // Arrange XDocument actual = XDocument.Parse(""); @@ -503,11 +517,13 @@ public void When_asserting_equivalence_of_an_xml_document_but_has_different_attr } [Fact] - public void When_asserting_equivalence_of_document_with_repeating_element_names_but_differs_it_should_fail_with_index_xpath_to_difference() + public void + When_asserting_equivalence_of_document_with_repeating_element_names_but_differs_it_should_fail_with_index_xpath_to_difference() { // Arrange XDocument actual = XDocument.Parse( ""); + XDocument expected = XDocument.Parse( ""); @@ -519,11 +535,13 @@ public void When_asserting_equivalence_of_document_with_repeating_element_names_ } [Fact] - public void When_asserting_equivalence_of_document_with_repeating_element_names_on_different_levels_but_differs_it_should_fail_with_index_xpath_to_difference() + public void + When_asserting_equivalence_of_document_with_repeating_element_names_on_different_levels_but_differs_it_should_fail_with_index_xpath_to_difference() { // Arrange XDocument actual = XDocument.Parse( ""); + XDocument expected = XDocument.Parse( ""); @@ -535,11 +553,13 @@ public void When_asserting_equivalence_of_document_with_repeating_element_names_ } [Fact] - public void When_asserting_equivalence_of_document_with_repeating_element_names_with_different_parents_but_differs_it_should_fail_with_index_xpath_to_difference() + public void + When_asserting_equivalence_of_document_with_repeating_element_names_with_different_parents_but_differs_it_should_fail_with_index_xpath_to_difference() { // Arrange XDocument actual = XDocument.Parse( ""); + XDocument expected = XDocument.Parse( ""); @@ -554,7 +574,8 @@ public void When_asserting_equivalence_of_document_with_repeating_element_names_ public class NotBeEquivalentTo { [Fact] - public void When_asserting_a_xml_document_is_not_equivalent_to_a_different_xml_document_with_elements_missing_it_should_succeed() + public void + When_asserting_a_xml_document_is_not_equivalent_to_a_different_xml_document_with_elements_missing_it_should_succeed() { // Arrange var document = XDocument.Parse(""); @@ -569,7 +590,8 @@ public void When_asserting_a_xml_document_is_not_equivalent_to_a_different_xml_d } [Fact] - public void When_asserting_a_xml_document_is_not_equivalent_to_a_different_xml_document_with_extra_elements_it_should_succeed() + public void + When_asserting_a_xml_document_is_not_equivalent_to_a_different_xml_document_with_extra_elements_it_should_succeed() { // Arrange var document = XDocument.Parse(""); @@ -584,7 +606,8 @@ public void When_asserting_a_xml_document_is_not_equivalent_to_a_different_xml_d } [Fact] - public void When_asserting_a_xml_document_is_not_equivalent_to_a_different_xml_document_with_same_structure_it_should_fail() + public void + When_asserting_a_xml_document_is_not_equivalent_to_a_different_xml_document_with_same_structure_it_should_fail() { // Arrange var theDocument = XDocument.Parse(""); @@ -616,7 +639,8 @@ public void When_asserting_a_xml_document_is_not_equivalent_to_the_same_xml_docu } [Fact] - public void When_asserting_a_xml_document_is_not_equivalent_to_a_different_xml_document_with_same_structure_it_should_fail_with_descriptive_message() + public void + When_asserting_a_xml_document_is_not_equivalent_to_a_different_xml_document_with_same_structure_it_should_fail_with_descriptive_message() { // Arrange var theDocument = XDocument.Parse(""); @@ -632,7 +656,8 @@ public void When_asserting_a_xml_document_is_not_equivalent_to_a_different_xml_d } [Fact] - public void When_asserting_a_xml_document_is_not_equivalent_to_a_different_xml_document_with_same_contents_but_different_ns_prefixes_it_should_fail() + public void + When_asserting_a_xml_document_is_not_equivalent_to_a_different_xml_document_with_same_contents_but_different_ns_prefixes_it_should_fail() { // Arrange var theDocument = XDocument.Parse(@""); @@ -648,7 +673,8 @@ public void When_asserting_a_xml_document_is_not_equivalent_to_a_different_xml_d } [Fact] - public void When_asserting_a_xml_document_is_not_equivalent_to_a_different_xml_document_with_same_contents_but_extra_unused_xmlns_declaration_it_should_fail() + public void + When_asserting_a_xml_document_is_not_equivalent_to_a_different_xml_document_with_same_contents_but_extra_unused_xmlns_declaration_it_should_fail() { // Arrange var theDocument = XDocument.Parse(@""); @@ -664,7 +690,8 @@ public void When_asserting_a_xml_document_is_not_equivalent_to_a_different_xml_d } [Fact] - public void When_asserting_a_xml_document_is_not_equivalent_to_the_same_xml_document_it_should_fail_with_descriptive_message() + public void + When_asserting_a_xml_document_is_not_equivalent_to_the_same_xml_document_it_should_fail_with_descriptive_message() { // Arrange var theDocument = XDocument.Parse(""); @@ -860,8 +887,8 @@ public void When_asserting_document_has_root_element_but_it_does_not_it_should_f // Assert string expectedMessage = "Expected theDocument to have root element \"unknown\"" + - " because we want to test the failure message" + - $", but found {Formatter.ToString(theDocument)}."; + " because we want to test the failure message" + + $", but found {Formatter.ToString(theDocument)}."; act.Should().Throw().WithMessage(expectedMessage); } @@ -967,7 +994,7 @@ public void When_asserting_document_has_root_element_with_ns_but_it_does_not_it_ string expectedMessage = "Expected theDocument to have root element \"{http://www.example.com/2012/test}unknown\"" + " because we want to test the failure message" + - $", but found {Formatter.ToString(theDocument)}."; + $", but found {Formatter.ToString(theDocument)}."; act.Should().Throw().WithMessage(expectedMessage); } @@ -1065,7 +1092,8 @@ public void When_asserting_document_has_root_with_child_element_with_ns_but_it_d } [Fact] - public void When_asserting_document_has_root_with_child_element_with_ns_but_it_does_not_it_should_fail_with_descriptive_message() + public void + When_asserting_document_has_root_with_child_element_with_ns_but_it_does_not_it_should_fail_with_descriptive_message() { // Arrange var theDocument = XDocument.Parse( @@ -1085,7 +1113,8 @@ public void When_asserting_document_has_root_with_child_element_with_ns_but_it_d } [Fact] - public void When_asserting_document_has_root_with_child_element_with_attributes_it_should_be_possible_to_use_which_to_assert_on_the_element() + public void + When_asserting_document_has_root_with_child_element_with_attributes_it_should_be_possible_to_use_which_to_assert_on_the_element() { // Arrange var document = XDocument.Parse( @@ -1201,7 +1230,8 @@ public void Asserting_document_null_inside_an_assertion_scope_it_checks_the_whol } [Fact] - public void Asserting_with_document_root_null_inside_an_assertion_scope_it_checks_the_whole_assertion_scope_before_failing() + public void + Asserting_with_document_root_null_inside_an_assertion_scope_it_checks_the_whole_assertion_scope_before_failing() { // Arrange XDocument document = new(); @@ -1236,7 +1266,8 @@ public void When_asserting_document_has_two_child_elements_but_it_does_have_thre // Assert act.Should().Throw() - .WithMessage("Expected document to have a root element containing a child \"child\"*exactly*2 times, but found it 3 times*"); + .WithMessage( + "Expected document to have a root element containing a child \"child\"*exactly*2 times, but found it 3 times*"); } [Fact] @@ -1298,7 +1329,7 @@ public void Chaining_after_a_non_successful_occurrence_check_does_not_continue_t { // Arrange var document = XDocument.Parse( - @" + @" @@ -1310,7 +1341,8 @@ public void Chaining_after_a_non_successful_occurrence_check_does_not_continue_t // Assert act.Should().Throw() - .WithMessage("Expected document to have a root element containing a child \"child\"*exactly*1 time, but found it 3 times."); + .WithMessage( + "Expected document to have a root element containing a child \"child\"*exactly*1 time, but found it 3 times."); } [Fact] diff --git a/Tests/FluentAssertions.Specs/Xml/XDocumentFormatterSpecs.cs b/Tests/FluentAssertions.Specs/Xml/XDocumentFormatterSpecs.cs index 70fac2c429..508dccd5da 100644 --- a/Tests/FluentAssertions.Specs/Xml/XDocumentFormatterSpecs.cs +++ b/Tests/FluentAssertions.Specs/Xml/XDocumentFormatterSpecs.cs @@ -1,5 +1,4 @@ using System.Xml.Linq; - using FluentAssertions.Formatting; using Xunit; diff --git a/Tests/FluentAssertions.Specs/Xml/XElementAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Xml/XElementAssertionSpecs.cs index 47f174b46a..fe9b955251 100644 --- a/Tests/FluentAssertions.Specs/Xml/XElementAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Xml/XElementAssertionSpecs.cs @@ -49,6 +49,7 @@ public void When_asserting_an_xml_element_is_equal_to_an_xml_element_with_a_deep new XElement("parent", new XElement("child", new XElement("grandChild2"))); + var expected = new XElement("parent", new XElement("child", @@ -81,7 +82,7 @@ public void When_the_expected_element_is_null_it_fails() public void When_element_is_expected_to_equal_null_it_fails() { // Arrange - XElement theElement = new XElement("element"); + XElement theElement = new("element"); // Act Action act = () => theElement.Should().Be(null, "we want to test the failure {0}", "message"); @@ -130,6 +131,7 @@ public void When_asserting_a_deep_xml_element_is_not_equal_to_a_different_xml_el new XElement("parent", new XElement("child", new XElement("grandChild"))); + var element = new XElement("parent", new XElement("child", @@ -162,7 +164,7 @@ public void When_asserting_an_xml_element_is_not_equal_to_the_same_xml_element_i public void When_an_element_is_not_supposed_to_be_null_it_succeeds() { // Arrange - XElement theElement = new XElement("element"); + XElement theElement = new("element"); // Act Action act = () => theElement.Should().NotBe(null); @@ -387,7 +389,8 @@ public void When_asserting_a_xml_element_is_equivalent_to_a_different_xml_elemen } [Fact] - public void When_asserting_a_xml_element_is_equivalent_to_a_different_xml_element_elements_missing_it_should_fail_with_descriptive_message() + public void + When_asserting_a_xml_element_is_equivalent_to_a_different_xml_element_elements_missing_it_should_fail_with_descriptive_message() { // Arrange var theElement = XElement.Parse(""); @@ -403,7 +406,8 @@ public void When_asserting_a_xml_element_is_equivalent_to_a_different_xml_elemen } [Fact] - public void When_asserting_a_xml_element_is_equivalent_to_a_different_xml_element_with_extra_elements_it_should_fail_with_descriptive_message() + public void + When_asserting_a_xml_element_is_equivalent_to_a_different_xml_element_with_extra_elements_it_should_fail_with_descriptive_message() { // Arrange var theElement = XElement.Parse(""); @@ -419,7 +423,8 @@ public void When_asserting_a_xml_element_is_equivalent_to_a_different_xml_elemen } [Fact] - public void When_asserting_an_empty_xml_element_is_equivalent_to_a_different_xml_element_with_text_content_it_should_fail() + public void + When_asserting_an_empty_xml_element_is_equivalent_to_a_different_xml_element_with_text_content_it_should_fail() { // Arrange var theElement = XElement.Parse(""); @@ -463,7 +468,7 @@ public void When_an_element_is_null_then_be_equivalent_to_an_element_fails() [Fact] public void When_an_element_is_equivalent_to_null_it_fails() { - XElement theElement = new XElement("element"); + XElement theElement = new("element"); // Act Action act = () => @@ -476,7 +481,7 @@ public void When_an_element_is_equivalent_to_null_it_fails() [Fact] public void - When_asserting_an_xml_element_is_equivalent_to_a_different_xml_element_with_different_namespace_prefix_it_should_succeed() + When_asserting_an_xml_element_is_equivalent_to_a_different_xml_element_with_different_namespace_prefix_it_should_succeed() { // Arrange var subject = XElement.Parse(""); @@ -491,7 +496,8 @@ public void } [Fact] - public void When_asserting_an_xml_element_is_equivalent_to_a_different_xml_element_which_differs_only_on_unused_namespace_declaration_it_should_succeed() + public void + When_asserting_an_xml_element_is_equivalent_to_a_different_xml_element_which_differs_only_on_unused_namespace_declaration_it_should_succeed() { // Arrange var subject = XElement.Parse(""); @@ -506,7 +512,8 @@ public void When_asserting_an_xml_element_is_equivalent_to_a_different_xml_eleme } [Fact] - public void When_asserting_an_xml_element_is_equivalent_to_different_xml_element_which_lacks_attributes_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_element_is_equivalent_to_different_xml_element_which_lacks_attributes_it_should_fail_with_descriptive_message() { // Arrange var theElement = XElement.Parse(""); @@ -522,7 +529,8 @@ public void When_asserting_an_xml_element_is_equivalent_to_different_xml_element } [Fact] - public void When_asserting_an_xml_element_is_equivalent_to_different_xml_element_which_has_extra_attributes_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_element_is_equivalent_to_different_xml_element_which_has_extra_attributes_it_should_fail_with_descriptive_message() { // Arrange var theElement = XElement.Parse(""); @@ -555,7 +563,8 @@ public void } [Fact] - public void When_asserting_an_xml_element_is_equivalent_to_different_xml_element_which_has_attribute_with_different_namespace_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_element_is_equivalent_to_different_xml_element_which_has_attribute_with_different_namespace_it_should_fail_with_descriptive_message() { // Arrange var theElement = XElement.Parse(""); @@ -571,7 +580,8 @@ public void When_asserting_an_xml_element_is_equivalent_to_different_xml_element } [Fact] - public void When_asserting_an_xml_element_is_equivalent_to_different_xml_element_which_has_different_text_contents_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_element_is_equivalent_to_different_xml_element_which_has_different_text_contents_it_should_fail_with_descriptive_message() { // Arrange var theElement = XElement.Parse(""); @@ -587,7 +597,8 @@ public void When_asserting_an_xml_element_is_equivalent_to_different_xml_element } [Fact] - public void When_asserting_an_xml_element_is_equivalent_to_different_xml_element_with_different_comments_it_should_succeed() + public void + When_asserting_an_xml_element_is_equivalent_to_different_xml_element_with_different_comments_it_should_succeed() { // Arrange var subject = XElement.Parse("a"); @@ -604,7 +615,8 @@ public void When_asserting_an_xml_element_is_equivalent_to_different_xml_element public class NotBeEquivalentTo { [Fact] - public void When_asserting_a_xml_element_is_not_equivalent_to_a_different_xml_element_with_elements_missing_it_should_succeed() + public void + When_asserting_a_xml_element_is_not_equivalent_to_a_different_xml_element_with_elements_missing_it_should_succeed() { // Arrange var element = XElement.Parse(""); @@ -619,7 +631,8 @@ public void When_asserting_a_xml_element_is_not_equivalent_to_a_different_xml_el } [Fact] - public void When_asserting_a_xml_element_is_not_equivalent_to_a_different_xml_element_with_extra_elements_it_should_succeed() + public void + When_asserting_a_xml_element_is_not_equivalent_to_a_different_xml_element_with_extra_elements_it_should_succeed() { // Arrange var element = XElement.Parse(""); @@ -650,7 +663,8 @@ public void When_asserting_a_xml_element_is_not_equivalent_to_a_different_xml_el } [Fact] - public void When_asserting_a_xml_element_is_not_equivalent_to_a_different_xml_element_with_same_contents_but_different_ns_prefixes_it_should_fail() + public void + When_asserting_a_xml_element_is_not_equivalent_to_a_different_xml_element_with_same_contents_but_different_ns_prefixes_it_should_fail() { // Arrange var theElement = XElement.Parse(@""); @@ -666,7 +680,8 @@ public void When_asserting_a_xml_element_is_not_equivalent_to_a_different_xml_el } [Fact] - public void When_asserting_a_xml_element_is_not_equivalent_to_a_different_xml_element_with_same_contents_but_extra_unused_xmlns_declaration_it_should_fail() + public void + When_asserting_a_xml_element_is_not_equivalent_to_a_different_xml_element_with_same_contents_but_extra_unused_xmlns_declaration_it_should_fail() { // Arrange var theElement = XElement.Parse(@""); @@ -698,7 +713,8 @@ public void When_asserting_a_xml_element_is_not_equivalent_to_the_same_xml_eleme } [Fact] - public void When_asserting_a_xml_element_is_not_equivalent_to_a_different_xml_element_with_same_structure_it_should_fail_with_descriptive_message() + public void + When_asserting_a_xml_element_is_not_equivalent_to_a_different_xml_element_with_same_structure_it_should_fail_with_descriptive_message() { // Arrange var theElement = XElement.Parse(""); @@ -714,7 +730,8 @@ public void When_asserting_a_xml_element_is_not_equivalent_to_a_different_xml_el } [Fact] - public void When_asserting_a_xml_element_is_not_equivalent_to_the_same_xml_element_it_should_fail_with_descriptive_message() + public void + When_asserting_a_xml_element_is_not_equivalent_to_the_same_xml_element_it_should_fail_with_descriptive_message() { // Arrange var theElement = XElement.Parse(""); @@ -757,7 +774,7 @@ public void When_a_null_element_is_not_equivalent_to_an_element_it_succeeds() [Fact] public void When_an_element_is_not_equivalent_to_null_it_succeeds() { - XElement theElement = new XElement("element"); + XElement theElement = new("element"); // Act Action act = () => theElement.Should().NotBeEquivalentTo(null); @@ -799,7 +816,8 @@ public void When_asserting_element_has_a_specific_value_but_it_has_a_different_v } [Fact] - public void When_asserting_element_has_a_specific_value_but_it_has_a_different_value_it_should_throw_with_descriptive_message() + public void + When_asserting_element_has_a_specific_value_but_it_has_a_different_value_it_should_throw_with_descriptive_message() { // Arrange var theElement = XElement.Parse(""); @@ -890,7 +908,8 @@ public void When_asserting_element_has_attribute_with_ns_and_specific_value_but_ } [Fact] - public void When_asserting_element_has_attribute_with_specific_value_but_attribute_does_not_exist_it_should_fail_with_descriptive_message() + public void + When_asserting_element_has_attribute_with_specific_value_but_attribute_does_not_exist_it_should_fail_with_descriptive_message() { // Arrange var theElement = XElement.Parse(@"grega"); @@ -906,7 +925,8 @@ public void When_asserting_element_has_attribute_with_specific_value_but_attribu } [Fact] - public void When_asserting_element_has_attribute_with_ns_and_specific_value_but_attribute_does_not_exist_it_should_fail_with_descriptive_message() + public void + When_asserting_element_has_attribute_with_ns_and_specific_value_but_attribute_does_not_exist_it_should_fail_with_descriptive_message() { // Arrange var theElement = XElement.Parse(@""); @@ -939,7 +959,8 @@ public void When_asserting_element_has_attribute_with_specific_value_but_attribu } [Fact] - public void When_asserting_element_has_attribute_with_ns_and_specific_value_but_attribute_has_different_value_it_should_fail() + public void + When_asserting_element_has_attribute_with_ns_and_specific_value_but_attribute_has_different_value_it_should_fail() { // Arrange var theElement = XElement.Parse(@""); @@ -954,7 +975,8 @@ public void When_asserting_element_has_attribute_with_ns_and_specific_value_but_ } [Fact] - public void When_asserting_element_has_attribute_with_specific_value_but_attribute_has_different_value_it_should_fail_with_descriptive_message() + public void + When_asserting_element_has_attribute_with_specific_value_but_attribute_has_different_value_it_should_fail_with_descriptive_message() { // Arrange var theElement = XElement.Parse(@""); @@ -970,14 +992,15 @@ public void When_asserting_element_has_attribute_with_specific_value_but_attribu } [Fact] - public void When_asserting_element_has_attribute_with_ns_and_specific_value_but_attribute_has_different_value_it_should_fail_with_descriptive_message() + public void + When_asserting_element_has_attribute_with_ns_and_specific_value_but_attribute_has_different_value_it_should_fail_with_descriptive_message() { // Arrange var theElement = XElement.Parse(@""); // Act Action act = () => - theElement.Should().HaveAttribute(XName.Get("name", "http://www.example.com/2012/test"), "dennis", + theElement.Should().HaveAttribute(XName.Get("name", "http://www.example.com/2012/test"), "dennis", "because we want to test the failure {0}", "message"); // Assert @@ -1021,7 +1044,7 @@ public void When_xml_element_is_null_then_have_attribute_with_XName_should_fail( [Fact] public void When_asserting_element_has_an_attribute_with_a_null_name_it_should_throw() { - XElement theElement = new XElement("element"); + XElement theElement = new("element"); // Act Action act = () => @@ -1035,7 +1058,7 @@ public void When_asserting_element_has_an_attribute_with_a_null_name_it_should_t [Fact] public void When_asserting_element_has_an_attribute_with_a_null_XName_it_should_throw() { - XElement theElement = new XElement("element"); + XElement theElement = new("element"); // Act Action act = () => @@ -1049,7 +1072,7 @@ public void When_asserting_element_has_an_attribute_with_a_null_XName_it_should_ [Fact] public void When_asserting_element_has_an_attribute_with_an_empty_name_it_should_throw() { - XElement theElement = new XElement("element"); + XElement theElement = new("element"); // Act Action act = () => @@ -1187,13 +1210,14 @@ public void When_asserting_element_has_child_element_it_should_return_the_matche // Assert matchedElement.Should().BeOfType() .And.HaveAttribute("attr", "1"); + matchedElement.Name.Should().Be(XName.Get("child")); } [Fact] public void When_asserting_element_has_a_child_element_with_a_null_name_it_should_throw() { - XElement theElement = new XElement("element"); + XElement theElement = new("element"); // Act Action act = () => @@ -1207,7 +1231,7 @@ public void When_asserting_element_has_a_child_element_with_a_null_name_it_shoul [Fact] public void When_asserting_element_has_a_child_element_with_a_null_XName_it_should_throw() { - XElement theElement = new XElement("element"); + XElement theElement = new("element"); // Act Action act = () => @@ -1221,7 +1245,7 @@ public void When_asserting_element_has_a_child_element_with_a_null_XName_it_shou [Fact] public void When_asserting_element_has_a_child_element_with_an_empty_name_it_should_throw() { - XElement theElement = new XElement("element"); + XElement theElement = new("element"); // Act Action act = () => diff --git a/Tests/FluentAssertions.Specs/Xml/XElementFormatterSpecs.cs b/Tests/FluentAssertions.Specs/Xml/XElementFormatterSpecs.cs index 78f2f5fb71..5542a49200 100644 --- a/Tests/FluentAssertions.Specs/Xml/XElementFormatterSpecs.cs +++ b/Tests/FluentAssertions.Specs/Xml/XElementFormatterSpecs.cs @@ -1,5 +1,4 @@ using System.Xml.Linq; - using FluentAssertions.Formatting; using Xunit; diff --git a/Tests/FluentAssertions.Specs/Xml/XmlElementAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Xml/XmlElementAssertionSpecs.cs index 28e01fca6f..b5b09c78fb 100644 --- a/Tests/FluentAssertions.Specs/Xml/XmlElementAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Xml/XmlElementAssertionSpecs.cs @@ -136,8 +136,8 @@ public void // Assert act.Should().Throw() .WithMessage("Expected theElement to have attribute \"age\" with value \"36\"" + - " because we want to test the failure message" + - ", but found no such attribute in () .WithMessage("Expected attribute \"name\" in theElement to have value \"dennis\"" + - " because we want to test the failure message" + - ", but found \"martin\"."); + " because we want to test the failure message" + + ", but found \"martin\"."); } } @@ -198,7 +198,7 @@ public void When_asserting_xml_element_has_attribute_with_ns_and_specific_value_ [Fact] public void - When_asserting_xml_element_has_attribute_with_ns_and_specific_value_but_attribute_does_not_exist_it_should_fail() + When_asserting_xml_element_has_attribute_with_ns_and_specific_value_but_attribute_does_not_exist_it_should_fail() { // Arrange var xmlDoc = new XmlDocument(); @@ -215,7 +215,7 @@ public void [Fact] public void - When_asserting_xml_element_has_attribute_with_ns_and_specific_value_but_attribute_does_not_exist_it_should_fail_with_descriptive_message() + When_asserting_xml_element_has_attribute_with_ns_and_specific_value_but_attribute_does_not_exist_it_should_fail_with_descriptive_message() { // Arrange var document = new XmlDocument(); @@ -237,7 +237,7 @@ public void [Fact] public void - When_asserting_xml_element_has_attribute_with_ns_and_specific_value_but_attribute_has_different_value_it_should_fail() + When_asserting_xml_element_has_attribute_with_ns_and_specific_value_but_attribute_has_different_value_it_should_fail() { // Arrange var xmlDoc = new XmlDocument(); @@ -254,7 +254,7 @@ public void [Fact] public void - When_asserting_xml_element_has_attribute_with_ns_and_specific_value_but_attribute_has_different_value_it_should_fail_with_descriptive_message() + When_asserting_xml_element_has_attribute_with_ns_and_specific_value_but_attribute_has_different_value_it_should_fail_with_descriptive_message() { // Arrange var document = new XmlDocument(); @@ -282,10 +282,12 @@ public void When_asserting_xml_element_has_child_element_and_it_does_it_should_s { // Arrange var xml = new XmlDocument(); + xml.LoadXml( @""); + var element = xml.DocumentElement; // Act @@ -301,10 +303,12 @@ public void When_asserting_xml_element_has_child_element_but_it_does_not_it_shou { // Arrange var xmlDoc = new XmlDocument(); + xmlDoc.LoadXml( @""); + var element = xmlDoc.DocumentElement; // Act @@ -320,10 +324,12 @@ public void When_asserting_xml_element_has_child_element_but_it_does_not_it_shou { // Arrange var document = new XmlDocument(); + document.LoadXml( @""); + var theElement = document.DocumentElement; // Act @@ -342,10 +348,12 @@ public void When_asserting_xml_element_has_child_element_it_should_return_the_ma { // Arrange var xmlDoc = new XmlDocument(); + xmlDoc.LoadXml( @""); + var element = xmlDoc.DocumentElement; // Act @@ -354,6 +362,7 @@ public void When_asserting_xml_element_has_child_element_it_should_return_the_ma // Assert matchedElement.Should().BeOfType () .And.HaveAttribute("attr", "1"); + matchedElement.Name.Should().Be("child"); } @@ -362,10 +371,12 @@ public void When_asserting_xml_element_with_ns_has_child_element_and_it_does_it_ { // Arrange var xmlDoc = new XmlDocument(); + xmlDoc.LoadXml( @""); + var element = xmlDoc.DocumentElement; // Act @@ -381,10 +392,12 @@ public void When_asserting_xml_element_has_child_element_and_it_does_with_ns_it_ { // Arrange var xmlDoc = new XmlDocument(); + xmlDoc.LoadXml( @""); + var element = xmlDoc.DocumentElement; // Act @@ -403,10 +416,12 @@ public void When_asserting_xml_element_has_child_element_with_ns_and_it_does_it_ { // Arrange var xmlDoc = new XmlDocument(); + xmlDoc.LoadXml( @""); + var element = xmlDoc.DocumentElement; // Act @@ -422,10 +437,12 @@ public void When_asserting_xml_element_has_child_element_with_ns_but_it_does_not { // Arrange var xmlDoc = new XmlDocument(); + xmlDoc.LoadXml( @""); + var element = xmlDoc.DocumentElement; // Act @@ -441,10 +458,12 @@ public void When_asserting_xml_element_has_child_element_with_ns_but_it_does_not { // Arrange var document = new XmlDocument(); + document.LoadXml( @""); + var theElement = document.DocumentElement; // Act diff --git a/Tests/FluentAssertions.Specs/Xml/XmlNodeAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Xml/XmlNodeAssertionSpecs.cs index b3ccca797d..02e0281718 100644 --- a/Tests/FluentAssertions.Specs/Xml/XmlNodeAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Xml/XmlNodeAssertionSpecs.cs @@ -43,7 +43,8 @@ public void When_asserting_an_xml_node_is_same_as_a_different_xml_node_it_should } [Fact] - public void When_asserting_an_xml_node_is_same_as_a_different_xml_node_it_should_fail_with_descriptive_message_and_truncate_xml() + public void + When_asserting_an_xml_node_is_same_as_a_different_xml_node_it_should_fail_with_descriptive_message_and_truncate_xml() { // Arrange var theDocument = new XmlDocument(); @@ -123,7 +124,7 @@ public void When_asserting_an_xml_node_is_null_but_it_is_not_it_should_fail_with // Assert act.Should().Throw value value () .WithMessage("Expected theDocument to be because we want to test the failure message," + - " but found ."); + " but found ."); } } @@ -191,7 +192,8 @@ public void When_asserting_an_xml_node_is_equivalent_to_the_same_xml_node_it_sho } [Fact] - public void When_asserting_an_xml_node_is_equivalent_to_a_different_xml_node_with_other_contents_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_node_is_equivalent_to_a_different_xml_node_with_other_contents_it_should_fail_with_descriptive_message() { // Arrange var theDocument = new XmlDocument(); @@ -229,7 +231,8 @@ public void When_asserting_an_xml_node_is_equivalent_to_a_different_xml_node_wit } [Fact] - public void When_assertion_an_xml_node_is_equivalent_to_a_different_xml_node_with_different_namespace_prefix_it_should_succeed() + public void + When_assertion_an_xml_node_is_equivalent_to_a_different_xml_node_with_different_namespace_prefix_it_should_succeed() { // Arrange var subject = new XmlDocument(); @@ -246,7 +249,8 @@ public void When_assertion_an_xml_node_is_equivalent_to_a_different_xml_node_wit } [Fact] - public void When_asserting_an_xml_node_is_equivalent_to_a_different_xml_node_which_differs_only_on_unused_namespace_declaration_it_should_succeed() + public void + When_asserting_an_xml_node_is_equivalent_to_a_different_xml_node_which_differs_only_on_unused_namespace_declaration_it_should_succeed() { // Arrange var subject = new XmlDocument(); @@ -263,7 +267,8 @@ public void When_asserting_an_xml_node_is_equivalent_to_a_different_xml_node_whi } [Fact] - public void When_asserting_an_xml_node_is_equivalent_to_a_different_XmlDocument_which_differs_on_a_child_element_name_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_node_is_equivalent_to_a_different_XmlDocument_which_differs_on_a_child_element_name_it_should_fail_with_descriptive_message() { // Arrange var theDocument = new XmlDocument(); @@ -282,7 +287,8 @@ public void When_asserting_an_xml_node_is_equivalent_to_a_different_XmlDocument_ } [Fact] - public void When_asserting_an_xml_node_is_equivalent_to_a_different_xml_node_which_differs_on_a_child_element_namespace_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_node_is_equivalent_to_a_different_xml_node_which_differs_on_a_child_element_namespace_it_should_fail_with_descriptive_message() { // Arrange var theDocument = new XmlDocument(); @@ -301,7 +307,8 @@ public void When_asserting_an_xml_node_is_equivalent_to_a_different_xml_node_whi } [Fact] - public void When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which_contains_an_unexpected_node_type_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which_contains_an_unexpected_node_type_it_should_fail_with_descriptive_message() { // Arrange var theDocument = new XmlDocument(); @@ -320,7 +327,8 @@ public void When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which } [Fact] - public void When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which_contains_extra_elements_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which_contains_extra_elements_it_should_fail_with_descriptive_message() { // Arrange var theDocument = new XmlDocument(); @@ -339,7 +347,8 @@ public void When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which } [Fact] - public void When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which_lacks_elements_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which_lacks_elements_it_should_fail_with_descriptive_message() { // Arrange var theDocument = new XmlDocument(); @@ -358,7 +367,8 @@ public void When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which } [Fact] - public void When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which_lacks_attributes_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which_lacks_attributes_it_should_fail_with_descriptive_message() { // Arrange var theDocument = new XmlDocument(); @@ -377,7 +387,8 @@ public void When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which } [Fact] - public void When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which_has_extra_attributes_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which_has_extra_attributes_it_should_fail_with_descriptive_message() { // Arrange var theDocument = new XmlDocument(); @@ -396,7 +407,8 @@ public void When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which } [Fact] - public void When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which_has_different_attribute_values_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which_has_different_attribute_values_it_should_fail_with_descriptive_message() { // Arrange var theDocument = new XmlDocument(); @@ -415,7 +427,8 @@ public void When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which } [Fact] - public void When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which_has_attribute_with_different_namespace_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which_has_attribute_with_different_namespace_it_should_fail_with_descriptive_message() { // Arrange var theDocument = new XmlDocument(); @@ -434,7 +447,8 @@ public void When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which } [Fact] - public void When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which_has_different_text_contents_it_should_fail_with_descriptive_message() + public void + When_asserting_an_xml_node_is_equivalent_to_different_xml_node_which_has_different_text_contents_it_should_fail_with_descriptive_message() { // Arrange var theDocument = new XmlDocument(); @@ -469,12 +483,16 @@ public void When_asserting_an_xml_node_is_equivalent_to_different_xml_node_with_ } [Fact] - public void When_asserting_an_xml_node_is_equivalent_to_different_xml_node_with_different_insignificant_whitespace_it_should_succeed() + public void + When_asserting_an_xml_node_is_equivalent_to_different_xml_node_with_different_insignificant_whitespace_it_should_succeed() { // Arrange - var subject = new XmlDocument() { PreserveWhitespace = true }; + var subject = new XmlDocument { PreserveWhitespace = true }; + subject.LoadXml(""); - var expected = new XmlDocument() { PreserveWhitespace = true }; + + var expected = new XmlDocument { PreserveWhitespace = true }; + expected.LoadXml("\n \n \r\n"); // Act @@ -485,7 +503,8 @@ public void When_asserting_an_xml_node_is_equivalent_to_different_xml_node_with_ } [Fact] - public void When_asserting_an_xml_node_is_equivalent_that_contains_an_unsupported_node_it_should_throw_a_descriptive_message() + public void + When_asserting_an_xml_node_is_equivalent_that_contains_an_unsupported_node_it_should_throw_a_descriptive_message() { // Arrange var theDocument = new XmlDocument(); diff --git a/Tests/FluentAssertions.Specs/Xml/XmlNodeFormatterSpecs.cs b/Tests/FluentAssertions.Specs/Xml/XmlNodeFormatterSpecs.cs index 604460afa1..ef83197743 100644 --- a/Tests/FluentAssertions.Specs/Xml/XmlNodeFormatterSpecs.cs +++ b/Tests/FluentAssertions.Specs/Xml/XmlNodeFormatterSpecs.cs @@ -1,6 +1,5 @@ using System; using System.Xml; - using FluentAssertions.Formatting; using Xunit; From c6b13e29e5c03d2a49a0e9e67da98ae7f79bd407 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Mon, 20 Feb 2023 15:14:35 +0100 Subject: [PATCH 06/98] BenchmarkDotNet 0.13.3 -> 0.13.5 --- Tests/Benchmarks/Benchmarks.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Benchmarks/Benchmarks.csproj b/Tests/Benchmarks/Benchmarks.csproj index 9f0c088bf2..4fa5d5cf7d 100644 --- a/Tests/Benchmarks/Benchmarks.csproj +++ b/Tests/Benchmarks/Benchmarks.csproj @@ -9,7 +9,7 @@ From a9dde6f7a59ab8a659e467aaf8af3a2a787b82cb Mon Sep 17 00:00:00 2001 From: Jonas Nyrup - + Date: Mon, 20 Feb 2023 15:15:06 +0100 Subject: [PATCH 07/98] PolySharp 1.8.1 -> 1.12.1 --- Src/FluentAssertions/FluentAssertions.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/FluentAssertions/FluentAssertions.csproj b/Src/FluentAssertions/FluentAssertions.csproj index 817254eadd..96b819ba1d 100644 --- a/Src/FluentAssertions/FluentAssertions.csproj +++ b/Src/FluentAssertions/FluentAssertions.csproj @@ -55,7 +55,7 @@ From a26fe6aeb9c119c50f399d16b24c94582cbe73b7 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup - + From 6149f08ed42c159242fb38a00c810d25e82fbf7c Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Mon, 20 Feb 2023 15:15:36 +0100 Subject: [PATCH 08/98] Microsoft.CodeAnalysis.BannedApiAnalyzers 3.3.3 -> 3.3.4 --- Src/FluentAssertions/FluentAssertions.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/FluentAssertions/FluentAssertions.csproj b/Src/FluentAssertions/FluentAssertions.csproj index 96b819ba1d..844940a78a 100644 --- a/Src/FluentAssertions/FluentAssertions.csproj +++ b/Src/FluentAssertions/FluentAssertions.csproj @@ -101,7 +101,7 @@ - + From 912052116c37b3855278bd2603237400842d7a33 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup allruntime; build; native; contentfiles; analyzers; buildtransitive Date: Mon, 20 Feb 2023 15:16:18 +0100 Subject: [PATCH 09/98] Verify.Xunit 19.5.0 -> 19.10.0 --- Tests/Approval.Tests/Approval.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Approval.Tests/Approval.Tests.csproj b/Tests/Approval.Tests/Approval.Tests.csproj index 7d1f0a9fbc..c51f788c4f 100644 --- a/Tests/Approval.Tests/Approval.Tests.csproj +++ b/Tests/Approval.Tests/Approval.Tests.csproj @@ -13,7 +13,7 @@ - + Date: Mon, 20 Feb 2023 15:16:31 +0100 Subject: [PATCH 10/98] Verify.DiffPlex 2.0.1 -> 2.2.0 --- Tests/Approval.Tests/Approval.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Approval.Tests/Approval.Tests.csproj b/Tests/Approval.Tests/Approval.Tests.csproj index c51f788c4f..bbb37353fd 100644 --- a/Tests/Approval.Tests/Approval.Tests.csproj +++ b/Tests/Approval.Tests/Approval.Tests.csproj @@ -12,7 +12,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + From d086e68fe51d4022c4add7f4245a5abe3ee238e6 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Mon, 20 Feb 2023 15:16:59 +0100 Subject: [PATCH 11/98] GitVersion.Tool 5.11.1 -> 5.12.0 --- Build/_build.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Build/_build.csproj b/Build/_build.csproj index a205e9f1d6..0a4cd21f61 100644 --- a/Build/_build.csproj +++ b/Build/_build.csproj @@ -17,7 +17,7 @@ OS_MAC - + From 16aff4a7f86c17ec086dab691e24fec9582892a4 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Mon, 20 Feb 2023 15:18:15 +0100 Subject: [PATCH 12/98] ReportGenerator 5.1.13 -> 5.1.17 --- Build/_build.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Build/_build.csproj b/Build/_build.csproj index 0a4cd21f61..0b15c7a026 100644 --- a/Build/_build.csproj +++ b/Build/_build.csproj @@ -19,7 +19,7 @@ diff --git a/Tests/TestFrameworks/NUnit3.Specs/NUnit3.Specs.csproj b/Tests/TestFrameworks/NUnit3.Specs/NUnit3.Specs.csproj index 566e1da8ca..29d74d3189 100644 --- a/Tests/TestFrameworks/NUnit3.Specs/NUnit3.Specs.csproj +++ b/Tests/TestFrameworks/NUnit3.Specs/NUnit3.Specs.csproj @@ -12,7 +12,7 @@ - - + From 8d2fcc7f86c92e218b06febef2be7f36a1e1e2b4 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Thu, 23 Feb 2023 21:00:31 +0100 Subject: [PATCH 13/98] Microsoft.NET.Test.Sdk 17.4.1 -> 17.5.0 --- Tests/Approval.Tests/Approval.Tests.csproj | 2 +- .../FluentAssertions.Equivalency.Specs.csproj | 2 +- Tests/FluentAssertions.Specs/FluentAssertions.Specs.csproj | 2 +- Tests/TestFrameworks/MSTestV2.Specs/MSTestV2.Specs.csproj | 2 +- Tests/TestFrameworks/MSpec.Specs/MSpec.Specs.csproj | 2 +- Tests/TestFrameworks/NUnit3.Specs/NUnit3.Specs.csproj | 2 +- Tests/TestFrameworks/XUnit2.Specs/XUnit2.Specs.csproj | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Tests/Approval.Tests/Approval.Tests.csproj b/Tests/Approval.Tests/Approval.Tests.csproj index bbb37353fd..073a816bd1 100644 --- a/Tests/Approval.Tests/Approval.Tests.csproj +++ b/Tests/Approval.Tests/Approval.Tests.csproj @@ -5,7 +5,7 @@ diff --git a/Tests/TestFrameworks/MSpec.Specs/MSpec.Specs.csproj b/Tests/TestFrameworks/MSpec.Specs/MSpec.Specs.csproj index 004991b0a6..7973403022 100644 --- a/Tests/TestFrameworks/MSpec.Specs/MSpec.Specs.csproj +++ b/Tests/TestFrameworks/MSpec.Specs/MSpec.Specs.csproj @@ -12,7 +12,7 @@ - - + diff --git a/Tests/FluentAssertions.Equivalency.Specs/FluentAssertions.Equivalency.Specs.csproj b/Tests/FluentAssertions.Equivalency.Specs/FluentAssertions.Equivalency.Specs.csproj index 97014c927c..84b8d40c22 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/FluentAssertions.Equivalency.Specs.csproj +++ b/Tests/FluentAssertions.Equivalency.Specs/FluentAssertions.Equivalency.Specs.csproj @@ -48,7 +48,7 @@ all - + diff --git a/Tests/FluentAssertions.Specs/FluentAssertions.Specs.csproj b/Tests/FluentAssertions.Specs/FluentAssertions.Specs.csproj index 2fd4edf822..65810cb194 100644 --- a/Tests/FluentAssertions.Specs/FluentAssertions.Specs.csproj +++ b/Tests/FluentAssertions.Specs/FluentAssertions.Specs.csproj @@ -52,7 +52,7 @@ allruntime; build; native; contentfiles; analyzers - + diff --git a/Tests/TestFrameworks/MSTestV2.Specs/MSTestV2.Specs.csproj b/Tests/TestFrameworks/MSTestV2.Specs/MSTestV2.Specs.csproj index 4ee13e9d4f..756fd1136c 100644 --- a/Tests/TestFrameworks/MSTestV2.Specs/MSTestV2.Specs.csproj +++ b/Tests/TestFrameworks/MSTestV2.Specs/MSTestV2.Specs.csproj @@ -12,7 +12,7 @@ - allruntime; build; native; contentfiles; analyzers runtime; build; native; contentfiles; analyzers; buildtransitive + runtime; build; native; contentfiles; analyzers; buildtransitive + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/Tests/TestFrameworks/XUnit2.Specs/XUnit2.Specs.csproj b/Tests/TestFrameworks/XUnit2.Specs/XUnit2.Specs.csproj index d53b701026..f3c9165b2f 100644 --- a/Tests/TestFrameworks/XUnit2.Specs/XUnit2.Specs.csproj +++ b/Tests/TestFrameworks/XUnit2.Specs/XUnit2.Specs.csproj @@ -12,7 +12,7 @@ - all runtime; build; native; contentfiles; analyzers; buildtransitive + From f045e6d9f4ea93d01a5f55626eeeb8a5349b2ba7 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup all Date: Mon, 20 Feb 2023 15:54:50 +0100 Subject: [PATCH 14/98] Change styling to please both VS and Rider --- .editorconfig | 1 + Build/Build.cs | 2 +- Src/FluentAssertions/Primitives/StringAssertions.cs | 6 +++--- Tests/Benchmarks/CheckIfMemberIsBrowsable.cs | 5 ++--- .../CollectionSpecs.cs | 13 +++++++++---- .../FluentAssertions.Equivalency.Specs/EnumSpecs.cs | 3 +-- .../Collections/GenericDictionaryAssertionSpecs.cs | 3 ++- .../Extensions/ObjectExtensionsSpecs.cs | 6 ++++-- 8 files changed, 23 insertions(+), 16 deletions(-) diff --git a/.editorconfig b/.editorconfig index 1dfa065e14..38c686df03 100644 --- a/.editorconfig +++ b/.editorconfig @@ -116,6 +116,7 @@ csharp_space_before_comma = false csharp_space_before_dot = false csharp_space_before_open_square_brackets = false csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_attribute_sections = false csharp_space_between_empty_square_brackets = false csharp_space_between_method_call_empty_parameter_list_parentheses = false csharp_space_between_method_call_name_and_opening_parenthesis = false diff --git a/Build/Build.cs b/Build/Build.cs index 809bde6c05..5a6c9f77e5 100644 --- a/Build/Build.cs +++ b/Build/Build.cs @@ -42,7 +42,7 @@ class Build : NukeBuild string PullRequestBase => GitHubActions?.BaseRef; [Parameter("Use this parameter if you encounter build problems in any way, " + - "to generate a .binlog file which holds some useful information.")] + "to generate a .binlog file which holds some useful information.")] readonly bool? GenerateBinLog; [Parameter("The key to push to Nuget")] diff --git a/Src/FluentAssertions/Primitives/StringAssertions.cs b/Src/FluentAssertions/Primitives/StringAssertions.cs index 4cc4e3c540..4e3f87fab0 100644 --- a/Src/FluentAssertions/Primitives/StringAssertions.cs +++ b/Src/FluentAssertions/Primitives/StringAssertions.cs @@ -406,7 +406,7 @@ public AndConstraint NotMatchEquivalentOf(string wildcardPattern, s /// Zero or more objects to format using the placeholders in . /// /// - public AndConstraint is . MatchRegex([RegexPattern] [StringSyntax("Regex")] string regularExpression, + public AndConstraint MatchRegex([RegexPattern][StringSyntax("Regex")] string regularExpression, OccurrenceConstraint occurrenceConstraint, string because = "", params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(regularExpression, nameof(regularExpression), @@ -443,7 +443,7 @@ public AndConstraint MatchRegex([RegexPattern] [StringSyntax("Regex /// Zero or more objects to format using the placeholders in . /// /// - public AndConstraint is . MatchRegex([RegexPattern] [StringSyntax("Regex")] string regularExpression, + public AndConstraint MatchRegex([RegexPattern][StringSyntax("Regex")] string regularExpression, string because = "", params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(regularExpression, nameof(regularExpression), @@ -578,7 +578,7 @@ public AndConstraint MatchRegex(Regex regularExpression, /// Zero or more objects to format using the placeholders in . /// /// - public AndConstraint is . NotMatchRegex([RegexPattern] [StringSyntax("Regex")] string regularExpression, + public AndConstraint NotMatchRegex([RegexPattern][StringSyntax("Regex")] string regularExpression, string because = "", params object[] becauseArgs) { Guard.ThrowIfArgumentIsNull(regularExpression, nameof(regularExpression), diff --git a/Tests/Benchmarks/CheckIfMemberIsBrowsable.cs b/Tests/Benchmarks/CheckIfMemberIsBrowsable.cs index 12da2de01f..abbe1b4ee7 100644 --- a/Tests/Benchmarks/CheckIfMemberIsBrowsable.cs +++ b/Tests/Benchmarks/CheckIfMemberIsBrowsable.cs @@ -19,9 +19,8 @@ public class CheckIfMemberIsBrowsableBenchmarks .GetField(IsBrowsable ? nameof(BrowsableField) : nameof(NonBrowsableField)); [Benchmark] - public void CheckIfMemberIsBrowsable() + public bool CheckIfMemberIsBrowsable() { - bool _ = - SubjectField.GetCustomAttribute() is not { State: EditorBrowsableState.Never }; + return SubjectField.GetCustomAttribute() is not { State: EditorBrowsableState.Never }; } } diff --git a/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs index 2d489aac88..b4ff9f65ed 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs @@ -1245,13 +1245,17 @@ public void When_all_subject_items_are_equivalent_to_expectation_object_it_shoul }; // Act - Action action = () => subject.Should().AllBeEquivalentTo(new + Action action = () => + { + var expectation = new { Name = "someDto", Age = 1, Birthdate = default(DateTime) - }) - .And.HaveCount(3); + }; + + subject.Should().AllBeEquivalentTo(expectation).And.HaveCount(3); + }; // Assert action.Should().NotThrow(); @@ -2649,7 +2653,8 @@ public static IEnumerable ArrayTestData() new int?[] { null, 1 }, new int?[] { 1, null }, new object[] { null, 1 }, new object[] { 1, null } }; - return from x in arrays + return + from x in arrays from y in arrays select new[] { x, y }; } diff --git a/Tests/FluentAssertions.Equivalency.Specs/EnumSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/EnumSpecs.cs index 4a80b384ba..3438462db7 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/EnumSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/EnumSpecs.cs @@ -101,8 +101,7 @@ public void When_asserting_members_from_different_enum_types_are_equivalent_by_s // Arrange var subject = new ClassWithEnumOne { Enum = EnumOne.Two }; - var expectation = new ClassWithEnumThree - { Enum = EnumThree.Two }; + var expectation = new ClassWithEnumThree { Enum = EnumThree.Two }; // Act Action act = () => subject.Should().BeEquivalentTo(expectation, config => config.ComparingEnumsByName()); diff --git a/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs index 5f08521359..147296f9f6 100644 --- a/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs @@ -2759,7 +2759,8 @@ public static object[] Dictionaries() public static IEnumerable DictionariesData() { - return from x in Dictionaries() + return + from x in Dictionaries() from y in Dictionaries() select new[] { x, y }; } diff --git a/Tests/FluentAssertions.Specs/Extensions/ObjectExtensionsSpecs.cs b/Tests/FluentAssertions.Specs/Extensions/ObjectExtensionsSpecs.cs index c999833eb6..8c0d4f524f 100644 --- a/Tests/FluentAssertions.Specs/Extensions/ObjectExtensionsSpecs.cs +++ b/Tests/FluentAssertions.Specs/Extensions/ObjectExtensionsSpecs.cs @@ -80,7 +80,8 @@ public void When_comparing_a_non_numeric_to_a_numeric_it_should_fail(object actu public static IEnumerable GetNonNumericAndNumericData() { - return from x in GetNonNumericIConvertibles() + return + from x in GetNonNumericIConvertibles() from y in GetNumericIConvertibles() select new[] { x, y }; } @@ -101,7 +102,8 @@ public void When_comparing_a_numeric_to_a_non_numeric_it_should_fail(object actu public static IEnumerable GetNumericAndNonNumericData() { - return from x in GetNumericIConvertibles() + return + from x in GetNumericIConvertibles() from y in GetNonNumericIConvertibles() select new[] { x, y }; } From beb6123d27f1018c1b920c8c9060676d063807a5 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Thu, 23 Feb 2023 22:21:45 +0100 Subject: [PATCH 15/98] Remove unused MultiEnumerable Added in c847f3cc93f59495d4309fc64d8801f3bdc764e4 --- .../CollectionSpecs.cs | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs index b4ff9f65ed..67fdfe5861 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs @@ -84,27 +84,6 @@ public void CopyTo(Array array, int index) public bool IsSynchronized => ((ICollection)inner).IsSynchronized; } - private class MultiEnumerable : IEnumerable, IEnumerable - { - private readonly List ints = new(); - private readonly List longs = new(); - - IEnumerator IEnumerable.GetEnumerator() - { - return ints.GetEnumerator(); - } - - public IEnumerator GetEnumerator() - { - return GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return longs.GetEnumerator(); - } - } - private class EnumerableOfStringAndObject : IEnumerable, IEnumerable { IEnumerator IEnumerable.GetEnumerator() From 21ce126c0c9d0b1d8303925c06abe6913de483fc Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 25 Feb 2023 10:08:10 +0100 Subject: [PATCH 16/98] Use a fixed seed for random generator --- Tests/FluentAssertions.Equivalency.Specs/DataSpecs.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/FluentAssertions.Equivalency.Specs/DataSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/DataSpecs.cs index f9b08f075b..08c7fe3f7b 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/DataSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/DataSpecs.cs @@ -442,7 +442,7 @@ private void CopyTable(TDataTable from, TDataTable to, boo #endregion - private static readonly Random Random = new(); + private static readonly Random Random = new(0); internal static TDataSet CreateDummyDataSet(bool identicalTables = false, bool includeDummyData = true, bool includeRelation = true) From 2aab90e962491f7a57427aac328c75e1164d9598 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 11:37:10 +0100 Subject: [PATCH 17/98] Add missing xml docs for parameters --- .../DataColumnCollectionAssertionExtensions.cs | 4 ++++ Src/FluentAssertions/Specialized/ExceptionAssertions.cs | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Src/FluentAssertions/DataColumnCollectionAssertionExtensions.cs b/Src/FluentAssertions/DataColumnCollectionAssertionExtensions.cs index 0524cc371e..d830033eb8 100644 --- a/Src/FluentAssertions/DataColumnCollectionAssertionExtensions.cs +++ b/Src/FluentAssertions/DataColumnCollectionAssertionExtensions.cs @@ -12,6 +12,7 @@ public static class DataColumnCollectionAssertionExtensions /// + /// The /// Asserts that an object reference refers to the exact same object as another object reference. /// object that is being extended. /// The expected object /// /// A formatted phrase as is supported by explaining why the assertion @@ -56,6 +57,7 @@ public static AndConstraint> BeSameAs( /// + /// The /// Asserts that an object reference refers to a different object than another object reference refers to. /// object that is being extended. /// The unexpected object /// /// A formatted phrase as is supported by explaining why the assertion @@ -98,6 +100,7 @@ public static AndConstraint> NotBeSameAs /// + /// The /// Assert that the current collection has the same number of elements as . /// object that is being extended. /// The other collection with the same expected number of elements /// /// A formatted phrase as is supported by explaining why the assertion @@ -134,6 +137,7 @@ public static AndConstraint> HaveSameCou /// Assert that the current collection of s does not have the same number of columns as /// . /// + /// The object that is being extended. /// The other with the unexpected number of /// elements /// diff --git a/Src/FluentAssertions/Specialized/ExceptionAssertions.cs b/Src/FluentAssertions/Specialized/ExceptionAssertions.cs index b665959082..da0b4a4e0d 100644 --- a/Src/FluentAssertions/Specialized/ExceptionAssertions.cs +++ b/Src/FluentAssertions/Specialized/ExceptionAssertions.cs @@ -112,8 +112,9 @@ public virtual ExceptionAssertions WithInnerException - /// Asserts that the thrown exception contains an inner exception of type . + /// Asserts that the thrown exception contains an inner exception of type . /// + /// The expected type of the inner exception. /// /// A formatted phrase as is supported by explaining why the assertion /// is needed. If the phrase does not start with the word , it is prepended automatically. @@ -147,8 +148,9 @@ public virtual ExceptionAssertionsbecause WithInnerExceptionExactly - /// Asserts that the thrown exception contains an inner exception of the exact type (and not a derived exception type). + /// Asserts that the thrown exception contains an inner exception of the exact type (and not a derived exception type). /// + /// The expected type of the inner exception. /// /// A formatted phrase as is supported by explaining why the assertion /// is needed. If the phrase does not start with the word , it is prepended automatically. From 3660ab6319a8727291a321c69296fb65e6ab72a6 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup because Date: Sat, 4 Mar 2023 12:09:59 +0100 Subject: [PATCH 18/98] Increase robustness when wrapped in an AssertionScope --- .../GenericDictionaryAssertions.cs | 573 +++++++++--------- .../Data/DataRowAssertions.cs | 31 +- .../Data/DataSetAssertions.cs | 46 +- .../Data/DataTableAssertions.cs | 49 +- .../Events/EventAssertions.cs | 33 +- .../Xml/XDocumentAssertions.cs | 21 +- .../Xml/XElementAssertions.cs | 17 +- .../Xml/XmlElementAssertions.cs | 17 +- .../DataRowSpecs.cs | 7 +- .../DataSetSpecs.cs | 13 +- .../DataTableSpecs.cs | 13 +- .../GenericDictionaryAssertionSpecs.cs | 124 +++- .../Events/EventAssertionSpecs.cs | 7 +- .../Xml/XDocumentAssertionSpecs.cs | 6 +- .../Xml/XElementAssertionSpecs.cs | 3 + .../Xml/XmlElementAssertionSpecs.cs | 4 + docs/_pages/releases.md | 1 + 17 files changed, 565 insertions(+), 400 deletions(-) diff --git a/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs b/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs index 132a2b5517..3ba3f9ae71 100644 --- a/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs +++ b/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs @@ -56,45 +56,46 @@ public AndConstraint Equal(T expected, string because = "", params object[] becauseArgs) where T : IEnumerable> { - if (Subject is null) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to be equal to {0}{reason}, but found {1}.", expected, Subject); - } - Guard.ThrowIfArgumentIsNull(expected, nameof(expected), "Cannot compare dictionary with ."); - IEnumerable subjectKeys = GetKeys(Subject); - IEnumerable expectedKeys = GetKeys(expected); - IEnumerable missingKeys = expectedKeys.Except(subjectKeys); - IEnumerable additionalKeys = subjectKeys.Except(expectedKeys); + bool success = Execute.Assertion + .ForCondition(Subject is not null) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} to be equal to {0}{reason}, but found {1}.", expected, Subject); - if (missingKeys.Any()) + if (success) { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to be equal to {0}{reason}, but could not find keys {1}.", expected, - missingKeys); - } + IEnumerable subjectKeys = GetKeys(Subject); + IEnumerable expectedKeys = GetKeys(expected); + IEnumerable missingKeys = expectedKeys.Except(subjectKeys); + IEnumerable additionalKeys = subjectKeys.Except(expectedKeys); - if (additionalKeys.Any()) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to be equal to {0}{reason}, but found additional keys {1}.", expected, - additionalKeys); - } + if (missingKeys.Any()) + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} to be equal to {0}{reason}, but could not find keys {1}.", expected, + missingKeys); + } + + if (additionalKeys.Any()) + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} to be equal to {0}{reason}, but found additional keys {1}.", expected, + additionalKeys); + } - Func areSameOrEqual = ObjectExtensions.GetComparer(); + Func areSameOrEqual = ObjectExtensions.GetComparer(); - foreach (var key in expectedKeys) - { - Execute.Assertion - .ForCondition(areSameOrEqual(GetValue(Subject, key), GetValue(expected, key))) - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to be equal to {0}{reason}, but {1} differs at key {2}.", - expected, Subject, key); + foreach (var key in expectedKeys) + { + Execute.Assertion + .ForCondition(areSameOrEqual(GetValue(Subject, key), GetValue(expected, key))) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} to be equal to {0}{reason}, but {1} differs at key {2}.", + expected, Subject, key); + } } return new AndConstraint((TAssertions)this); @@ -118,38 +119,39 @@ public AndConstraint NotEqual(T unexpected, string because = "", params object[] becauseArgs) where T : IEnumerable> { - if (Subject is null) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected dictionaries not to be equal{reason}, but found {0}.", Subject); - } - Guard.ThrowIfArgumentIsNull(unexpected, nameof(unexpected), "Cannot compare dictionary with ."); - if (ReferenceEquals(Subject, unexpected)) + bool success = Execute.Assertion + .ForCondition(Subject is not null) + .BecauseOf(because, becauseArgs) + .FailWith("Expected dictionaries not to be equal{reason}, but found {0}.", Subject); + + if (success) { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected dictionaries not to be equal{reason}, but they both reference the same object."); - } + if (ReferenceEquals(Subject, unexpected)) + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Expected dictionaries not to be equal{reason}, but they both reference the same object."); + } - IEnumerable subjectKeys = GetKeys(Subject); - IEnumerable unexpectedKeys = GetKeys(unexpected); - IEnumerable missingKeys = unexpectedKeys.Except(subjectKeys); - IEnumerable additionalKeys = subjectKeys.Except(unexpectedKeys); + IEnumerable subjectKeys = GetKeys(Subject); + IEnumerable unexpectedKeys = GetKeys(unexpected); + IEnumerable missingKeys = unexpectedKeys.Except(subjectKeys); + IEnumerable additionalKeys = subjectKeys.Except(unexpectedKeys); - Func areSameOrEqual = ObjectExtensions.GetComparer(); + Func areSameOrEqual = ObjectExtensions.GetComparer(); - bool foundDifference = missingKeys.Any() - || additionalKeys.Any() - || subjectKeys.Any(key => !areSameOrEqual(GetValue(Subject, key), GetValue(unexpected, key))); + bool foundDifference = missingKeys.Any() + || additionalKeys.Any() + || subjectKeys.Any(key => !areSameOrEqual(GetValue(Subject, key), GetValue(unexpected, key))); - if (!foundDifference) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Did not expect dictionaries {0} and {1} to be equal{reason}.", unexpected, Subject); + if (!foundDifference) + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Did not expect dictionaries {0} and {1} to be equal{reason}.", unexpected, Subject); + } } return new AndConstraint((TAssertions)this); @@ -292,30 +294,31 @@ public AndConstraint ContainKeys(IEnumerable expected, ICollection expectedKeys = expected.ConvertOrCastToCollection(); Guard.ThrowIfArgumentIsEmpty(expectedKeys, nameof(expected), "Cannot verify key containment against an empty sequence"); - if (Subject is null) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to contain keys {0}{reason}, but found {1}.", expected, Subject); - } - - IEnumerable missingKeys = expectedKeys.Where(key => !ContainsKey(Subject, key)); + bool success = Execute.Assertion + .ForCondition(Subject is not null) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} to contain keys {0}{reason}, but found .", expected); - if (missingKeys.Any()) + if (success) { - if (expectedKeys.Count > 1) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} {0} to contain key {1}{reason}, but could not find {2}.", Subject, - expected, missingKeys); - } - else + IEnumerable missingKeys = expectedKeys.Where(key => !ContainsKey(Subject, key)); + + if (missingKeys.Any()) { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} {0} to contain key {1}{reason}.", Subject, - expected.Cast().First()); + if (expectedKeys.Count > 1) + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} {0} to contain key {1}{reason}, but could not find {2}.", Subject, + expected, missingKeys); + } + else + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} {0} to contain key {1}{reason}.", Subject, + expected.Cast().First()); + } } } @@ -341,19 +344,20 @@ public AndConstraint ContainKeys(IEnumerable expected, public AndConstraint NotContainKey(TKey unexpected, string because = "", params object[] becauseArgs) { - if (Subject is null) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} not to contain key {0}{reason}, but found {1}.", unexpected, Subject); - } + bool success = Execute.Assertion + .ForCondition(Subject is not null) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} not to contain key {0}{reason}, but found .", unexpected); - if (ContainsKey(Subject, unexpected)) + if (success) { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} {0} not to contain key {1}{reason}, but found it anyhow.", Subject, - unexpected); + if (ContainsKey(Subject, unexpected)) + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} {0} not to contain key {1}{reason}, but found it anyhow.", Subject, + unexpected); + } } return new AndConstraint((TAssertions)this); @@ -394,30 +398,31 @@ public AndConstraint NotContainKeys(IEnumerable unexpected, Guard.ThrowIfArgumentIsEmpty(unexpectedKeys, nameof(unexpected), "Cannot verify key containment against an empty sequence"); - if (Subject is null) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to contain keys {0}{reason}, but found {1}.", unexpected, Subject); - } - - IEnumerable foundKeys = unexpected.Where(key => ContainsKey(Subject, key)); + bool success = Execute.Assertion + .ForCondition(Subject is not null) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} to not contain keys {0}{reason}, but found .", unexpected); - if (foundKeys.Any()) + if (success) { - if (unexpectedKeys.Count > 1) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} {0} to not contain key {1}{reason}, but found {2}.", Subject, - unexpected, foundKeys); - } - else + IEnumerable foundKeys = unexpected.Where(key => ContainsKey(Subject, key)); + + if (foundKeys.Any()) { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} {0} to not contain key {1}{reason}.", Subject, - unexpected.Cast().First()); + if (unexpectedKeys.Count > 1) + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} {0} to not contain key {1}{reason}, but found {2}.", Subject, + unexpected, foundKeys); + } + else + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} {0} to not contain key {1}{reason}.", Subject, + unexpected.Cast().First()); + } } } @@ -493,38 +498,40 @@ private AndWhichConstraint> ContainValuesAndWhi Guard.ThrowIfArgumentIsEmpty(expectedValues, nameof(expected), "Cannot verify value containment against an empty sequence"); - if (Subject is null) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to contain value {0}{reason}, but found {1}.", expected, Subject); - } + bool success = Execute.Assertion + .ForCondition(Subject is not null) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} to contain values {0}{reason}, but found {1}.", expected, Subject); - IEnumerable subjectValues = GetValues(Subject); - IEnumerable missingValues = expectedValues.Except(subjectValues); + IEnumerable matchedConstraint = null; - if (missingValues.Any()) + if (success) { - if (expectedValues.Count > 1) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} {0} to contain value {1}{reason}, but could not find {2}.", Subject, - expected, missingValues); - } - else + IEnumerable subjectValues = GetValues(Subject); + IEnumerable missingValues = expectedValues.Except(subjectValues); + + if (missingValues.Any()) { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} {0} to contain value {1}{reason}.", Subject, - expected.Cast().First()); + if (expectedValues.Count > 1) + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} {0} to contain value {1}{reason}, but could not find {2}.", Subject, + expected, missingValues); + } + else + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} {0} to contain value {1}{reason}.", Subject, + expected.Cast().First()); + } } + + matchedConstraint = RepetitionPreservingIntersect(subjectValues, expectedValues); } - return - new AndWhichConstraint>((TAssertions)this, - RepetitionPreservingIntersect(subjectValues, expectedValues)); + return new AndWhichConstraint>((TAssertions)this, matchedConstraint); } /// @@ -557,19 +564,20 @@ private static IEnumerable RepetitionPreservingIntersect( public AndConstraint NotContainValue(TValue unexpected, string because = "", params object[] becauseArgs) { - if (Subject is null) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} not to contain value {0}{reason}, but found {1}.", unexpected, Subject); - } + bool success = Execute.Assertion + .ForCondition(Subject is not null) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} not to contain value {0}{reason}, but found .", unexpected); - if (GetValues(Subject).Contains(unexpected)) + if (success) { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} {0} not to contain value {1}{reason}, but found it anyhow.", Subject, - unexpected); + if (GetValues(Subject).Contains(unexpected)) + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} {0} not to contain value {1}{reason}, but found it anyhow.", Subject, + unexpected); + } } return new AndConstraint((TAssertions)this); @@ -610,30 +618,31 @@ public AndConstraint NotContainValues(IEnumerable unexpecte Guard.ThrowIfArgumentIsEmpty(unexpectedValues, nameof(unexpected), "Cannot verify value containment with an empty sequence"); - if (Subject is null) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to not contain value {0}{reason}, but found {1}.", unexpected, Subject); - } - - IEnumerable foundValues = unexpectedValues.Intersect(GetValues(Subject)); + bool success = Execute.Assertion + .ForCondition(Subject is not null) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} to not contain values {0}{reason}, but found .", unexpected); - if (foundValues.Any()) + if (success) { - if (unexpectedValues.Count > 1) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} {0} to not contain value {1}{reason}, but found {2}.", Subject, - unexpected, foundValues); - } - else + IEnumerable foundValues = unexpectedValues.Intersect(GetValues(Subject)); + + if (foundValues.Any()) { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} {0} to not contain value {1}{reason}.", Subject, - unexpected.Cast().First()); + if (unexpectedValues.Count > 1) + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} {0} to not contain value {1}{reason}, but found {2}.", Subject, + unexpected, foundValues); + } + else + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} {0} to not contain value {1}{reason}.", Subject, + unexpected.Cast().First()); + } } } @@ -680,60 +689,61 @@ public AndConstraint Contain(params KeyValuePair[] ex Guard.ThrowIfArgumentIsEmpty(expectedKeyValuePairs, nameof(expected), "Cannot verify key containment against an empty collection of key/value pairs"); - if (Subject is null) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to contain key/value pairs {0}{reason}, but dictionary is {1}.", - expected, Subject); - } + bool success = Execute.Assertion + .ForCondition(Subject is not null) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} to contain key/value pairs {0}{reason}, but dictionary is .", + expected); - TKey[] expectedKeys = expectedKeyValuePairs.Select(keyValuePair => keyValuePair.Key).ToArray(); - IEnumerable missingKeys = expectedKeys.Where(key => !ContainsKey(Subject, key)); - - if (missingKeys.Any()) + if (success) { - if (expectedKeyValuePairs.Count > 1) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} {0} to contain key(s) {1}{reason}, but could not find keys {2}.", - Subject, - expectedKeys, missingKeys); - } - else + TKey[] expectedKeys = expectedKeyValuePairs.Select(keyValuePair => keyValuePair.Key).ToArray(); + IEnumerable missingKeys = expectedKeys.Where(key => !ContainsKey(Subject, key)); + + if (missingKeys.Any()) { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} {0} to contain key {1}{reason}.", Subject, - expectedKeys.Cast().First()); + if (expectedKeyValuePairs.Count > 1) + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} {0} to contain key(s) {1}{reason}, but could not find keys {2}.", + Subject, + expectedKeys, missingKeys); + } + else + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} {0} to contain key {1}{reason}.", Subject, + expectedKeys.Cast().First()); + } } - } - Func areSameOrEqual = ObjectExtensions.GetComparer(); + Func areSameOrEqual = ObjectExtensions.GetComparer(); - KeyValuePair[] keyValuePairsNotSameOrEqualInSubject = expectedKeyValuePairs - .Where(keyValuePair => !areSameOrEqual(GetValue(Subject, keyValuePair.Key), keyValuePair.Value)).ToArray(); + KeyValuePair[] keyValuePairsNotSameOrEqualInSubject = expectedKeyValuePairs + .Where(keyValuePair => !areSameOrEqual(GetValue(Subject, keyValuePair.Key), keyValuePair.Value)).ToArray(); - if (keyValuePairsNotSameOrEqualInSubject.Any()) - { - if (keyValuePairsNotSameOrEqualInSubject.Length > 1) + if (keyValuePairsNotSameOrEqualInSubject.Any()) { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith( - "Expected {context:dictionary} to contain {0}{reason}, but {context:dictionary} differs at keys {1}.", - expectedKeyValuePairs, keyValuePairsNotSameOrEqualInSubject.Select(keyValuePair => keyValuePair.Key)); - } - else - { - KeyValuePair expectedKeyValuePair = keyValuePairsNotSameOrEqualInSubject[0]; - TValue actual = GetValue(Subject, expectedKeyValuePair.Key); + if (keyValuePairsNotSameOrEqualInSubject.Length > 1) + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith( + "Expected {context:dictionary} to contain {0}{reason}, but {context:dictionary} differs at keys {1}.", + expectedKeyValuePairs, keyValuePairsNotSameOrEqualInSubject.Select(keyValuePair => keyValuePair.Key)); + } + else + { + KeyValuePair expectedKeyValuePair = keyValuePairsNotSameOrEqualInSubject[0]; + TValue actual = GetValue(Subject, expectedKeyValuePair.Key); - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to contain value {0} at key {1}{reason}, but found {2}.", - expectedKeyValuePair.Value, expectedKeyValuePair.Key, actual); + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} to contain value {0} at key {1}{reason}, but found {2}.", + expectedKeyValuePair.Value, expectedKeyValuePair.Key, actual); + } } } @@ -777,32 +787,32 @@ public AndConstraint Contain(params KeyValuePair[] ex public AndConstraint Contain(TKey key, TValue value, string because = "", params object[] becauseArgs) { - if (Subject is null) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to contain value {0} at key {1}{reason}, but dictionary is {2}.", value, - key, - Subject); - } + bool success = Execute.Assertion + .ForCondition(Subject is not null) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} to contain value {0} at key {1}{reason}, but dictionary is .", + value, key); - if (TryGetValue(Subject, key, out TValue actual)) + if (success) { - Func areSameOrEqual = ObjectExtensions.GetComparer(); + if (TryGetValue(Subject, key, out TValue actual)) + { + Func areSameOrEqual = ObjectExtensions.GetComparer(); - Execute.Assertion - .ForCondition(areSameOrEqual(actual, value)) - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to contain value {0} at key {1}{reason}, but found {2}.", value, key, - actual); - } - else - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to contain value {0} at key {1}{reason}, but the key was not found.", - value, - key); + Execute.Assertion + .ForCondition(areSameOrEqual(actual, value)) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} to contain value {0} at key {1}{reason}, but found {2}.", value, key, + actual); + } + else + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} to contain value {0} at key {1}{reason}, but the key was not found.", + value, + key); + } } return new AndConstraint((TAssertions)this); @@ -848,43 +858,44 @@ public AndConstraint NotContain(params KeyValuePair[] Guard.ThrowIfArgumentIsEmpty(keyValuePairs, nameof(items), "Cannot verify key containment against an empty collection of key/value pairs"); - if (Subject is null) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to not contain key/value pairs {0}{reason}, but dictionary is {1}.", - items, Subject); - } + bool success = Execute.Assertion + .ForCondition(Subject is not null) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} to not contain key/value pairs {0}{reason}, but dictionary is .", + items); - KeyValuePair[] keyValuePairsFound = - keyValuePairs.Where(keyValuePair => ContainsKey(Subject, keyValuePair.Key)).ToArray(); - - if (keyValuePairsFound.Any()) + if (success) { - Func areSameOrEqual = ObjectExtensions.GetComparer(); - - KeyValuePair[] keyValuePairsSameOrEqualInSubject = keyValuePairsFound - .Where(keyValuePair => areSameOrEqual(GetValue(Subject, keyValuePair.Key), keyValuePair.Value)).ToArray(); + KeyValuePair[] keyValuePairsFound = + keyValuePairs.Where(keyValuePair => ContainsKey(Subject, keyValuePair.Key)).ToArray(); - if (keyValuePairsSameOrEqualInSubject.Any()) + if (keyValuePairsFound.Any()) { - if (keyValuePairsSameOrEqualInSubject.Length > 1) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith( - "Expected {context:dictionary} to not contain key/value pairs {0}{reason}, but found them anyhow.", - keyValuePairs); - } - else - { - KeyValuePair keyValuePair = keyValuePairsSameOrEqualInSubject[0]; + Func areSameOrEqual = ObjectExtensions.GetComparer(); - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith( - "Expected {context:dictionary} to not contain value {0} at key {1}{reason}, but found it anyhow.", - keyValuePair.Value, keyValuePair.Key); + KeyValuePair[] keyValuePairsSameOrEqualInSubject = keyValuePairsFound + .Where(keyValuePair => areSameOrEqual(GetValue(Subject, keyValuePair.Key), keyValuePair.Value)).ToArray(); + + if (keyValuePairsSameOrEqualInSubject.Any()) + { + if (keyValuePairsSameOrEqualInSubject.Length > 1) + { + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith( + "Expected {context:dictionary} to not contain key/value pairs {0}{reason}, but found them anyhow.", + keyValuePairs); + } + else + { + KeyValuePair keyValuePair = keyValuePairsSameOrEqualInSubject[0]; + + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith( + "Expected {context:dictionary} to not contain value {0} at key {1}{reason}, but found it anyhow.", + keyValuePair.Value, keyValuePair.Key); + } } } } @@ -929,22 +940,22 @@ public AndConstraint NotContain(params KeyValuePair[] public AndConstraint NotContain(TKey key, TValue value, string because = "", params object[] becauseArgs) { - if (Subject is null) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} not to contain value {0} at key {1}{reason}, but dictionary is {2}.", - value, - key, Subject); - } + bool success = Execute.Assertion + .ForCondition(Subject is not null) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} not to contain value {0} at key {1}{reason}, but dictionary is .", + value, key); - if (TryGetValue(Subject, key, out TValue actual)) + if (success) { - Execute.Assertion - .ForCondition(!ObjectExtensions.GetComparer()(actual, value)) - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} not to contain value {0} at key {1}{reason}, but found it anyhow.", - value, key); + if (TryGetValue(Subject, key, out TValue actual)) + { + Execute.Assertion + .ForCondition(!ObjectExtensions.GetComparer()(actual, value)) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} not to contain value {0} at key {1}{reason}, but found it anyhow.", + value, key); + } } return new AndConstraint((TAssertions)this); diff --git a/Src/FluentAssertions/Data/DataRowAssertions.cs b/Src/FluentAssertions/Data/DataRowAssertions.cs index 167a4d533a..591813c454 100644 --- a/Src/FluentAssertions/Data/DataRowAssertions.cs +++ b/Src/FluentAssertions/Data/DataRowAssertions.cs @@ -84,22 +84,23 @@ public AndConstraint> HaveColumns(params string[] ex public AndConstraint> HaveColumns(IEnumerable expectedColumnNames, string because = "", params object[] becauseArgs) { - if (Subject is null) + bool success = Execute.Assertion + .ForCondition(Subject is not null) + .BecauseOf(because, becauseArgs) + .FailWith( + "Expected {context:DataRow} to be in a table containing {0} column(s) with specific names{reason}, but found .", + () => expectedColumnNames.Count()); + + if (success) { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith( - "Expected {context:DataRow} to be in a table containing {0} column(s) with specific names{reason}, but found .", - expectedColumnNames.Count()); - } - - foreach (var expectedColumnName in expectedColumnNames) - { - Execute.Assertion - .ForCondition(Subject.Table.Columns.Contains(expectedColumnName)) - .BecauseOf(because, becauseArgs) - .FailWith("Expected table containing {context:DataRow} to contain a column named {0}{reason}, but it does not.", - expectedColumnName); + foreach (var expectedColumnName in expectedColumnNames) + { + Execute.Assertion + .ForCondition(Subject.Table.Columns.Contains(expectedColumnName)) + .BecauseOf(because, becauseArgs) + .FailWith("Expected table containing {context:DataRow} to contain a column named {0}{reason}, but it does not.", + expectedColumnName); + } } return new AndConstraint>(this); diff --git a/Src/FluentAssertions/Data/DataSetAssertions.cs b/Src/FluentAssertions/Data/DataSetAssertions.cs index c2e2466458..0c465c9763 100644 --- a/Src/FluentAssertions/Data/DataSetAssertions.cs +++ b/Src/FluentAssertions/Data/DataSetAssertions.cs @@ -37,21 +37,22 @@ public DataSetAssertions(TDataSet dataSet) public AndConstraint> HaveTableCount(int expected, string because = "", params object[] becauseArgs) { - if (Subject is null) + bool success = Execute.Assertion + .ForCondition(Subject is not null) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:DataSet} to contain exactly {0} table(s){reason}, but found .", expected); + + if (success) { + int actualCount = Subject.Tables.Count; + Execute.Assertion + .ForCondition(actualCount == expected) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:DataSet} to contain exactly {0} table(s){reason}, but found .", expected); + .FailWith("Expected {context:DataSet} to contain exactly {0} table(s){reason}, but found {1}.", expected, + actualCount); } - int actualCount = Subject.Tables.Count; - - Execute.Assertion - .ForCondition(actualCount == expected) - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:DataSet} to contain exactly {0} table(s){reason}, but found {1}.", expected, - actualCount); - return new AndConstraint>(this); } @@ -115,20 +116,21 @@ public AndConstraint> HaveTables(params string[] exp public AndConstraint> HaveTables(IEnumerable expectedTableNames, string because = "", params object[] becauseArgs) { - if (Subject is null) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:DataSet} to contain {0} table(s) with specific names{reason}, but found .", - expectedTableNames.Count()); - } + bool success = Execute.Assertion + .ForCondition(Subject is not null) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:DataSet} to contain {0} table(s) with specific names{reason}, but found .", + () => expectedTableNames.Count()); - foreach (var expectedTableName in expectedTableNames) + if (success) { - Execute.Assertion - .ForCondition(Subject.Tables.Contains(expectedTableName)) - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:DataSet} to contain a table named {0}{reason}, but it does not.", expectedTableName); + foreach (var expectedTableName in expectedTableNames) + { + Execute.Assertion + .ForCondition(Subject.Tables.Contains(expectedTableName)) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:DataSet} to contain a table named {0}{reason}, but it does not.", expectedTableName); + } } return new AndConstraint>(this); diff --git a/Src/FluentAssertions/Data/DataTableAssertions.cs b/Src/FluentAssertions/Data/DataTableAssertions.cs index 2c1916b230..9167928057 100644 --- a/Src/FluentAssertions/Data/DataTableAssertions.cs +++ b/Src/FluentAssertions/Data/DataTableAssertions.cs @@ -3,6 +3,7 @@ using System.Data; using System.Diagnostics; using System.Linq; +using System.Xml.Schema; using FluentAssertions.Common; using FluentAssertions.Equivalency; using FluentAssertions.Execution; @@ -37,21 +38,22 @@ public DataTableAssertions(TDataTable dataTable) public AndConstraint> HaveRowCount(int expected, string because = "", params object[] becauseArgs) { - if (Subject is null) + bool success = Execute.Assertion + .ForCondition(Subject is not null) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:DataTable} to contain exactly {0} row(s){reason}, but found .", expected); + + if (success) { + int actualCount = Subject.Rows.Count; + Execute.Assertion + .ForCondition(actualCount == expected) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:DataTable} to contain exactly {0} row(s){reason}, but found .", expected); + .FailWith("Expected {context:DataTable} to contain exactly {0} row(s){reason}, but found {1}.", expected, + actualCount); } - int actualCount = Subject.Rows.Count; - - Execute.Assertion - .ForCondition(actualCount == expected) - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:DataTable} to contain exactly {0} row(s){reason}, but found {1}.", expected, - actualCount); - return new AndConstraint>(this); } @@ -116,21 +118,22 @@ public AndConstraint> HaveColumns(params string[ public AndConstraint> HaveColumns(IEnumerable expectedColumnNames, string because = "", params object[] becauseArgs) { - if (Subject is null) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:DataTable} to contain {0} column(s) with specific names{reason}, but found .", - expectedColumnNames.Count()); - } + bool success = Execute.Assertion + .ForCondition(Subject is not null) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:DataTable} to contain {0} column(s) with specific names{reason}, but found .", + () => expectedColumnNames.Count()); - foreach (var expectedColumnName in expectedColumnNames) + if (success) { - Execute.Assertion - .ForCondition(Subject.Columns.Contains(expectedColumnName)) - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:DataTable} to contain a column named {0}{reason}, but it does not.", - expectedColumnName); + foreach (var expectedColumnName in expectedColumnNames) + { + Execute.Assertion + .ForCondition(Subject.Columns.Contains(expectedColumnName)) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:DataTable} to contain a column named {0}{reason}, but it does not.", + expectedColumnName); + } } return new AndConstraint>(this); diff --git a/Src/FluentAssertions/Events/EventAssertions.cs b/Src/FluentAssertions/Events/EventAssertions.cs index 8a5f28e820..97fadab856 100644 --- a/Src/FluentAssertions/Events/EventAssertions.cs +++ b/Src/FluentAssertions/Events/EventAssertions.cs @@ -100,27 +100,28 @@ public IEventRecording RaisePropertyChangeFor(Expression> proper IEventRecording recording = Monitor.GetRecordingFor(PropertyChangedEventName); - if (!recording.Any()) + bool success = Execute.Assertion + .BecauseOf(because, becauseArgs) + .ForCondition(recording.Any()) + .FailWith( + "Expected object {0} to raise event {1} for property {2}{reason}, but it did not raise that event at all.", + Monitor.Subject, PropertyChangedEventName, propertyName); + + if (success) { + var actualPropertyNames = recording + .SelectMany(@event => @event.Parameters.OfType()) + .Select(eventArgs => eventArgs.PropertyName) + .Distinct() + .ToArray(); + Execute.Assertion + .ForCondition(actualPropertyNames.Contains(propertyName)) .BecauseOf(because, becauseArgs) - .FailWith( - "Expected object {0} to raise event {1} for property {2}{reason}, but it did not raise that event at all.", - Monitor.Subject, PropertyChangedEventName, propertyName); + .FailWith("Expected object {0} to raise event {1} for property {2}{reason}, but it was only raised for {3}.", + Monitor.Subject, PropertyChangedEventName, propertyName, actualPropertyNames); } - var actualPropertyNames = recording - .SelectMany(@event => @event.Parameters.OfType()) - .Select(eventArgs => eventArgs.PropertyName) - .Distinct() - .ToArray(); - - Execute.Assertion - .ForCondition(actualPropertyNames.Contains(propertyName)) - .BecauseOf(because, becauseArgs) - .FailWith("Expected object {0} to raise event {1} for property {2}{reason}, but it was only raised for {3}.", - Monitor.Subject, PropertyChangedEventName, propertyName, actualPropertyNames); - return recording; } diff --git a/Src/FluentAssertions/Xml/XDocumentAssertions.cs b/Src/FluentAssertions/Xml/XDocumentAssertions.cs index 2971c9ec6a..3c6b13aedb 100644 --- a/Src/FluentAssertions/Xml/XDocumentAssertions.cs +++ b/Src/FluentAssertions/Xml/XDocumentAssertions.cs @@ -254,21 +254,26 @@ public AndWhichConstraint HaveElement(XName expec Guard.ThrowIfArgumentIsNull(expected, nameof(expected), "Cannot assert the document has an element if the expected name is ."); - Execute.Assertion + bool success = Execute.Assertion .ForCondition(Subject.Root is not null) .BecauseOf(because, becauseArgs) .FailWith( "Expected {context:subject} to have root element with child {0}{reason}, but it has no root element.", expected.ToString()); - XElement xElement = Subject.Root.Element(expected); + XElement xElement = null; - Execute.Assertion - .ForCondition(xElement is not null) - .BecauseOf(because, becauseArgs) - .FailWith( - "Expected {context:subject} to have root element with child {0}{reason}, but no such child element was found.", - expected.ToString()); + if (success) + { + xElement = Subject.Root.Element(expected); + + Execute.Assertion + .ForCondition(xElement is not null) + .BecauseOf(because, becauseArgs) + .FailWith( + "Expected {context:subject} to have root element with child {0}{reason}, but no such child element was found.", + expected.ToString()); + } return new AndWhichConstraint(this, xElement); } diff --git a/Src/FluentAssertions/Xml/XElementAssertions.cs b/Src/FluentAssertions/Xml/XElementAssertions.cs index 6b0f916716..6b212e3c54 100644 --- a/Src/FluentAssertions/Xml/XElementAssertions.cs +++ b/Src/FluentAssertions/Xml/XElementAssertions.cs @@ -209,7 +209,7 @@ public AndConstraint HaveAttribute(XName expectedName, strin { XAttribute attribute = Subject.Attribute(expectedName); - Execute.Assertion + success = Execute.Assertion .ForCondition(attribute is not null) .BecauseOf(because, becauseArgs) .FailWith( @@ -217,12 +217,15 @@ public AndConstraint HaveAttribute(XName expectedName, strin + " but found no such attribute in {2}", expectedText, expectedValue, Subject); - Execute.Assertion - .ForCondition(attribute.Value == expectedValue) - .BecauseOf(because, becauseArgs) - .FailWith( - "Expected attribute {0} in {context:subject} to have value {1}{reason}, but found {2}.", - expectedText, expectedValue, attribute.Value); + if (success) + { + Execute.Assertion + .ForCondition(attribute.Value == expectedValue) + .BecauseOf(because, becauseArgs) + .FailWith( + "Expected attribute {0} in {context:subject} to have value {1}{reason}, but found {2}.", + expectedText, expectedValue, attribute.Value); + } } return new AndConstraint(this); diff --git a/Src/FluentAssertions/Xml/XmlElementAssertions.cs b/Src/FluentAssertions/Xml/XmlElementAssertions.cs index dd1631e380..40d3503982 100644 --- a/Src/FluentAssertions/Xml/XmlElementAssertions.cs +++ b/Src/FluentAssertions/Xml/XmlElementAssertions.cs @@ -93,7 +93,7 @@ public AndConstraint HaveAttributeWithNamespace( (string.IsNullOrEmpty(expectedNamespace) ? string.Empty : $"{{{expectedNamespace}}}") + expectedName; - Execute.Assertion + bool success = Execute.Assertion .ForCondition(attribute is not null) .BecauseOf(because, becauseArgs) .FailWith( @@ -101,12 +101,15 @@ public AndConstraint HaveAttributeWithNamespace( + " with value {1}{reason}, but found no such attribute in {2}", expectedFormattedName, expectedValue, Subject); - Execute.Assertion - .ForCondition(attribute.Value == expectedValue) - .BecauseOf(because, becauseArgs) - .FailWith( - "Expected attribute {0} in {context:subject} to have value {1}{reason}, but found {2}.", - expectedFormattedName, expectedValue, attribute.Value); + if (success) + { + Execute.Assertion + .ForCondition(attribute.Value == expectedValue) + .BecauseOf(because, becauseArgs) + .FailWith( + "Expected attribute {0} in {context:subject} to have value {1}{reason}, but found {2}.", + expectedFormattedName, expectedValue, attribute.Value); + } return new AndConstraint(this); } diff --git a/Tests/FluentAssertions.Equivalency.Specs/DataRowSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/DataRowSpecs.cs index bdac798576..a2edba5a51 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/DataRowSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/DataRowSpecs.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Data; using System.Linq; +using FluentAssertions.Execution; using Xunit; using Xunit.Sdk; @@ -476,7 +477,11 @@ public void Null_data_row_and_using_the_array_overload_fails() .ToArray(); // Act - Action act = () => actual.Should().HaveColumns(subsetOfColumnNames); + Action act = () => + { + using var _ = new AssertionScope(); + actual.Should().HaveColumns(subsetOfColumnNames); + }; // Assert act.Should().Throw() diff --git a/Tests/FluentAssertions.Equivalency.Specs/DataSetSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/DataSetSpecs.cs index 635c555045..341bd5d509 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/DataSetSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/DataSetSpecs.cs @@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; +using FluentAssertions.Execution; using Xunit; using Xunit.Sdk; @@ -684,7 +685,11 @@ public void Null_data_set_fails() var correctTableCount = -1; // Act - Action act = () => dataSet.Should().HaveTableCount(correctTableCount); + Action act = () => + { + using var _ = new AssertionScope(); + dataSet.Should().HaveTableCount(correctTableCount); + }; // Assert act.Should().Throw() @@ -777,7 +782,11 @@ public void Null_data_set_has_no_tables_and_fails() .Select(table => table.TableName); // Act - Action act = () => actual.Should().HaveTables(existingTableNames); + Action act = () => + { + using var _ = new AssertionScope(); + actual.Should().HaveTables(existingTableNames); + }; // Assert act.Should().Throw() diff --git a/Tests/FluentAssertions.Equivalency.Specs/DataTableSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/DataTableSpecs.cs index d64fe33739..3406bbed26 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/DataTableSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/DataTableSpecs.cs @@ -3,6 +3,7 @@ using System.Globalization; using System.Linq; using FluentAssertions.Data; +using FluentAssertions.Execution; using Xunit; using Xunit.Sdk; @@ -806,7 +807,11 @@ public void Null_data_table_no_rows_and_fails_test() int correctRowCount = -1; // Act - Action act = () => dataTable.Should().HaveRowCount(correctRowCount); + Action act = () => + { + using var _ = new AssertionScope(); + dataTable.Should().HaveRowCount(correctRowCount); + }; // Assert act.Should().Throw() @@ -919,7 +924,11 @@ public void Null_data_table_has_no_columns_and_fails_the_test() var existingColumnName = "Does not matter"; // Act - Action act = () => actual.Should().HaveColumns(existingColumnName); + Action act = () => + { + using var _ = new AssertionScope(); + actual.Should().HaveColumns(existingColumnName); + }; // Assert act.Should().Throw() diff --git a/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs index 147296f9f6..35000545df 100644 --- a/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs @@ -1094,7 +1094,10 @@ public void When_asserting_dictionaries_to_be_equal_but_subject_dictionary_is_nu // Act Action act = () => + { + using var _ = new AssertionScope(); dictionary1.Should().Equal(dictionary2, "because we want to test the behaviour with a null subject"); + }; // Assert act.Should().Throw().WithMessage( @@ -1247,8 +1250,11 @@ public void When_asserting_dictionaries_not_to_be_equal_subject_but_dictionary_i }; // Act - Action act = - () => dictionary1.Should().NotEqual(dictionary2, "because we want to test the behaviour with a null subject"); + Action act = () => + { + using var _ = new AssertionScope(); + dictionary1.Should().NotEqual(dictionary2, "because we want to test the behaviour with a null subject"); + }; // Assert act.Should().Throw().WithMessage( @@ -1400,6 +1406,24 @@ public void When_a_dictionary_does_not_contain_a_list_of_keys_it_should_throw_wi "Expected dictionary {[1] = \"One\", [2] = \"Two\"} to contain key {2, 3} because we do, but could not find {3}."); } + [Fact] + public void Null_dictionaries_do_not_contain_any_keys() + { + // Arrange + Dictionary dictionary = null; + + // Act + Action act = () => + { + using var _ = new AssertionScope(); + dictionary.Should().ContainKeys(new[] { 2, 3 }, "because {0}", "we do"); + }; + + // Assert + act.Should().Throw().WithMessage( + "Expected dictionary to contain keys {2, 3} because we do, but found ."); + } + [Fact] public void When_the_contents_of_a_dictionary_are_checked_against_an_empty_list_of_keys_it_should_throw_clear_explanation() @@ -1481,8 +1505,11 @@ public void When_asserting_dictionary_does_not_contain_key_against_null_dictiona Dictionary dictionary = null; // Act - Action act = () => dictionary.Should() - .NotContainKey(1, "because we want to test the behaviour with a null subject"); + Action act = () => + { + using var _ = new AssertionScope(); + dictionary.Should().NotContainKey(1, "because we want to test the behaviour with a null subject"); + }; // Assert act.Should().Throw().WithMessage( @@ -1525,6 +1552,24 @@ public void When_a_dictionary_contains_exactly_one_of_the_keys_it_should_throw_w "Expected dictionary {[1] = \"One\", [2] = \"Two\"} to not contain key 2 because we do."); } + [Fact] + public void Null_dictionaries_do_not_contain_any_keys() + { + // Arrange + Dictionary dictionary = null; + + // Act + Action act = () => + { + using var _ = new AssertionScope(); + dictionary.Should().NotContainKeys(new[] { 2 }, "because {0}", "we do"); + }; + + // Assert + act.Should().Throw().WithMessage( + "Expected dictionary to not contain keys {2} because we do, but found ."); + } + [Fact] public void When_the_noncontents_of_a_dictionary_are_checked_against_an_empty_list_of_keys_it_should_throw_clear_explanation() @@ -1652,6 +1697,24 @@ public void When_dictionary_contains_expected_value_it_should_succeed() act.Should().NotThrow(); } + [Fact] + public void Null_dictionaries_do_not_contain_any_values() + { + // Arrange + Dictionary dictionary = null; + + // Act + Action act = () => + { + using var _ = new AssertionScope(); + dictionary.Should().ContainValue("One", "because {0}", "we do"); + }; + + // Assert + act.Should().Throw() + .WithMessage("Expected dictionary to contain values {\"One\"} because we do, but found ."); + } + [Fact] public void When_dictionary_contains_expected_null_value_it_should_succeed() { @@ -1830,8 +1893,11 @@ public void When_asserting_dictionary_does_not_contain_value_against_null_dictio Dictionary dictionary = null; // Act - Action act = () => dictionary.Should() - .NotContainValue("One", "because we want to test the behaviour with a null subject"); + Action act = () => + { + using var _ = new AssertionScope(); + dictionary.Should().NotContainValue("One", "because we want to test the behaviour with a null subject"); + }; // Assert act.Should().Throw().WithMessage( @@ -1909,6 +1975,24 @@ public void act.Should().Throw().WithMessage( "Cannot verify value containment with an empty sequence*"); } + + [Fact] + public void Null_dictionaries_do_not_contain_any_values() + { + // Arrange + Dictionary dictionary = null; + + // Act + Action act = () => + { + using var _ = new AssertionScope(); + dictionary.Should().NotContainValues(new[] { "Two", "Three" }, "because {0}", "we do"); + }; + + // Assert + act.Should().Throw().WithMessage( + "Expected dictionary to not contain values {\"Two\", \"Three\"} because we do, but found ."); + } } public class Contain @@ -2081,8 +2165,11 @@ public void When_asserting_dictionary_contains_key_value_pairs_against_null_dict }; // Act - Action act = () => dictionary.Should().Contain(keyValuePairs, - "because we want to test the behaviour with a null subject"); + Action act = () => + { + using var _ = new AssertionScope(); + dictionary.Should().Contain(keyValuePairs, "because we want to test the behaviour with a null subject"); + }; // Assert act.Should().Throw().WithMessage( @@ -2280,8 +2367,11 @@ public void When_asserting_dictionary_contains_value_at_specific_key_against_nul Dictionary dictionary = null; // Act - Action act = () => dictionary.Should().Contain(1, "One", - "because we want to test the behaviour with a null subject"); + Action act = () => + { + using var _ = new AssertionScope(); + dictionary.Should().Contain(1, "One", "because we want to test the behaviour with a null subject"); + }; // Assert act.Should().Throw().WithMessage( @@ -2462,8 +2552,11 @@ public void When_asserting_dictionary_does_not_contain_key_value_pairs_against_n }; // Act - Action act = () => dictionary.Should().NotContain(keyValuePairs, - "because we want to test the behaviour with a null subject"); + Action act = () => + { + using var _ = new AssertionScope(); + dictionary.Should().NotContain(keyValuePairs, "because we want to test the behaviour with a null subject"); + }; // Assert act.Should().Throw().WithMessage( @@ -2662,8 +2755,11 @@ public void When_asserting_dictionary_does_not_contain_value_at_specific_key_aga Dictionary dictionary = null; // Act - Action act = () => dictionary.Should().NotContain(1, "One", - "because we want to test the behaviour with a null subject"); + Action act = () => + { + using var _ = new AssertionScope(); + dictionary.Should().NotContain(1, "One", "because we want to test the behaviour with a null subject"); + }; // Assert act.Should().Throw().WithMessage( diff --git a/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs index d491e9b366..e03842bde1 100644 --- a/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs @@ -2,6 +2,7 @@ using System.ComponentModel; using System.Linq; using FluentAssertions.Events; +using FluentAssertions.Execution; using FluentAssertions.Extensions; using FluentAssertions.Formatting; using Xunit; @@ -507,7 +508,11 @@ public void When_a_property_agnostic_property_changed_event_for_was_not_raised_i using var monitor = subject.Monitor(); // Act - Action act = () => monitor.Should().RaisePropertyChangeFor(null); + Action act = () => + { + using var _ = new AssertionScope(); + monitor.Should().RaisePropertyChangeFor(null); + }; // Assert act.Should().Throw().WithMessage( diff --git a/Tests/FluentAssertions.Specs/Xml/XDocumentAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Xml/XDocumentAssertionSpecs.cs index 35ef93c747..f308fd4418 100644 --- a/Tests/FluentAssertions.Specs/Xml/XDocumentAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Xml/XDocumentAssertionSpecs.cs @@ -1151,7 +1151,11 @@ public void When_asserting_a_document_without_root_element_has_an_element_it_sho XDocument document = new(); // Act - Action act = () => document.Should().HaveElement("unknown"); + Action act = () => + { + using var _ = new AssertionScope(); + document.Should().HaveElement("unknown"); + }; // Assert act.Should().Throw().WithMessage( diff --git a/Tests/FluentAssertions.Specs/Xml/XElementAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Xml/XElementAssertionSpecs.cs index fe9b955251..24c59c1f6b 100644 --- a/Tests/FluentAssertions.Specs/Xml/XElementAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Xml/XElementAssertionSpecs.cs @@ -916,7 +916,10 @@ public void // Act Action act = () => + { + using var _ = new AssertionScope(); theElement.Should().HaveAttribute("age", "36", "because we want to test the failure {0}", "message"); + }; // Assert act.Should().Throw().WithMessage( diff --git a/Tests/FluentAssertions.Specs/Xml/XmlElementAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Xml/XmlElementAssertionSpecs.cs index b5b09c78fb..485f1ed495 100644 --- a/Tests/FluentAssertions.Specs/Xml/XmlElementAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Xml/XmlElementAssertionSpecs.cs @@ -1,5 +1,6 @@ using System; using System.Xml; +using FluentAssertions.Execution; using Xunit; using Xunit.Sdk; @@ -224,8 +225,11 @@ public void // Act Action act = () => + { + using var _ = new AssertionScope(); theElement.Should().HaveAttributeWithNamespace("age", "http://www.example.com/2012/test", "36", "because we want to test the failure {0}", "message"); + }; // Assert act.Should().Throw() diff --git a/docs/_pages/releases.md b/docs/_pages/releases.md index 3228d54f07..ae332296fc 100644 --- a/docs/_pages/releases.md +++ b/docs/_pages/releases.md @@ -12,6 +12,7 @@ sidebar: ### What's new ### Fixes +* Improved robustness of several assertions when they're wrapped in an `AssertionScope` - [#2133](https://github.com/fluentassertions/fluentassertions/pull/2133) ## 6.10.0 From eb0ea23eccbf3286c540c5d32fea9ad7cfc14d77 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Mon, 6 Mar 2023 16:24:30 +0100 Subject: [PATCH 19/98] Pluralize key to keys --- .../Collections/GenericDictionaryAssertions.cs | 4 ++-- .../Collections/GenericDictionaryAssertionSpecs.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs b/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs index 3ba3f9ae71..78586d2d77 100644 --- a/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs +++ b/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs @@ -309,7 +309,7 @@ public AndConstraint ContainKeys(IEnumerable expected, { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} {0} to contain key {1}{reason}, but could not find {2}.", Subject, + .FailWith("Expected {context:dictionary} {0} to contain keys {1}{reason}, but could not find {2}.", Subject, expected, missingKeys); } else @@ -413,7 +413,7 @@ public AndConstraint NotContainKeys(IEnumerable unexpected, { Execute.Assertion .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} {0} to not contain key {1}{reason}, but found {2}.", Subject, + .FailWith("Expected {context:dictionary} {0} to not contain keys {1}{reason}, but found {2}.", Subject, unexpected, foundKeys); } else diff --git a/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs index 35000545df..f06fc95cb3 100644 --- a/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs @@ -1403,7 +1403,7 @@ public void When_a_dictionary_does_not_contain_a_list_of_keys_it_should_throw_wi // Assert act.Should().Throw().WithMessage( - "Expected dictionary {[1] = \"One\", [2] = \"Two\"} to contain key {2, 3} because we do, but could not find {3}."); + "Expected dictionary {[1] = \"One\", [2] = \"Two\"} to contain keys {2, 3} because we do, but could not find {3}."); } [Fact] @@ -1531,7 +1531,7 @@ public void When_a_dictionary_contains_a_list_of_keys_it_should_throw_with_clear // Assert act.Should().Throw().WithMessage( - "Expected dictionary {[1] = \"One\", [2] = \"Two\"} to not contain key {2, 3} because we do, but found {2}."); + "Expected dictionary {[1] = \"One\", [2] = \"Two\"} to not contain keys {2, 3} because we do, but found {2}."); } [Fact] From c9a1b8886ae38d51efeb5317cd337f695311128b Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Mon, 6 Mar 2023 16:29:47 +0100 Subject: [PATCH 20/98] Remove unnecessary cast This is a leftover from the non-generic days when we accepted an `IEnumerable` and not `IEnumerable` --- .../Collections/GenericDictionaryAssertions.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs b/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs index 78586d2d77..90dd3811de 100644 --- a/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs +++ b/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs @@ -317,7 +317,7 @@ public AndConstraint ContainKeys(IEnumerable expected, Execute.Assertion .BecauseOf(because, becauseArgs) .FailWith("Expected {context:dictionary} {0} to contain key {1}{reason}.", Subject, - expected.Cast().First()); + expected.First()); } } } @@ -421,7 +421,7 @@ public AndConstraint NotContainKeys(IEnumerable unexpected, Execute.Assertion .BecauseOf(because, becauseArgs) .FailWith("Expected {context:dictionary} {0} to not contain key {1}{reason}.", Subject, - unexpected.Cast().First()); + unexpected.First()); } } } @@ -524,7 +524,7 @@ private AndWhichConstraint> ContainValuesAndWhi Execute.Assertion .BecauseOf(because, becauseArgs) .FailWith("Expected {context:dictionary} {0} to contain value {1}{reason}.", Subject, - expected.Cast().First()); + expected.First()); } } @@ -641,7 +641,7 @@ public AndConstraint NotContainValues(IEnumerable unexpecte Execute.Assertion .BecauseOf(because, becauseArgs) .FailWith("Expected {context:dictionary} {0} to not contain value {1}{reason}.", Subject, - unexpected.Cast().First()); + unexpected.First()); } } } @@ -715,7 +715,7 @@ public AndConstraint Contain(params KeyValuePair[] ex Execute.Assertion .BecauseOf(because, becauseArgs) .FailWith("Expected {context:dictionary} {0} to contain key {1}{reason}.", Subject, - expectedKeys.Cast().First()); + expectedKeys.First()); } } From 751cebff94f003327bf9f98023b2a84ccc6733a9 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 09:22:09 +0100 Subject: [PATCH 21/98] Unnecessary interpolated strings --- Src/FluentAssertions/Equivalency/INode.cs | 2 +- .../Equivalency/IObjectInfo.cs | 2 +- .../Matching/MustMatchByNameRule.cs | 2 +- ...elfReferenceEquivalencyAssertionOptions.cs | 2 +- .../Primitives/StringAssertions.cs | 2 +- .../StringBuilderExtensions.cs | 2 +- .../Types/MemberInfoAssertions.cs | 8 ++--- Src/FluentAssertions/Types/TypeAssertions.cs | 30 +++++++++---------- .../Xml/XDocumentAssertions.cs | 2 +- .../Xml/XElementAssertions.cs | 2 +- .../DataRowSpecs.cs | 2 +- .../Execution/CallerIdentifierSpecs.cs | 4 +++ 12 files changed, 32 insertions(+), 28 deletions(-) diff --git a/Src/FluentAssertions/Equivalency/INode.cs b/Src/FluentAssertions/Equivalency/INode.cs index e3f37d40ce..ce6e612ba5 100644 --- a/Src/FluentAssertions/Equivalency/INode.cs +++ b/Src/FluentAssertions/Equivalency/INode.cs @@ -24,7 +24,7 @@ public interface INode string Name { get; set; } /// Type Type { get; } diff --git a/Src/FluentAssertions/Equivalency/IObjectInfo.cs b/Src/FluentAssertions/Equivalency/IObjectInfo.cs index aed6ca8130..a02a04a1a0 100644 --- a/Src/FluentAssertions/Equivalency/IObjectInfo.cs +++ b/Src/FluentAssertions/Equivalency/IObjectInfo.cs @@ -9,7 +9,7 @@ namespace FluentAssertions.Equivalency; public interface IObjectInfo { /// [Obsolete("Use CompileTimeType or RuntimeType instead")] Type Type { get; } diff --git a/Src/FluentAssertions/Equivalency/Matching/MustMatchByNameRule.cs b/Src/FluentAssertions/Equivalency/Matching/MustMatchByNameRule.cs index 87a530358f..0f804c1024 100644 --- a/Src/FluentAssertions/Equivalency/Matching/MustMatchByNameRule.cs +++ b/Src/FluentAssertions/Equivalency/Matching/MustMatchByNameRule.cs @@ -40,7 +40,7 @@ public IMember Match(IMember expectedMember, object subject, INode parent, IEqui { Execute.Assertion.FailWith( $"Expectation has {expectedMember.Description} that is non-browsable in the other object, and non-browsable " + - $"members on the subject are ignored with the current configuration"); + "members on the subject are ignored with the current configuration"); } return subjectMember; diff --git a/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs b/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs index ff627159e4..a2c32ba37d 100644 --- a/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs +++ b/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs @@ -613,7 +613,7 @@ public TSelf ComparingRecordsByValue() } /// /// - /// Gets the type of this node, e.g. the type of the field or property, or the type of the collection item. + /// Gets the type of this node, e.g. the type of the field or property, or the type of the collection item. /// - /// Gets the type of the object + /// Gets the type of the object /// - /// Ensures records by default are compared by their members even though they override + /// Ensures records by default are compared by their members even though they override /// the method. /// diff --git a/Src/FluentAssertions/Primitives/StringAssertions.cs b/Src/FluentAssertions/Primitives/StringAssertions.cs index 4e3f87fab0..44811576d7 100644 --- a/Src/FluentAssertions/Primitives/StringAssertions.cs +++ b/Src/FluentAssertions/Primitives/StringAssertions.cs @@ -512,7 +512,7 @@ public AndConstraint MatchRegex(Regex regularExpression, .ForConstraint(occurrenceConstraint, actual) .UsingLineBreaks .BecauseOf(because, becauseArgs) - .FailWith($"Expected {{context:string}} {{0}} to match regex {{1}} {{expectedOccurrence}}{{reason}}, " + + .FailWith("Expected {context:string} {0} to match regex {1} {expectedOccurrence}{reason}, " + $"but found it {actual.Times()}.", Subject, regexStr); } diff --git a/Src/FluentAssertions/StringBuilderExtensions.cs b/Src/FluentAssertions/StringBuilderExtensions.cs index 8de0a7946e..1234ccd378 100644 --- a/Src/FluentAssertions/StringBuilderExtensions.cs +++ b/Src/FluentAssertions/StringBuilderExtensions.cs @@ -3,7 +3,7 @@ /// internal static class StringBuilderExtensions diff --git a/Src/FluentAssertions/Types/MemberInfoAssertions.cs b/Src/FluentAssertions/Types/MemberInfoAssertions.cs index c41dcfed59..e57dbdd9a5 100644 --- a/Src/FluentAssertions/Types/MemberInfoAssertions.cs +++ b/Src/FluentAssertions/Types/MemberInfoAssertions.cs @@ -84,7 +84,7 @@ public AndWhichConstraint /// Since net6.0 StringBuilder has additional overloads taking an AppendInterpolatedStringHandler /// and optionally an IFormatProvider. -/// The overload here is polyfill for older target frameworks to avoid littering the code base with #ifs +/// The overload here is polyfill for older target frameworks to avoid littering the code base with #ifs /// in order to silence analyzers about dependending on the current culture instead of an invariant culture. /// , TAttribut .ForCondition(Subject is not null) .FailWith( $"Expected {Identifier} to be decorated with {typeof(TAttribute)}{{reason}}" + - $", but {{context:member}} is ."); + ", but {context:member} is ."); IEnumerable attributes = new TAttribute[0]; @@ -97,7 +97,7 @@ public AndWhichConstraint, TAttribut .BecauseOf(because, becauseArgs) .FailWith( $"Expected {Identifier} {SubjectDescription} to be decorated with {typeof(TAttribute)}{{reason}}" + - $", but that attribute was not found."); + ", but that attribute was not found."); } return new AndWhichConstraint, TAttribute>(this, attributes); @@ -130,7 +130,7 @@ public AndConstraint NotBeDecoratedWith( .ForCondition(Subject is not null) .FailWith( $"Expected {Identifier} to not be decorated with {typeof(TAttribute)}{{reason}}" + - $", but {{context:member}} is ."); + ", but {context:member} is ."); if (success) { @@ -141,7 +141,7 @@ public AndConstraint NotBeDecoratedWith( .BecauseOf(because, becauseArgs) .FailWith( $"Expected {Identifier} {SubjectDescription} to not be decorated with {typeof(TAttribute)}{{reason}}" + - $", but that attribute was found."); + ", but that attribute was found."); } return new AndConstraint((TAssertions)this); diff --git a/Src/FluentAssertions/Types/TypeAssertions.cs b/Src/FluentAssertions/Types/TypeAssertions.cs index 6373caf6e3..120f9c0bb8 100644 --- a/Src/FluentAssertions/Types/TypeAssertions.cs +++ b/Src/FluentAssertions/Types/TypeAssertions.cs @@ -969,7 +969,7 @@ public AndConstraint HaveExplicitProperty( .ForCondition(Subject is not null) .FailWith( $"Expected {{context:type}} to explicitly implement {interfaceType}.{name}{{reason}}" + - $", but {{context:type}} is ."); + ", but {context:type} is ."); if (success) { @@ -1036,7 +1036,7 @@ public AndConstraint NotHaveExplicitProperty( .ForCondition(Subject is not null) .FailWith( $"Expected {{context:type}} to not explicitly implement {interfaceType}.{name}{{reason}}" + - $", but {{context:type}} is ."); + ", but {context:type} is ."); if (success) { @@ -1049,7 +1049,7 @@ public AndConstraint NotHaveExplicitProperty( .ForCondition(!explicitlyImplementsProperty) .FailWith( $"Expected {Subject} to not explicitly implement {interfaceType}.{name}{{reason}}" + - $", but it does."); + ", but it does."); } return new AndConstraint(this); @@ -1249,7 +1249,7 @@ public AndWhichConstraint HaveIndexer( .ForCondition(Subject is not null) .FailWith( $"Expected {indexerType.Name} {{context:type}}[{GetParameterString(parameterTypes)}] to exist{{reason}}" + - $", but {{context:type}} is ."); + ", but {context:type} is ."); PropertyInfo propertyInfo = null; @@ -1263,7 +1263,7 @@ public AndWhichConstraint HaveIndexer( .ForCondition(propertyInfo is not null) .FailWith( $"Expected {indexerType.Name} {Subject}[{GetParameterString(parameterTypes)}] to exist{{reason}}" + - $", but it does not.") + ", but it does not.") .Then .ForCondition(propertyInfo.PropertyType == indexerType) .FailWith($"Expected {propertyInfoDescription} to be of type {indexerType}{{reason}}, but it is not."); @@ -1295,7 +1295,7 @@ public AndConstraint NotHaveIndexer( .ForCondition(Subject is not null) .FailWith( $"Expected indexer {{context:type}}[{GetParameterString(parameterTypes)}] to not exist{{reason}}" + - $", but {{context:type}} is ."); + ", but {context:type} is ."); if (success) { @@ -1306,7 +1306,7 @@ public AndConstraint NotHaveIndexer( .ForCondition(propertyInfo is null) .FailWith( $"Expected indexer {Subject}[{GetParameterString(parameterTypes)}] to not exist{{reason}}" + - $", but it does."); + ", but it does."); } return new AndConstraint(this); @@ -1339,7 +1339,7 @@ public AndWhichConstraint HaveMethod( .ForCondition(Subject is not null) .FailWith( $"Expected method {{context:type}}.{name}({GetParameterString(parameterTypes)}) to exist{{reason}}" + - $", but {{context:type}} is ."); + ", but {context:type} is ."); MethodInfo methodInfo = null; @@ -1352,7 +1352,7 @@ public AndWhichConstraint HaveMethod( .ForCondition(methodInfo is not null) .FailWith( $"Expected method {Subject}.{name}({GetParameterString(parameterTypes)}) to exist{{reason}}" + - $", but it does not."); + ", but it does not."); } return new AndWhichConstraint(this, methodInfo); @@ -1385,7 +1385,7 @@ public AndConstraint NotHaveMethod( .ForCondition(Subject is not null) .FailWith( $"Expected method {{context:type}}.{name}({GetParameterString(parameterTypes)}) to not exist{{reason}}" + - $", but {{context:type}} is ."); + ", but {context:type} is ."); if (success) { @@ -1397,7 +1397,7 @@ public AndConstraint NotHaveMethod( .ForCondition(methodInfo is null) .FailWith( $"Expected method {methodInfoDescription}({GetParameterString(parameterTypes)}) to not exist{{reason}}" + - $", but it does."); + ", but it does."); } return new AndConstraint(this); @@ -1425,7 +1425,7 @@ public AndWhichConstraint HaveConstructor( .ForCondition(Subject is not null) .FailWith( $"Expected constructor {{context:type}}({GetParameterString(parameterTypes)}) to exist{{reason}}" + - $", but {{context:type}} is ."); + ", but {context:type} is ."); ConstructorInfo constructorInfo = null; @@ -1438,7 +1438,7 @@ public AndWhichConstraint HaveConstructor( .ForCondition(constructorInfo is not null) .FailWith( $"Expected constructor {Subject}({GetParameterString(parameterTypes)}) to exist{{reason}}" + - $", but it does not."); + ", but it does not."); } return new AndWhichConstraint(this, constructorInfo); @@ -1482,7 +1482,7 @@ public AndWhichConstraint NotHaveConstructor( .ForCondition(Subject is not null) .FailWith( $"Expected constructor {{context:type}}({GetParameterString(parameterTypes)}) not to exist{{reason}}" + - $", but {{context:type}} is ."); + ", but {context:type} is ."); ConstructorInfo constructorInfo = null; @@ -1495,7 +1495,7 @@ public AndWhichConstraint NotHaveConstructor( .ForCondition(constructorInfo is null) .FailWith( $"Expected constructor {Subject}({GetParameterString(parameterTypes)}) not to exist{{reason}}" + - $", but it does."); + ", but it does."); } return new AndWhichConstraint(this, constructorInfo); diff --git a/Src/FluentAssertions/Xml/XDocumentAssertions.cs b/Src/FluentAssertions/Xml/XDocumentAssertions.cs index 3c6b13aedb..2760a6e0b9 100644 --- a/Src/FluentAssertions/Xml/XDocumentAssertions.cs +++ b/Src/FluentAssertions/Xml/XDocumentAssertions.cs @@ -330,7 +330,7 @@ public AndWhichConstraint> HaveElemen .ForConstraint(occurrenceConstraint, actual) .BecauseOf(because, becauseArgs) .FailWith( - $"Expected {{context:subject}} to have a root element containing a child {{0}} " + + "Expected {context:subject} to have a root element containing a child {0} " + $"{{expectedOccurrence}}{{reason}}, but found it {actual.Times()}.", expected.ToString()); } diff --git a/Src/FluentAssertions/Xml/XElementAssertions.cs b/Src/FluentAssertions/Xml/XElementAssertions.cs index 6b212e3c54..2ab3943c89 100644 --- a/Src/FluentAssertions/Xml/XElementAssertions.cs +++ b/Src/FluentAssertions/Xml/XElementAssertions.cs @@ -338,7 +338,7 @@ public AndWhichConstraint> HaveElement .ForConstraint(occurrenceConstraint, actual) .BecauseOf(because, becauseArgs) .FailWith( - $"Expected {{context:subject}} to have an element {{0}} {{expectedOccurrence}}" + + "Expected {context:subject} to have an element {0} {expectedOccurrence}" + $"{{reason}}, but found it {actual.Times()}.", expected.ToString()); } diff --git a/Tests/FluentAssertions.Equivalency.Specs/DataRowSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/DataRowSpecs.cs index a2edba5a51..1539c836e0 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/DataRowSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/DataRowSpecs.cs @@ -372,7 +372,7 @@ public void Data_row_is_not_equivalent_to_another_type() [Fact] public void Any_type_is_not_equivalent_to_data_row_colletion() { - // Arrange + // Arrange var o = new object(); // Act diff --git a/Tests/FluentAssertions.Specs/Execution/CallerIdentifierSpecs.cs b/Tests/FluentAssertions.Specs/Execution/CallerIdentifierSpecs.cs index f5081ce2d7..b80dff08dc 100644 --- a/Tests/FluentAssertions.Specs/Execution/CallerIdentifierSpecs.cs +++ b/Tests/FluentAssertions.Specs/Execution/CallerIdentifierSpecs.cs @@ -9,6 +9,8 @@ using Xunit; using Xunit.Sdk; +#pragma warning disable RCS1192, RCS1214 // verbatim string literals and interpolated strings + namespace FluentAssertions.Specs.Execution { public class CallerIdentifierSpecs @@ -223,10 +225,12 @@ public void When_there_are_several_statements_on_the_line_it_should_use_the_corr var foo = new Foo(); // Act +#pragma warning disable format Action act = () => { var foo2 = foo; foo2.Should().BeNull(); }; +#pragma warning restore format // Assert act.Should().Throw() From 7b64250092a9bb036c3c1b62fb5490b66b518ccc Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 09:30:22 +0100 Subject: [PATCH 22/98] Use discard parameter names --- .../FluentAssertions.Specs/Events/EventAssertionSpecs.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs index e03842bde1..113fc221e4 100644 --- a/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs @@ -912,7 +912,7 @@ public void One_matching_argument_type_anywhere_between_mismatching_types_with_p a.OnEvent(new C()); // Act / Assert - IEventRecording filteredEvents = aMonitor.GetRecordingFor(nameof(A.Event)).WithArgs(b => true); + IEventRecording filteredEvents = aMonitor.GetRecordingFor(nameof(A.Event)).WithArgs(_ => true); filteredEvents.Should().HaveCount(1); } @@ -927,7 +927,7 @@ public void Mismatching_argument_types_with_one_parameter_matching_a_different_t a.OnEvent(new C()); // Act - Action act = () => aMonitor.GetRecordingFor(nameof(A.Event)).WithArgs(b => true); + Action act = () => aMonitor.GetRecordingFor(nameof(A.Event)).WithArgs(_ => true); // Assert act.Should().Throw() @@ -945,7 +945,7 @@ public void Mismatching_argument_types_with_two_or_more_parameters_matching_a_di a.OnEvent(new C()); // Act - Action act = () => aMonitor.GetRecordingFor(nameof(A.Event)).WithArgs(b => true, b => false); + Action act = () => aMonitor.GetRecordingFor(nameof(A.Event)).WithArgs(_ => true, _ => false); // Assert act.Should().Throw() @@ -963,7 +963,7 @@ public void One_matching_argument_type_with_two_or_more_parameters_matching_a_mi a.OnEvent(new B()); // Act - Action act = () => aMonitor.GetRecordingFor(nameof(A.Event)).WithArgs(b => true, b => false); + Action act = () => aMonitor.GetRecordingFor(nameof(A.Event)).WithArgs(_ => true, _ => false); // Assert act.Should().Throw() From b604e420b594502366ffbd9eb6e467c80979f8b7 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 09:42:30 +0100 Subject: [PATCH 23/98] Use AppendJoin to avoid intermediate string --- .../Execution/CollectingAssertionStrategy.cs | 2 +- Src/FluentAssertions/StringBuilderExtensions.cs | 9 ++++++++- .../Execution/AssertionScopeSpecs.cs | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Src/FluentAssertions/Execution/CollectingAssertionStrategy.cs b/Src/FluentAssertions/Execution/CollectingAssertionStrategy.cs index 26ec686600..334637cc5f 100644 --- a/Src/FluentAssertions/Execution/CollectingAssertionStrategy.cs +++ b/Src/FluentAssertions/Execution/CollectingAssertionStrategy.cs @@ -34,7 +34,7 @@ public void ThrowIfAny(IDictionary context) if (failureMessages.Any()) { var builder = new StringBuilder(); - builder.AppendLine(string.Join(Environment.NewLine, failureMessages)); + builder.AppendJoin(Environment.NewLine, failureMessages).AppendLine(); if (context.Any()) { diff --git a/Src/FluentAssertions/StringBuilderExtensions.cs b/Src/FluentAssertions/StringBuilderExtensions.cs index 1234ccd378..1d9e98e1f9 100644 --- a/Src/FluentAssertions/StringBuilderExtensions.cs +++ b/Src/FluentAssertions/StringBuilderExtensions.cs @@ -1,4 +1,6 @@ -namespace System.Text; +using System.Collections.Generic; + +namespace System.Text; /// internal class MustMatchByNameRule : IMemberMatchingRule { - public IMember Match(IMember expectedMember, object subject, INode parent, IEquivalencyAssertionOptions config) + public IMember Match(IMember expectedMember, object subject, INode parent, IEquivalencyAssertionOptions options) { IMember subjectMember = null; - if (config.IncludedProperties != MemberVisibility.None) + if (options.IncludedProperties != MemberVisibility.None) { PropertyInfo propertyInfo = subject.GetType().FindProperty(expectedMember.Name); subjectMember = propertyInfo is not null && !propertyInfo.IsIndexer() ? new Property(propertyInfo, parent) : null; } - if (subjectMember is null && config.IncludedFields != MemberVisibility.None) + if (subjectMember is null && options.IncludedFields != MemberVisibility.None) { FieldInfo fieldInfo = subject.GetType().FindField(expectedMember.Name); subjectMember = fieldInfo is not null ? new Field(fieldInfo, parent) : null; } - if ((subjectMember is null || !config.UseRuntimeTyping) && ExpectationImplementsMemberExplicitly(subject, expectedMember)) + if ((subjectMember is null || !options.UseRuntimeTyping) && ExpectationImplementsMemberExplicitly(subject, expectedMember)) { subjectMember = expectedMember; } @@ -36,7 +36,7 @@ public IMember Match(IMember expectedMember, object subject, INode parent, IEqui $"Expectation has {expectedMember.Description} that the other object does not have."); } - if (config.IgnoreNonBrowsableOnSubject && !subjectMember.IsBrowsable) + if (options.IgnoreNonBrowsableOnSubject && !subjectMember.IsBrowsable) { Execute.Assertion.FailWith( $"Expectation has {expectedMember.Description} that is non-browsable in the other object, and non-browsable " + diff --git a/Src/FluentAssertions/Equivalency/Matching/TryMatchByNameRule.cs b/Src/FluentAssertions/Equivalency/Matching/TryMatchByNameRule.cs index 6a20dc10bd..e44c0e6779 100644 --- a/Src/FluentAssertions/Equivalency/Matching/TryMatchByNameRule.cs +++ b/Src/FluentAssertions/Equivalency/Matching/TryMatchByNameRule.cs @@ -8,7 +8,7 @@ namespace FluentAssertions.Equivalency.Matching; /// internal class TryMatchByNameRule : IMemberMatchingRule { - public IMember Match(IMember expectedMember, object subject, INode parent, IEquivalencyAssertionOptions config) + public IMember Match(IMember expectedMember, object subject, INode parent, IEquivalencyAssertionOptions options) { PropertyInfo property = subject.GetType().FindProperty(expectedMember.Name); diff --git a/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs b/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs index a2c32ba37d..a794036032 100644 --- a/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs +++ b/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs @@ -178,31 +178,31 @@ IEnumerable /// Since net6.0 StringBuilder has additional overloads taking an AppendInterpolatedStringHandler @@ -10,4 +12,9 @@ internal static class StringBuilderExtensions { public static StringBuilder AppendLine(this StringBuilder stringBuilder, IFormatProvider _, string value) => stringBuilder.AppendLine(value); + +#if NET47 || NETSTANDARD2_0 + public static StringBuilder AppendJoin(this StringBuilder stringBuilder, string separator, IEnumerable values) => + stringBuilder.Append(string.Join(Environment.NewLine, values)); +#endif } diff --git a/Tests/FluentAssertions.Specs/Execution/AssertionScopeSpecs.cs b/Tests/FluentAssertions.Specs/Execution/AssertionScopeSpecs.cs index f4f4caa1d3..4c6261afa2 100644 --- a/Tests/FluentAssertions.Specs/Execution/AssertionScopeSpecs.cs +++ b/Tests/FluentAssertions.Specs/Execution/AssertionScopeSpecs.cs @@ -272,7 +272,7 @@ public void ThrowIfAny(IDictionary context) if (failureMessages.Any()) { var builder = new StringBuilder(); - builder.AppendLine(string.Join(Environment.NewLine, failureMessages)); + builder.AppendJoin(Environment.NewLine, failureMessages).AppendLine(); if (context.Any()) { From 1a2b6c79a0cd8673c307523db5b30c5df4623d44 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 10:17:49 +0100 Subject: [PATCH 24/98] Compile-time string concatenation https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA+ABAjABgAQByEAdgMIkDOALgBQCUAsAFADezeHe2+AZhBHgC8eAER8IIgNztOGAOx5xeANSjgAQyhTmAX2bNuecsWr1mbJpzyQTVLrkX8ho8dsuyFS1SI1bpTHSA=== --- Src/FluentAssertions/Collections/GenericCollectionAssertions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs b/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs index 51c472e595..dc7b6fa1c4 100644 --- a/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs +++ b/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs @@ -1140,7 +1140,7 @@ public AndWhichConstraint ContainSingle(Expression { Guard.ThrowIfArgumentIsNull(predicate); - string expectationPrefix = + const string expectationPrefix = "Expected {context:collection} to contain a single item matching {0}{reason}, "; bool success = Execute.Assertion From a6bd17f44e5f8ca388c97f7ecd8a99b726686221 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 10:25:21 +0100 Subject: [PATCH 25/98] String operations with constant comparisonType The JIT can now inline StartsWith and Equals https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AXEBDAzgWwB8ABAJgEYBYAKBuAggBsACAOQgDsBhT3DACmLkADMwBmUbPhispMXAAdsYGAEoaAbxrMdzAMoYoASw4BzHviXHcnZpEvZrnACoBPBTGYBefYZPmIBycOADoAeSgAExNsRgBJUw5oGC48GABubV1iAHZxSWlZaUVlGAB+EINHDFwAdSMMAAt+ACJcVz4YfBCWtDtAqyMbDjcPVW8fQwBXT0JCLN1FnQk5IvklFQqAUQBHKdjcVvbO/F7+oKGXdzUJ5mmMmgBfGjoGFh4OPkERfNW5EpU6moWmoi0gnwwvmMZgsg2G5zhVw83ih/lhjkuoQi0Q4sQSSVgqVwD1B2TyK0K/w25UqGGqdQazTaHQwXR6fXsiJG13GXkmUBmzDmCyWugpMippW2ewORxZXTOnIxw1GNz5dwFJMeQA --- Src/FluentAssertions/CallerIdentifier.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/FluentAssertions/CallerIdentifier.cs b/Src/FluentAssertions/CallerIdentifier.cs index 5ef1a91728..a3452fb59b 100644 --- a/Src/FluentAssertions/CallerIdentifier.cs +++ b/Src/FluentAssertions/CallerIdentifier.cs @@ -153,7 +153,7 @@ private static bool IsCurrentAssembly(StackFrame frame) private static bool IsDotNet(StackFrame frame) { var frameNamespace = frame.GetMethod()?.DeclaringType?.Namespace; - var comparisonType = StringComparison.OrdinalIgnoreCase; + const StringComparison comparisonType = StringComparison.OrdinalIgnoreCase; return frameNamespace?.StartsWith("system.", comparisonType) == true || frameNamespace?.Equals("system", comparisonType) == true; From 5570e1552c22ea41eaefb8c31945f17e9de0fe0f Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 10:42:41 +0100 Subject: [PATCH 26/98] Null coalescing assignment --- Src/FluentAssertions/Common/Services.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Src/FluentAssertions/Common/Services.cs b/Src/FluentAssertions/Common/Services.cs index 740bf428a3..5dd8061ae7 100644 --- a/Src/FluentAssertions/Common/Services.cs +++ b/Src/FluentAssertions/Common/Services.cs @@ -24,12 +24,7 @@ public static Configuration Configuration { lock (Lockable) { - if (configuration is null) - { - configuration = new Configuration(ConfigurationStore); - } - - return configuration; + return configuration ??= new Configuration(ConfigurationStore); } } } From 197ad57030e15a759e77bf5d2bfe7973b06de9f3 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 10:46:07 +0100 Subject: [PATCH 27/98] Make GetConversionOperators private --- Src/FluentAssertions/Common/TypeExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/FluentAssertions/Common/TypeExtensions.cs b/Src/FluentAssertions/Common/TypeExtensions.cs index 3da8b976b0..008e14ec67 100644 --- a/Src/FluentAssertions/Common/TypeExtensions.cs +++ b/Src/FluentAssertions/Common/TypeExtensions.cs @@ -447,7 +447,7 @@ public static ConstructorInfo GetConstructor(this Type type, IEnumerable p .SingleOrDefault(m => m.GetParameters().Select(p => p.ParameterType).SequenceEqual(parameterTypes)); } - public static IEnumerable GetConversionOperators(this Type type, Type sourceType, Type targetType, + private static IEnumerable GetConversionOperators(this Type type, Type sourceType, Type targetType, Func predicate) { return type From abb8bbfd514962a18995ce3240f1ad9f03c6fcb3 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 10:46:54 +0100 Subject: [PATCH 28/98] Target typed new expression --- Build/Build.cs | 2 +- Build/Configuration.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Build/Build.cs b/Build/Build.cs index 5a6c9f77e5..e5c8a6a88e 100644 --- a/Build/Build.cs +++ b/Build/Build.cs @@ -374,7 +374,7 @@ static bool IsDocumentation(string x) => .Select(x => x.Path) .ToArray(); - Repository Repository => new Repository(GitRepository.LocalDirectory); + Repository Repository => new(GitRepository.LocalDirectory); Tree TargetBranch => Repository.Branches[PullRequestBase].Tip.Tree; Tree SourceBranch => Repository.Branches[Repository.Head.FriendlyName].Tip.Tree; diff --git a/Build/Configuration.cs b/Build/Configuration.cs index dd776c5aba..28711f53d9 100644 --- a/Build/Configuration.cs +++ b/Build/Configuration.cs @@ -4,12 +4,12 @@ [TypeConverter(typeof(TypeConverter))] public class Configuration : Enumeration { - public static Configuration Debug = new Configuration { Value = nameof(Debug) }; - public static Configuration Release = new Configuration { Value = nameof(Release) }; - public static Configuration CI = new Configuration { Value = nameof(CI) }; + public static Configuration Debug = new() { Value = nameof(Debug) }; + public static Configuration Release = new() { Value = nameof(Release) }; + public static Configuration CI = new() { Value = nameof(CI) }; public static implicit operator string(Configuration configuration) { return configuration.Value; } -} \ No newline at end of file +} From 9c982f1b3c0edf8340cdfe7c3e6f7808f63ad76b Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 10:59:11 +0100 Subject: [PATCH 29/98] Use char overloads of string.Contains --- .../Equivalency/Ordering/PathBasedOrderingRule.cs | 2 +- .../Equivalency/Selection/SelectMemberByPathSelectionRule.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs b/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs index a9ffc123df..e33b612e7e 100644 --- a/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs +++ b/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs @@ -40,7 +40,7 @@ public OrderStrictness Evaluate(IObjectInfo objectInfo) private static bool ContainsIndexingQualifiers(string path) { - return path.Contains("[", StringComparison.Ordinal) && path.Contains("]", StringComparison.Ordinal); + return path.Contains('[', StringComparison.Ordinal) && path.Contains(']', StringComparison.Ordinal); } private string RemoveInitialIndexQualifier(string sourcePath) diff --git a/Src/FluentAssertions/Equivalency/Selection/SelectMemberByPathSelectionRule.cs b/Src/FluentAssertions/Equivalency/Selection/SelectMemberByPathSelectionRule.cs index ea91c68669..eb4adeeb31 100644 --- a/Src/FluentAssertions/Equivalency/Selection/SelectMemberByPathSelectionRule.cs +++ b/Src/FluentAssertions/Equivalency/Selection/SelectMemberByPathSelectionRule.cs @@ -45,7 +45,7 @@ protected abstract void AddOrRemoveMembersFrom(List selectedMembers, private static bool ContainsIndexingQualifiers(string path) { - return path.Contains("[", StringComparison.Ordinal) && path.Contains("]", StringComparison.Ordinal); + return path.Contains('[', StringComparison.Ordinal) && path.Contains(']', StringComparison.Ordinal); } private static string RemoveIndexQualifiers(string path) From 48aa5902dcbe9fdf4045c050da02955433557893 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 11:00:22 +0100 Subject: [PATCH 30/98] Exception is always non-null here --- Src/FluentAssertions/Specialized/FunctionAssertionHelpers.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Src/FluentAssertions/Specialized/FunctionAssertionHelpers.cs b/Src/FluentAssertions/Specialized/FunctionAssertionHelpers.cs index d40d15548f..968e6c54a4 100644 --- a/Src/FluentAssertions/Specialized/FunctionAssertionHelpers.cs +++ b/Src/FluentAssertions/Specialized/FunctionAssertionHelpers.cs @@ -15,7 +15,6 @@ internal static T NotThrow(Func subject, string because, object[] becauseA catch (Exception exception) { Execute.Assertion - .ForCondition(exception is null) .BecauseOf(because, becauseArgs) .FailWith("Did not expect any exception{reason}, but found {0}.", exception); From ff665e8752879f1b4956668c51df442b6b7ef99d Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 11:01:33 +0100 Subject: [PATCH 31/98] Suppress warning about invalid regex --- .../Primitives/StringAssertionSpecs.MatchRegex.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.MatchRegex.cs b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.MatchRegex.cs index a80ec3e027..a8527618b2 100644 --- a/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.MatchRegex.cs +++ b/Tests/FluentAssertions.Specs/Primitives/StringAssertionSpecs.MatchRegex.cs @@ -347,7 +347,9 @@ public void When_regex_is_invalid_it_fails_and_ignores_occurrences() string subject = "a"; // Act +#pragma warning disable RE0001 // Invalid regex pattern Action act = () => subject.Should().MatchRegex(".**", Exactly.Times(0)); +#pragma warning restore RE0001 // Invalid regex pattern // Assert act.Should().ThrowExactly() From 6b91ad1e60165c1b6e0ef1e0d541e2744c133119 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 11:15:52 +0100 Subject: [PATCH 32/98] Simplify Boolean expression --- Src/FluentAssertions/Primitives/TimeOnlyAssertions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/FluentAssertions/Primitives/TimeOnlyAssertions.cs b/Src/FluentAssertions/Primitives/TimeOnlyAssertions.cs index c1c49fa914..557d089c07 100644 --- a/Src/FluentAssertions/Primitives/TimeOnlyAssertions.cs +++ b/Src/FluentAssertions/Primitives/TimeOnlyAssertions.cs @@ -205,7 +205,7 @@ public AndConstraint NotBeCloseTo(TimeOnly distantTime, TimeSpan pr .ForCondition(Subject is not null) .FailWith("but found .") .Then - .ForCondition(!Subject?.IsCloseTo(distantTime, precision) == true) + .ForCondition(Subject?.IsCloseTo(distantTime, precision) == false) .FailWith("but it was {0}.", Subject) .Then .ClearExpectation(); From 1f97db20ffbf0d80633722cf378e54dd5dbc010c Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 11:33:00 +0100 Subject: [PATCH 33/98] Simplify benchmarks code --- Tests/Benchmarks/Program.cs | 4 +- .../UsersOfGetClosedGenericInterfaces.cs | 134 +++++++----------- 2 files changed, 50 insertions(+), 88 deletions(-) diff --git a/Tests/Benchmarks/Program.cs b/Tests/Benchmarks/Program.cs index 6ff37e86ae..0850181194 100644 --- a/Tests/Benchmarks/Program.cs +++ b/Tests/Benchmarks/Program.cs @@ -17,9 +17,9 @@ public static void Main() new SummaryStyle( cultureInfo: CultureInfo.GetCultureInfo("nl-NL"), printUnitsInHeader: true, - printUnitsInContent: false, + sizeUnit: SizeUnit.KB, timeUnit: TimeUnit.Microsecond, - sizeUnit: SizeUnit.KB + printUnitsInContent: false )); var config = ManualConfig.CreateMinimumViable().AddExporter(exporter); diff --git a/Tests/Benchmarks/UsersOfGetClosedGenericInterfaces.cs b/Tests/Benchmarks/UsersOfGetClosedGenericInterfaces.cs index 5b778fa409..b8167ca9a7 100644 --- a/Tests/Benchmarks/UsersOfGetClosedGenericInterfaces.cs +++ b/Tests/Benchmarks/UsersOfGetClosedGenericInterfaces.cs @@ -91,93 +91,12 @@ public void GlobalSetup() dictionaryStep = new GenericDictionaryEquivalencyStep(); enumerableStep = new GenericEnumerableEquivalencyStep(); - values = new object[ValueCount]; - - var faker = new Faker(); - - faker.Random = new Randomizer(localSeed: 1); - - for (int i = 0; i < values.Length; i++) + var faker = new Faker { - switch (Type.GetTypeCode(DataType)) - { - case TypeCode.DBNull: - values[i] = DBNull.Value; - break; - case TypeCode.Boolean: - values[i] = faker.Random.Bool(); - break; - case TypeCode.Char: - values[i] = faker.Lorem.Letter().Single(); - break; - case TypeCode.SByte: - values[i] = faker.Random.SByte(); - break; - case TypeCode.Byte: - values[i] = faker.Random.Byte(); - break; - case TypeCode.Int16: - values[i] = faker.Random.Short(); - break; - case TypeCode.UInt16: - values[i] = faker.Random.UShort(); - break; - case TypeCode.Int32: - values[i] = faker.Random.Int(); - break; - case TypeCode.UInt32: - values[i] = faker.Random.UInt(); - break; - case TypeCode.Int64: - values[i] = faker.Random.Long(); - break; - case TypeCode.UInt64: - values[i] = faker.Random.ULong(); - break; - case TypeCode.Single: - values[i] = faker.Random.Float(); - break; - case TypeCode.Double: - values[i] = faker.Random.Double(); - break; - case TypeCode.Decimal: - values[i] = faker.Random.Decimal(); - break; - case TypeCode.DateTime: - values[i] = faker.Date.Between(DateTime.UtcNow.AddDays(-30), DateTime.UtcNow.AddDays(+30)); - break; - case TypeCode.String: - values[i] = faker.Lorem.Lines(1); - break; - - default: - { - if (DataType == typeof(TimeSpan)) - { - values[i] = faker.Date.Future() - faker.Date.Future(); - } - else if (DataType == typeof(Guid)) - { - values[i] = faker.Random.Guid(); - } - else if (DataType == typeof(Dictionary)) - { - values[i] = new Dictionary - { { faker.Random.Int(), faker.Random.Int() } }; - } - else if (DataType == typeof(IEnumerable)) - { - values[i] = new[] { faker.Random.Int(), faker.Random.Int() }; - } - else - { - throw new Exception("Unable to populate data of type " + DataType); - } - - break; - } - } - } + Random = new Randomizer(localSeed: 1) + }; + + values = Enumerable.Range(0, ValueCount).Select(_ => CreateValue(faker)).ToArray(); context = new Context { @@ -185,6 +104,49 @@ public void GlobalSetup() }; } + private object CreateValue(Faker faker) => Type.GetTypeCode(DataType) switch + { + TypeCode.DBNull => DBNull.Value, + TypeCode.Boolean => faker.Random.Bool(), + TypeCode.Char => faker.Lorem.Letter().Single(), + TypeCode.SByte => faker.Random.SByte(), + TypeCode.Byte => faker.Random.Byte(), + TypeCode.Int16 => faker.Random.Short(), + TypeCode.UInt16 => faker.Random.UShort(), + TypeCode.Int32 => faker.Random.Int(), + TypeCode.UInt32 => faker.Random.UInt(), + TypeCode.Int64 => faker.Random.Long(), + TypeCode.UInt64 => faker.Random.ULong(), + TypeCode.Single => faker.Random.Float(), + TypeCode.Double => faker.Random.Double(), + TypeCode.Decimal => faker.Random.Decimal(), + TypeCode.DateTime => faker.Date.Between(DateTime.UtcNow.AddDays(-30), DateTime.UtcNow.AddDays(+30)), + TypeCode.String => faker.Lorem.Lines(1), + _ => CustomValue(faker), + }; + + private object CustomValue(Faker faker) + { + if (DataType == typeof(TimeSpan)) + { + return faker.Date.Future() - faker.Date.Future(); + } + else if (DataType == typeof(Guid)) + { + return faker.Random.Guid(); + } + else if (DataType == typeof(Dictionary)) + { + return new Dictionary { { faker.Random.Int(), faker.Random.Int() } }; + } + else if (DataType == typeof(IEnumerable)) + { + return new[] { faker.Random.Int(), faker.Random.Int() }; + } + + throw new Exception("Unable to populate data of type " + DataType); + } + [Benchmark] public void GenericDictionaryEquivalencyStep_CanHandle() { From 1412593afabf8f1104c91d50b41c08960fccc6ba Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 11:34:15 +0100 Subject: [PATCH 34/98] Use collection initializer --- Tests/FluentAssertions.Equivalency.Specs/DataRowSpecs.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Tests/FluentAssertions.Equivalency.Specs/DataRowSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/DataRowSpecs.cs index 1539c836e0..6e561ded69 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/DataRowSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/DataRowSpecs.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Data; using System.Linq; using FluentAssertions.Execution; @@ -518,10 +517,7 @@ public void When_data_row_data_has_none_of_the_columns_being_asserted_then_it_sh var dataRow = dataSet.TypedDataTable1[0]; - var columnNames = new List(); - - columnNames.Add("Unicorn"); - columnNames.Add("Dragon"); + var columnNames = new[] { "Unicorn", "Dragon" }; // Act Action action = From 469ee76433f943f28dc439bfe70bd2975749afed Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 12:17:58 +0100 Subject: [PATCH 35/98] Silence CA1508 false positive The analyzer cannot take multi-threading into account, so it thinks that this.cleanup is *always* non-null inside the if. https://github.com/dotnet/roslyn-analyzers/issues/1649 --- Src/FluentAssertions/Events/EventRecorder.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Src/FluentAssertions/Events/EventRecorder.cs b/Src/FluentAssertions/Events/EventRecorder.cs index 4fa3410cae..11933f1fd2 100644 --- a/Src/FluentAssertions/Events/EventRecorder.cs +++ b/Src/FluentAssertions/Events/EventRecorder.cs @@ -65,9 +65,10 @@ public void Attach(WeakReference subject, EventInfo eventInfo) public void Dispose() { - if (cleanup is not null) + Action localCleanup = cleanup; + if (localCleanup is not null) { - cleanup?.Invoke(); + localCleanup(); cleanup = null; EventObject = null; raisedEvents.Dispose(); From 0c63333e0d3a281a92279f9ad1a4b37d7791ba7d Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 12:39:27 +0100 Subject: [PATCH 36/98] Ensure single enumeration of `members` --- .../Equivalency/Steps/DataRowEquivalencyStep.cs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs index fedad03d3b..f4214668b7 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs @@ -195,9 +195,9 @@ private static SelectedDataRowMembers GetMembersFromExpectation(Comparands compa { var cacheKey = (comparands.CompileTimeType, comparands.RuntimeType, config); - if (!SelectedMembersCache.TryGetValue(cacheKey, out SelectedDataRowMembers selectedMembers)) + if (!SelectedMembersCache.TryGetValue(cacheKey, out SelectedDataRowMembers selectedDataRowMembers)) { - var members = Enumerable.Empty(); + IEnumerable members = Enumerable.Empty(); foreach (IMemberSelectionRule rule in config.SelectionRules) { @@ -205,15 +205,17 @@ private static SelectedDataRowMembers GetMembersFromExpectation(Comparands compa new MemberSelectionContext(comparands.CompileTimeType, comparands.RuntimeType, config)); } - selectedMembers = new SelectedDataRowMembers + IMember[] selectedMembers = members.ToArray(); + + selectedDataRowMembers = new SelectedDataRowMembers { - HasErrors = members.Any(m => m.Name == nameof(DataRow.HasErrors)), - RowState = members.Any(m => m.Name == nameof(DataRow.RowState)) + HasErrors = selectedMembers.Any(m => m.Name == nameof(DataRow.HasErrors)), + RowState = selectedMembers.Any(m => m.Name == nameof(DataRow.RowState)) }; - SelectedMembersCache.TryAdd(cacheKey, selectedMembers); + SelectedMembersCache.TryAdd(cacheKey, selectedDataRowMembers); } - return selectedMembers; + return selectedDataRowMembers; } } From a8830b8a07a8f349f80fd40735d0752b37c05cca Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 12:44:11 +0100 Subject: [PATCH 37/98] Match parameter name of base type --- .../Matching/MustMatchByNameRule.cs | 10 +++++----- .../Equivalency/Matching/TryMatchByNameRule.cs | 2 +- ...SelfReferenceEquivalencyAssertionOptions.cs | 18 +++++++++--------- Tests/UWP.Specs/App.xaml.cs | 4 ++-- Tests/UWP.Specs/Properties/AssemblyInfo.cs | 1 - 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/Src/FluentAssertions/Equivalency/Matching/MustMatchByNameRule.cs b/Src/FluentAssertions/Equivalency/Matching/MustMatchByNameRule.cs index 0f804c1024..0c1e572187 100644 --- a/Src/FluentAssertions/Equivalency/Matching/MustMatchByNameRule.cs +++ b/Src/FluentAssertions/Equivalency/Matching/MustMatchByNameRule.cs @@ -9,23 +9,23 @@ namespace FluentAssertions.Equivalency.Matching; /// IEquivalencyAssertionOptions.SelectionRules public bool? CompareRecordsByValue => compareRecordsByValue; - EqualityStrategy IEquivalencyAssertionOptions.GetEqualityStrategy(Type requestedType) + EqualityStrategy IEquivalencyAssertionOptions.GetEqualityStrategy(Type type) { // As the valueFactory parameter captures instance members, // be aware if the cache must be cleared on mutating the members. - return equalityStrategyCache.GetOrAdd(requestedType, type => + return equalityStrategyCache.GetOrAdd(type, typeKey => { EqualityStrategy strategy; - if (!type.IsPrimitive && referenceTypes.Count > 0 && referenceTypes.Any(t => type.IsSameOrInherits(t))) + if (!typeKey.IsPrimitive && referenceTypes.Count > 0 && referenceTypes.Any(t => typeKey.IsSameOrInherits(t))) { strategy = EqualityStrategy.ForceMembers; } - else if (valueTypes.Count > 0 && valueTypes.Any(t => type.IsSameOrInherits(t))) + else if (valueTypes.Count > 0 && valueTypes.Any(t => typeKey.IsSameOrInherits(t))) { strategy = EqualityStrategy.ForceEquals; } - else if (!type.IsPrimitive && referenceTypes.Count > 0 && referenceTypes.Any(t => type.IsAssignableToOpenGeneric(t))) + else if (!typeKey.IsPrimitive && referenceTypes.Count > 0 && referenceTypes.Any(t => typeKey.IsAssignableToOpenGeneric(t))) { strategy = EqualityStrategy.ForceMembers; } - else if (valueTypes.Count > 0 && valueTypes.Any(t => type.IsAssignableToOpenGeneric(t))) + else if (valueTypes.Count > 0 && valueTypes.Any(t => typeKey.IsAssignableToOpenGeneric(t))) { strategy = EqualityStrategy.ForceEquals; } - else if ((compareRecordsByValue.HasValue || getDefaultEqualityStrategy is null) && type.IsRecord()) + else if ((compareRecordsByValue.HasValue || getDefaultEqualityStrategy is null) && typeKey.IsRecord()) { strategy = compareRecordsByValue is true ? EqualityStrategy.ForceEquals : EqualityStrategy.ForceMembers; } @@ -210,11 +210,11 @@ EqualityStrategy IEquivalencyAssertionOptions.GetEqualityStrategy(Type requested { if (getDefaultEqualityStrategy is not null) { - strategy = getDefaultEqualityStrategy(type); + strategy = getDefaultEqualityStrategy(typeKey); } else { - strategy = type.HasValueSemantics() ? EqualityStrategy.Equals : EqualityStrategy.Members; + strategy = typeKey.HasValueSemantics() ? EqualityStrategy.Equals : EqualityStrategy.Members; } } diff --git a/Tests/UWP.Specs/App.xaml.cs b/Tests/UWP.Specs/App.xaml.cs index 2ead019670..0b335f4e45 100644 --- a/Tests/UWP.Specs/App.xaml.cs +++ b/Tests/UWP.Specs/App.xaml.cs @@ -16,7 +16,7 @@ public App() Suspending += OnSuspending; } - protected override void OnLaunched(LaunchActivatedEventArgs e) + protected override void OnLaunched(LaunchActivatedEventArgs args) { if (Window.Current.Content is not Frame rootFrame) { @@ -25,7 +25,7 @@ protected override void OnLaunched(LaunchActivatedEventArgs e) Window.Current.Content = rootFrame; } - UnitTestClient.Run(e.Arguments); + UnitTestClient.Run(args.Arguments); } private void OnNavigationFailed(object sender, NavigationFailedEventArgs e) => diff --git a/Tests/UWP.Specs/Properties/AssemblyInfo.cs b/Tests/UWP.Specs/Properties/AssemblyInfo.cs index a430f052f9..bccfd85910 100644 --- a/Tests/UWP.Specs/Properties/AssemblyInfo.cs +++ b/Tests/UWP.Specs/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; [assembly: AssemblyTitle("UWP.Specs")] From 087e83a95b929aefcec90d559555697a7e9171ea Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 12:50:27 +0100 Subject: [PATCH 38/98] Use private protected --- .../Equivalency/SelfReferenceEquivalencyAssertionOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs b/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs index a794036032..22af9a1f1f 100644 --- a/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs +++ b/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs @@ -64,7 +64,7 @@ public abstract class SelfReferenceEquivalencyAssertionOptions : IEquival #endregion - internal SelfReferenceEquivalencyAssertionOptions() + private protected SelfReferenceEquivalencyAssertionOptions() { AddMatchingRule(new MustMatchByNameRule()); From d4cb70ab4d9737084093f205b21925890dabd821 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 4 Mar 2023 12:55:43 +0100 Subject: [PATCH 39/98] Avoid multiple enumerations of enumerables --- .../Collections/GenericDictionaryAssertions.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs b/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs index 90dd3811de..2ae317b7e6 100644 --- a/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs +++ b/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs @@ -401,11 +401,11 @@ public AndConstraint NotContainKeys(IEnumerable unexpected, bool success = Execute.Assertion .ForCondition(Subject is not null) .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} to not contain keys {0}{reason}, but found .", unexpected); + .FailWith("Expected {context:dictionary} to not contain keys {0}{reason}, but found .", unexpectedKeys); if (success) { - IEnumerable foundKeys = unexpected.Where(key => ContainsKey(Subject, key)); + IEnumerable foundKeys = unexpectedKeys.Where(key => ContainsKey(Subject, key)); if (foundKeys.Any()) { @@ -414,14 +414,14 @@ public AndConstraint NotContainKeys(IEnumerable unexpected, Execute.Assertion .BecauseOf(because, becauseArgs) .FailWith("Expected {context:dictionary} {0} to not contain keys {1}{reason}, but found {2}.", Subject, - unexpected, foundKeys); + unexpectedKeys, foundKeys); } else { Execute.Assertion .BecauseOf(because, becauseArgs) .FailWith("Expected {context:dictionary} {0} to not contain key {1}{reason}.", Subject, - unexpected.First()); + unexpectedKeys.First()); } } } From 527b98a3536fe1a3f0a649f4f607cce3245d7e77 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sun, 5 Mar 2023 09:35:32 +0100 Subject: [PATCH 40/98] Seal disposable types Unsealed disposable types should expose a virtual Dispose method for child types to override. --- Src/FluentAssertions/Common/Iterator.cs | 2 +- Src/FluentAssertions/Common/StopwatchTimer.cs | 2 +- Src/FluentAssertions/Disposable.cs | 2 +- Src/FluentAssertions/Events/EventMonitor.cs | 2 +- .../Collections/CollectionAssertionSpecs.BeEmpty.cs | 4 ++-- .../Collections/CollectionAssertionSpecs.cs | 4 ++-- .../Collections/GenericDictionaryAssertionSpecs.cs | 2 +- .../FluentAssertions.Specs/Primitives/ObjectAssertionSpecs.cs | 2 +- Tests/FluentAssertions.Specs/TestTimer.cs | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Src/FluentAssertions/Common/Iterator.cs b/Src/FluentAssertions/Common/Iterator.cs index 064a5db2b2..0ee86c231d 100644 --- a/Src/FluentAssertions/Common/Iterator.cs +++ b/Src/FluentAssertions/Common/Iterator.cs @@ -8,7 +8,7 @@ namespace FluentAssertions.Common; /// A smarter enumerator that can provide information about the relative location (current, first, last) /// of the current item within the collection without unnecessarily iterating the collection. /// -internal class Iterator : IEnumerator +internal sealed class Iterator : IEnumerator { private const int InitialIndex = -1; private readonly IEnumerable enumerable; diff --git a/Src/FluentAssertions/Common/StopwatchTimer.cs b/Src/FluentAssertions/Common/StopwatchTimer.cs index eea7353434..bb81266cbb 100644 --- a/Src/FluentAssertions/Common/StopwatchTimer.cs +++ b/Src/FluentAssertions/Common/StopwatchTimer.cs @@ -3,7 +3,7 @@ namespace FluentAssertions.Common; -internal class StopwatchTimer : ITimer +internal sealed class StopwatchTimer : ITimer { private readonly Stopwatch stopwatch; diff --git a/Src/FluentAssertions/Disposable.cs b/Src/FluentAssertions/Disposable.cs index 1a7bbb875b..ac98c8167a 100644 --- a/Src/FluentAssertions/Disposable.cs +++ b/Src/FluentAssertions/Disposable.cs @@ -2,7 +2,7 @@ namespace FluentAssertions; -internal class Disposable : IDisposable +internal sealed class Disposable : IDisposable { private readonly Action action; diff --git a/Src/FluentAssertions/Events/EventMonitor.cs b/Src/FluentAssertions/Events/EventMonitor.cs index d23458af63..e378cdb796 100644 --- a/Src/FluentAssertions/Events/EventMonitor.cs +++ b/Src/FluentAssertions/Events/EventMonitor.cs @@ -12,7 +12,7 @@ namespace FluentAssertions.Events; /// -internal class EventMonitor /// Tracks the events an object raises. /// : IMonitor +internal sealed class EventMonitor : IMonitor { private readonly WeakReference subject; diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeEmpty.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeEmpty.cs index e8fa188b34..4274caa438 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeEmpty.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeEmpty.cs @@ -181,14 +181,14 @@ public void When_asserting_collection_to_be_not_empty_it_should_enumerate_only_o } } - private class InfiniteEnumerable : IEnumerable + private sealed class InfiniteEnumerable : IEnumerable { public IEnumerator GetEnumerator() => new InfiniteEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } - private class InfiniteEnumerator : IEnumerator + private sealed class InfiniteEnumerator : IEnumerator { public bool MoveNext() => true; diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.cs index cfc7921940..c27cf22cfb 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.cs @@ -293,7 +293,7 @@ public int Count public bool IsReadOnly { get; private set; } } -internal class TrackingTestEnumerable : IEnumerable +internal sealed class TrackingTestEnumerable : IEnumerable { private readonly int[] values; @@ -315,7 +315,7 @@ public IEnumerator GetEnumerator() IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } -internal class TrackingEnumerator : IEnumerator +internal sealed class TrackingEnumerator : IEnumerator { private readonly int[] values; private int index; diff --git a/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs index f06fc95cb3..536d660726 100644 --- a/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Collections/GenericDictionaryAssertionSpecs.cs @@ -3011,7 +3011,7 @@ public ICollection Values } } -internal class TrackingDictionaryEnumerator : IEnumerator> +internal sealed class TrackingDictionaryEnumerator : IEnumerator> { private readonly KeyValuePair[] values; private int index; diff --git a/Tests/FluentAssertions.Specs/Primitives/ObjectAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Primitives/ObjectAssertionSpecs.cs index 342224cf15..a12fe9e52f 100644 --- a/Tests/FluentAssertions.Specs/Primitives/ObjectAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Primitives/ObjectAssertionSpecs.cs @@ -1331,7 +1331,7 @@ internal class DummyBaseClass { } -internal class DummyImplementingClass : DummyBaseClass, IDisposable +internal sealed class DummyImplementingClass : DummyBaseClass, IDisposable { public void Dispose() { diff --git a/Tests/FluentAssertions.Specs/TestTimer.cs b/Tests/FluentAssertions.Specs/TestTimer.cs index 5fd8db0fe0..575249bc84 100644 --- a/Tests/FluentAssertions.Specs/TestTimer.cs +++ b/Tests/FluentAssertions.Specs/TestTimer.cs @@ -3,7 +3,7 @@ namespace FluentAssertions.Specs; -internal class TestTimer : ITimer +internal sealed class TestTimer : ITimer { private readonly Func getElapsed; From 8988a8a35e61c4308e46ca9d401709f6c6069ce4 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sun, 5 Mar 2023 09:36:33 +0100 Subject: [PATCH 41/98] Simplify using statement --- .../Execution/AssertionScopeSpecs.cs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/Tests/FluentAssertions.Specs/Execution/AssertionScopeSpecs.cs b/Tests/FluentAssertions.Specs/Execution/AssertionScopeSpecs.cs index 4c6261afa2..cd72bf30e3 100644 --- a/Tests/FluentAssertions.Specs/Execution/AssertionScopeSpecs.cs +++ b/Tests/FluentAssertions.Specs/Execution/AssertionScopeSpecs.cs @@ -240,18 +240,16 @@ public void When_using_a_custom_strategy_it_should_include_failure_messages_of_a public void When_nested_scope_is_disposed_it_passes_reports_to_parent_scope() { // Arrange/Act - using (var outerScope = new AssertionScope()) - { - outerScope.AddReportable("outerReportable", "foo"); - - using (var innerScope = new AssertionScope()) - { - innerScope.AddReportable("innerReportable", "bar"); - } + using var outerScope = new AssertionScope(); + outerScope.AddReportable("outerReportable", "foo"); - // Assert - outerScope.Get("innerReportable").Should().Be("bar"); + using (var innerScope = new AssertionScope()) + { + innerScope.AddReportable("innerReportable", "bar"); } + + // Assert + outerScope.Get("innerReportable").Should().Be("bar"); } public class CustomAssertionStrategy : IAssertionStrategy From 2f4f20a0658781cedab8f77c8c6b9508966ce6f4 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sun, 5 Mar 2023 12:20:54 +0100 Subject: [PATCH 42/98] Use Enumerable/Array.Empty to reduce allocations Fixes CA1825 --- .../Collections/GenericCollectionAssertions.cs | 12 ++++++------ .../Common/FullFrameworkReflector.cs | 4 ++-- .../Equivalency/Steps/AssertionResultSet.cs | 3 ++- .../Equivalency/Steps/DictionaryInterfaceInfo.cs | 2 +- .../Execution/DefaultAssertionStrategy.cs | 5 +++-- Src/FluentAssertions/Execution/GivenSelector.cs | 2 +- Src/FluentAssertions/Types/MemberInfoAssertions.cs | 2 +- Src/FluentAssertions/Types/TypeAssertions.cs | 4 ++-- 8 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs b/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs index dc7b6fa1c4..57cce3e30d 100644 --- a/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs +++ b/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs @@ -71,7 +71,7 @@ public AndWhichConstraint> AllBeAssignabl .FailWith("Expected type to be {0}{reason}, but found {context:the collection} is .", typeof(TExpectation).FullName); - IEnumerable matches = new TExpectation[0]; + IEnumerable matches = Enumerable.Empty(); if (success) { @@ -218,7 +218,7 @@ public AndWhichConstraint> AllBeOfType.", typeof(TExpectation).FullName); - IEnumerable matches = new TExpectation[0]; + IEnumerable matches = Enumerable.Empty(); if (success) { @@ -701,7 +701,7 @@ public AndWhichConstraint Contain(T expected, string because = " .ForCondition(Subject is not null) .FailWith("Expected {context:collection} to contain {0}{reason}, but found .", expected); - IEnumerable matches = new T[0]; + IEnumerable matches = Enumerable.Empty(); if (success) { @@ -740,7 +740,7 @@ public AndWhichConstraint Contain(Expression> pred .ForCondition(Subject is not null) .FailWith("Expected {context:collection} to contain {0}{reason}, but found .", predicate.Body); - IEnumerable matches = new T[0]; + IEnumerable matches = Enumerable.Empty(); if (success) { @@ -1148,7 +1148,7 @@ public AndWhichConstraint ContainSingle(Expression .ForCondition(Subject is not null) .FailWith(expectationPrefix + "but found .", predicate); - T[] matches = new T[0]; + T[] matches = Array.Empty(); if (success) { @@ -2134,7 +2134,7 @@ public AndWhichConstraint NotContain(T unexpected, string becaus .ForCondition(Subject is not null) .FailWith("Expected {context:collection} to not contain {0}{reason}, but found .", unexpected); - IEnumerable matched = new T[0]; + IEnumerable matched = Enumerable.Empty(); if (success) { diff --git a/Src/FluentAssertions/Common/FullFrameworkReflector.cs b/Src/FluentAssertions/Common/FullFrameworkReflector.cs index 6f4f5d58d5..3c54cbe1d3 100644 --- a/Src/FluentAssertions/Common/FullFrameworkReflector.cs +++ b/Src/FluentAssertions/Common/FullFrameworkReflector.cs @@ -47,11 +47,11 @@ private static IEnumerable GetExportedTypes(Assembly assembly) } catch (FileLoadException) { - return new Type[0]; + return Enumerable.Empty(); } catch (Exception) { - return new Type[0]; + return Array.Empty(); } } } diff --git a/Src/FluentAssertions/Equivalency/Steps/AssertionResultSet.cs b/Src/FluentAssertions/Equivalency/Steps/AssertionResultSet.cs index 9e27975e54..0185c1329d 100644 --- a/Src/FluentAssertions/Equivalency/Steps/AssertionResultSet.cs +++ b/Src/FluentAssertions/Equivalency/Steps/AssertionResultSet.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using FluentAssertions.Execution; @@ -32,7 +33,7 @@ public string[] SelectClosestMatchFor(object key = null) { if (ContainsSuccessfulSet()) { - return new string[0]; + return Array.Empty(); } KeyValuePair[] bestResultSets = GetBestResultSets(); diff --git a/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs b/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs index d7506b3fed..64af83c60a 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs @@ -100,7 +100,7 @@ private static DictionaryInterfaceInfo[] GetDictionaryInterfacesFrom(Type target { if (Type.GetTypeCode(key) != TypeCode.Object) { - return new DictionaryInterfaceInfo[0]; + return Array.Empty(); } else { diff --git a/Src/FluentAssertions/Execution/DefaultAssertionStrategy.cs b/Src/FluentAssertions/Execution/DefaultAssertionStrategy.cs index 7e404e102d..3af8859666 100644 --- a/Src/FluentAssertions/Execution/DefaultAssertionStrategy.cs +++ b/Src/FluentAssertions/Execution/DefaultAssertionStrategy.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using FluentAssertions.Common; @@ -12,7 +13,7 @@ public IEnumerable FailureMessages { get { - return new string[0]; + return Array.Empty(); } } @@ -29,7 +30,7 @@ public void HandleFailure(string message) /// public IEnumerable DiscardFailures() { - return new string[0]; + return Array.Empty(); } /// diff --git a/Src/FluentAssertions/Execution/GivenSelector.cs b/Src/FluentAssertions/Execution/GivenSelector.cs index d1a4d3ce0c..b2d776fb26 100644 --- a/Src/FluentAssertions/Execution/GivenSelector.cs +++ b/Src/FluentAssertions/Execution/GivenSelector.cs @@ -62,7 +62,7 @@ public GivenSelector Given(Func selector) /// public ContinuationOfGiven FailWith(string message) { - return FailWith(message, new object[0]); + return FailWith(message, Array.Empty()); } /// diff --git a/Src/FluentAssertions/Types/MemberInfoAssertions.cs b/Src/FluentAssertions/Types/MemberInfoAssertions.cs index e57dbdd9a5..97d80fccb2 100644 --- a/Src/FluentAssertions/Types/MemberInfoAssertions.cs +++ b/Src/FluentAssertions/Types/MemberInfoAssertions.cs @@ -86,7 +86,7 @@ public AndWhichConstraint, TAttribut $"Expected {Identifier} to be decorated with {typeof(TAttribute)}{{reason}}" + ", but {context:member} is ."); - IEnumerable attributes = new TAttribute[0]; + IEnumerable attributes = Array.Empty(); if (success) { diff --git a/Src/FluentAssertions/Types/TypeAssertions.cs b/Src/FluentAssertions/Types/TypeAssertions.cs index 120f9c0bb8..2c8c577072 100644 --- a/Src/FluentAssertions/Types/TypeAssertions.cs +++ b/Src/FluentAssertions/Types/TypeAssertions.cs @@ -1457,7 +1457,7 @@ public AndWhichConstraint HaveConstructor( public AndWhichConstraint HaveDefaultConstructor( string because = "", params object[] becauseArgs) { - return HaveConstructor(new Type[0], because, becauseArgs); + return HaveConstructor(Array.Empty(), because, becauseArgs); } /// private protected async Task @@ -1514,7 +1514,7 @@ public AndWhichConstraint NotHaveConstructor( public AndWhichConstraint NotHaveDefaultConstructor( string because = "", params object[] becauseArgs) { - return NotHaveConstructor(new Type[0], because, becauseArgs); + return NotHaveConstructor(Array.Empty(), because, becauseArgs); } private static string GetParameterString(IEnumerable parameterTypes) From 72203d731ca05863b008c2e486cad0d45bafe222 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sun, 5 Mar 2023 14:20:03 +0100 Subject: [PATCH 43/98] Use lambda expressions --- Tests/FluentAssertions.Specs/AndWhichConstraintSpecs.cs | 5 +---- Tests/FluentAssertions.Specs/AssertionOptionsSpecs.cs | 8 ++++---- .../GenericCollectionAssertionOfStringSpecs.cs | 5 +---- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Tests/FluentAssertions.Specs/AndWhichConstraintSpecs.cs b/Tests/FluentAssertions.Specs/AndWhichConstraintSpecs.cs index 9181c1e887..b102f96dc4 100644 --- a/Tests/FluentAssertions.Specs/AndWhichConstraintSpecs.cs +++ b/Tests/FluentAssertions.Specs/AndWhichConstraintSpecs.cs @@ -14,10 +14,7 @@ public void When_many_objects_are_provided_accessing_which_should_throw_a_descri var continuation = new AndWhichConstraint(null, new[] { "hello", "world" }); // Act - Action act = () => - { - _ = continuation.Which; - }; + Action act = () => _ = continuation.Which; // Assert act.Should().Throw() diff --git a/Tests/FluentAssertions.Specs/AssertionOptionsSpecs.cs b/Tests/FluentAssertions.Specs/AssertionOptionsSpecs.cs index 7e8af5a9c9..11738e3966 100644 --- a/Tests/FluentAssertions.Specs/AssertionOptionsSpecs.cs +++ b/Tests/FluentAssertions.Specs/AssertionOptionsSpecs.cs @@ -35,7 +35,7 @@ public class When_injecting_a_null_configurer : GivenSubject { return () => AssertionOptions.AssertEquivalencyUsing(defaultsConfigurer: null); }); + When(() => () => AssertionOptions.AssertEquivalencyUsing(defaultsConfigurer: null)); } [Fact] @@ -80,7 +80,7 @@ public When_modifying_global_reference_type_settings_a_previous_assertion_should new MyValueType { Value = 1 }.Should().BeEquivalentTo(new MyValueType { Value = 2 }); }); - When(() => { AssertionOptions.AssertEquivalencyUsing(o => o.ComparingByMembers()); }); + When(() => AssertionOptions.AssertEquivalencyUsing(o => o.ComparingByMembers())); } [Fact] @@ -113,7 +113,7 @@ public When_modifying_global_value_type_settings_a_previous_assertion_should_not new MyClass { Value = 1 }.Should().BeEquivalentTo(new MyClass { Value = 1 }); }); - When(() => { AssertionOptions.AssertEquivalencyUsing(o => o.ComparingByValue()); }); + When(() => AssertionOptions.AssertEquivalencyUsing(o => o.ComparingByValue())); } [Fact] @@ -388,7 +388,7 @@ public class When_global_formatting_settings_are_modified : GivenWhenThen public When_global_formatting_settings_are_modified() { - Given(() => { oldSettings = AssertionOptions.FormattingOptions.Clone(); }); + Given(() => oldSettings = AssertionOptions.FormattingOptions.Clone()); When(() => { diff --git a/Tests/FluentAssertions.Specs/Collections/GenericCollectionAssertionOfStringSpecs.cs b/Tests/FluentAssertions.Specs/Collections/GenericCollectionAssertionOfStringSpecs.cs index 91fe66cc84..b03855eb1c 100644 --- a/Tests/FluentAssertions.Specs/Collections/GenericCollectionAssertionOfStringSpecs.cs +++ b/Tests/FluentAssertions.Specs/Collections/GenericCollectionAssertionOfStringSpecs.cs @@ -1726,10 +1726,7 @@ public void When_collection_contains_multiple_matches_which_should_throw() IEnumerable collection = new[] { "build succeded", "test failed", "pack failed" }; // Act - Action action = () => - { - _ = collection.Should().ContainMatch("* failed").Which; - }; + Action action = () => _ = collection.Should().ContainMatch("* failed").Which; // Assert action.Should().Throw() From 1bdffbab2109a4aedcc2b605a827d89002e343a2 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sun, 5 Mar 2023 14:25:42 +0100 Subject: [PATCH 44/98] Add newline after closing brace --- Tests/Approval.Tests/ApiApproval.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Tests/Approval.Tests/ApiApproval.cs b/Tests/Approval.Tests/ApiApproval.cs index a1dfc01e04..a1f0bbd9ca 100644 --- a/Tests/Approval.Tests/ApiApproval.cs +++ b/Tests/Approval.Tests/ApiApproval.cs @@ -67,6 +67,7 @@ public static Task OnlyIncludeChanges(string received, string ver // omit unchanged files continue; } + builder.AppendLine(line.Text); } From c01ef4dc6ff7d7d06deb0046a6f7bd451db47b97 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sun, 5 Mar 2023 14:29:21 +0100 Subject: [PATCH 45/98] Silence CA1720 CA1720: Identifiers should not contain type names --- .../CyclicReferencesSpecs.cs | 8 ++++---- Tests/FluentAssertions.Equivalency.Specs/TestTypes.cs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs index b7597b2b87..9830e59ab1 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs @@ -157,23 +157,23 @@ public void When_the_graph_contains_the_same_value_object_it_should_not_be_treat // Arrange var actual = new CyclicRootWithValueObject { - Object = new ValueObject("MyValue") + Value = new ValueObject("MyValue") }; actual.Level = new CyclicLevelWithValueObject { - Object = new ValueObject("MyValue"), + Value = new ValueObject("MyValue"), Root = null }; var expectation = new CyclicRootWithValueObject { - Object = new ValueObject("MyValue") + Value = new ValueObject("MyValue") }; expectation.Level = new CyclicLevelWithValueObject { - Object = new ValueObject("MyValue"), + Value = new ValueObject("MyValue"), Root = null }; diff --git a/Tests/FluentAssertions.Equivalency.Specs/TestTypes.cs b/Tests/FluentAssertions.Equivalency.Specs/TestTypes.cs index 1d0a87476e..75f378f4b5 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/TestTypes.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/TestTypes.cs @@ -572,7 +572,7 @@ public class CyclicRoot public class CyclicRootWithValueObject { - public ValueObject Object { get; set; } + public ValueObject Value { get; set; } public CyclicLevelWithValueObject Level { get; set; } } @@ -606,7 +606,7 @@ public class CyclicLevel1 public class CyclicLevelWithValueObject { - public ValueObject Object { get; set; } + public ValueObject Value { get; set; } public CyclicRootWithValueObject Root { get; set; } } From e0bbe77af66001a8cc46a897a557418378eda6ef Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sun, 5 Mar 2023 14:42:19 +0100 Subject: [PATCH 46/98] Simplify object initialization --- .../CyclicReferencesSpecs.cs | 44 +++++++++---------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs index 9830e59ab1..ef92dce8dd 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs @@ -123,25 +123,23 @@ public void When_validating_nested_properties_that_are_null_it_should_not_throw_ { // Arrange var actual = new CyclicRoot - { - Text = null - }; - - actual.Level = new CyclicLevel1 { Text = null, - Root = null + Level = new CyclicLevel1 + { + Text = null, + Root = null + } }; var expectation = new CyclicRootDto - { - Text = null - }; - - expectation.Level = new CyclicLevel1Dto { Text = null, - Root = null + Level = new CyclicLevel1Dto + { + Text = null, + Root = null + } }; // Act @@ -156,25 +154,23 @@ public void When_the_graph_contains_the_same_value_object_it_should_not_be_treat { // Arrange var actual = new CyclicRootWithValueObject - { - Value = new ValueObject("MyValue") - }; - - actual.Level = new CyclicLevelWithValueObject { Value = new ValueObject("MyValue"), - Root = null + Level = new CyclicLevelWithValueObject + { + Value = new ValueObject("MyValue"), + Root = null + } }; var expectation = new CyclicRootWithValueObject - { - Value = new ValueObject("MyValue") - }; - - expectation.Level = new CyclicLevelWithValueObject { Value = new ValueObject("MyValue"), - Root = null + Level = new CyclicLevelWithValueObject + { + Value = new ValueObject("MyValue"), + Root = null + } }; // Act From 612342ce5304759ae9bba3313940744070155549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=BCtzmacher?= Date: Sun, 19 Feb 2023 12:43:11 +0100 Subject: [PATCH 47/98] Introduce ThrowWithinAsync --- .../Specialized/AsyncFunctionAssertions.cs | 116 ++++++- .../Specialized/DelegateAssertionsBase.cs | 11 +- .../FluentAssertions/net47.verified.txt | 2 + .../FluentAssertions/net6.0.verified.txt | 2 + .../netcoreapp2.1.verified.txt | 2 + .../netcoreapp3.0.verified.txt | 2 + .../netstandard2.0.verified.txt | 2 + .../netstandard2.1.verified.txt | 2 + .../Specialized/TaskAssertionSpecs.cs | 285 +++++++++++++++++- docs/_pages/executiontime.md | 1 + docs/_pages/releases.md | 1 + 11 files changed, 415 insertions(+), 11 deletions(-) diff --git a/Src/FluentAssertions/Specialized/AsyncFunctionAssertions.cs b/Src/FluentAssertions/Specialized/AsyncFunctionAssertions.cs index aaf0233e31..e7f0c24db3 100644 --- a/Src/FluentAssertions/Specialized/AsyncFunctionAssertions.cs +++ b/Src/FluentAssertions/Specialized/AsyncFunctionAssertions.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using System.Linq; using System.Threading; using System.Threading.Tasks; using FluentAssertions.Common; @@ -180,6 +181,106 @@ public async Task> ThrowAsync(string return new ExceptionAssertions(Array.Empty()); } + /// + /// + /// The allowed time span for the operation. + /// + /// A formatted phrase as is supported by + /// Asserts that the current throws an exception of type + /// within a specific timeout. + /// The type of exception expected to be thrown. explaining why the assertion + /// is needed. If the phrase does not start with the word , it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in because. + /// + public async Task> ThrowWithinAsync( + TimeSpan timeSpan, string because = "", params object[] becauseArgs) + where TException : Exception + { + bool success = Execute.Assertion + .ForCondition(Subject is not null) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context} to throw {0} within {1}{reason}, but found .", + typeof(TException), timeSpan); + + if (success) + { + Exception caughtException = await InvokeWithInterceptionAsync(timeSpan); + return AssertThrows(caughtException, timeSpan, because, becauseArgs); + } + + return new ExceptionAssertions(Array.Empty()); + } + + private ExceptionAssertions AssertThrows( + Exception exception, TimeSpan timeSpan, string because, object[] becauseArgs) + where TException : Exception + { + TException[] expectedExceptions = Extractor.OfType(exception).ToArray(); + + Execute.Assertion + .BecauseOf(because, becauseArgs) + .WithExpectation("Expected a <{0}> to be thrown within {1}{reason}, ", + typeof(TException), timeSpan) + .ForCondition(exception is not null) + .FailWith("but no exception was thrown.") + .Then + .ForCondition(expectedExceptions.Any()) + .FailWith("but found <{0}>: {1}{2}.", + exception?.GetType(), + Environment.NewLine, + exception) + .Then + .ClearExpectation(); + + return new ExceptionAssertions(expectedExceptions); + } + + private async Task InvokeWithInterceptionAsync(TimeSpan timeout) + { + try + { + // For the duration of this nested invocation, configure CallerIdentifier + // to match the contents of the subject rather than our own call site. + // + // Func action = async () => await subject.Should().BeSomething(); + // await action.Should().ThrowAsync(); + // + // If an assertion failure occurs, we want the message to talk about "subject" + // not "await action". + using (CallerIdentifier.OnlyOneFluentAssertionScopeOnCallStack() + ? CallerIdentifier.OverrideStackSearchUsingCurrentScope() + : default) + { + (TTask task, TimeSpan remainingTime) = InvokeWithTimer(timeout); + if (remainingTime < TimeSpan.Zero) + { + // timeout reached without exception + return null; + } + + if (task.IsFaulted) + { + // exception in synchronous portion + return task.Exception!.GetBaseException(); + } + + // Start monitoring the task regarding timeout. + // Here we do not need to know whether the task completes (successfully) in timeout + // or does not complete. We are only interested in the exception which is thrown, not returned. + // So, we can ignore the result. + _ = await CompletesWithinTimeoutAsync(task, remainingTime); + } + + return null; + } + catch (Exception exception) + { + return exception; + } + } + /// @@ -330,18 +431,25 @@ private protected (TTask result, TimeSpan remainingTime) InvokeWithTimer(TimeSpa /// /// Asserts that the current does not throw any exception. /// CompletesWithinTimeoutAsync(Task target, TimeSpan remainingTime) { - using var timeoutCancellationTokenSource = new CancellationTokenSource(); + using var delayCancellationTokenSource = new CancellationTokenSource(); Task completedTask = - await Task.WhenAny(target, Clock.DelayAsync(remainingTime, timeoutCancellationTokenSource.Token)); + await Task.WhenAny(target, Clock.DelayAsync(remainingTime, delayCancellationTokenSource.Token)); + + if (completedTask.IsFaulted) + { + // Throw the inner exception. + await completedTask; + } if (completedTask != target) { + // The monitored task did not complete. return false; } - // cancel the clock - timeoutCancellationTokenSource.Cancel(); + // The monitored task is completed, we shall cancel the clock. + delayCancellationTokenSource.Cancel(); return true; } diff --git a/Src/FluentAssertions/Specialized/DelegateAssertionsBase.cs b/Src/FluentAssertions/Specialized/DelegateAssertionsBase.cs index 29ab2635a0..db76b1f9ce 100644 --- a/Src/FluentAssertions/Specialized/DelegateAssertionsBase.cs +++ b/Src/FluentAssertions/Specialized/DelegateAssertionsBase.cs @@ -17,21 +17,22 @@ public abstract class DelegateAssertionsBase where TDelegate : Delegate where TAssertions : DelegateAssertionsBase { - private readonly IExtractExceptions extractor; + private protected IExtractExceptions Extractor { get; } private protected DelegateAssertionsBase(TDelegate @delegate, IExtractExceptions extractor, IClock clock) : base(@delegate) { - this.extractor = extractor ?? throw new ArgumentNullException(nameof(extractor)); + Extractor = extractor ?? throw new ArgumentNullException(nameof(extractor)); Clock = clock ?? throw new ArgumentNullException(nameof(clock)); } private protected IClock Clock { get; } - protected ExceptionAssertions ThrowInternal(Exception exception, string because, object[] becauseArgs) + protected ExceptionAssertions ThrowInternal( + Exception exception, string because, object[] becauseArgs) where TException : Exception { - TException[] expectedExceptions = extractor.OfType(exception).ToArray(); + TException[] expectedExceptions = Extractor.OfType(exception).ToArray(); Execute.Assertion .BecauseOf(because, becauseArgs) @@ -63,7 +64,7 @@ protected AndConstraint NotThrowInternal(Exception exception, strin protected AndConstraint NotThrowInternal(Exception exception, string because, object[] becauseArgs) where TException : Exception { - IEnumerable exceptions = extractor.OfType(exception); + IEnumerable exceptions = Extractor.OfType(exception); Execute.Assertion .ForCondition(!exceptions.Any()) diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt index bdec61a8fb..06c9e60f85 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt @@ -2272,6 +2272,8 @@ namespace FluentAssertions.Specialized where TException : System.Exception { } public System.Threading.Tasks.Task> ThrowExactlyAsync(string because = "", params object[] becauseArgs) where TException : System.Exception { } + public System.Threading.Tasks.Task> ThrowWithinAsync(System.TimeSpan timeSpan, string because = "", params object[] becauseArgs) + where TException : System.Exception { } } public abstract class DelegateAssertionsBase : FluentAssertions.Primitives.ReferenceTypeAssertions> where TDelegate : System.Delegate diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt index 3d7f0e179e..23f0164ed9 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt @@ -2393,6 +2393,8 @@ namespace FluentAssertions.Specialized where TException : System.Exception { } public System.Threading.Tasks.Task> ThrowExactlyAsync(string because = "", params object[] becauseArgs) where TException : System.Exception { } + public System.Threading.Tasks.Task> ThrowWithinAsync(System.TimeSpan timeSpan, string because = "", params object[] becauseArgs) + where TException : System.Exception { } } public abstract class DelegateAssertionsBase : FluentAssertions.Primitives.ReferenceTypeAssertions> where TDelegate : System.Delegate diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt index b205411ad4..6ed48ec4e9 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt @@ -2272,6 +2272,8 @@ namespace FluentAssertions.Specialized where TException : System.Exception { } public System.Threading.Tasks.Task> ThrowExactlyAsync(string because = "", params object[] becauseArgs) where TException : System.Exception { } + public System.Threading.Tasks.Task> ThrowWithinAsync(System.TimeSpan timeSpan, string because = "", params object[] becauseArgs) + where TException : System.Exception { } } public abstract class DelegateAssertionsBase : FluentAssertions.Primitives.ReferenceTypeAssertions> where TDelegate : System.Delegate diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt index b205411ad4..6ed48ec4e9 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt @@ -2272,6 +2272,8 @@ namespace FluentAssertions.Specialized where TException : System.Exception { } public System.Threading.Tasks.Task> ThrowExactlyAsync(string because = "", params object[] becauseArgs) where TException : System.Exception { } + public System.Threading.Tasks.Task> ThrowWithinAsync(System.TimeSpan timeSpan, string because = "", params object[] becauseArgs) + where TException : System.Exception { } } public abstract class DelegateAssertionsBase : FluentAssertions.Primitives.ReferenceTypeAssertions> where TDelegate : System.Delegate diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt index d1d42f2ee8..21e89e850a 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt @@ -2223,6 +2223,8 @@ namespace FluentAssertions.Specialized where TException : System.Exception { } public System.Threading.Tasks.Task> ThrowExactlyAsync(string because = "", params object[] becauseArgs) where TException : System.Exception { } + public System.Threading.Tasks.Task> ThrowWithinAsync(System.TimeSpan timeSpan, string because = "", params object[] becauseArgs) + where TException : System.Exception { } } public abstract class DelegateAssertionsBase : FluentAssertions.Primitives.ReferenceTypeAssertions> where TDelegate : System.Delegate diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt index b205411ad4..6ed48ec4e9 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt @@ -2272,6 +2272,8 @@ namespace FluentAssertions.Specialized where TException : System.Exception { } public System.Threading.Tasks.Task> ThrowExactlyAsync(string because = "", params object[] becauseArgs) where TException : System.Exception { } + public System.Threading.Tasks.Task> ThrowWithinAsync(System.TimeSpan timeSpan, string because = "", params object[] becauseArgs) + where TException : System.Exception { } } public abstract class DelegateAssertionsBase : FluentAssertions.Primitives.ReferenceTypeAssertions> where TDelegate : System.Delegate diff --git a/Tests/FluentAssertions.Specs/Specialized/TaskAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Specialized/TaskAssertionSpecs.cs index 79ff89dfdd..f1787663b8 100644 --- a/Tests/FluentAssertions.Specs/Specialized/TaskAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Specialized/TaskAssertionSpecs.cs @@ -1,10 +1,13 @@ using System; using System.Threading; using System.Threading.Tasks; +using FluentAssertions.Execution; using FluentAssertions.Extensions; using Xunit; using Xunit.Sdk; +using static FluentAssertions.FluentActions; + namespace FluentAssertions.Specs.Specialized; public static class TaskAssertionSpecs @@ -44,7 +47,7 @@ await testAction.Should().ThrowAsync() } [Fact] - public async Task When_task_completes_fast_t_should_succeed() + public async Task When_task_completes_fast_it_should_succeed() { // Arrange var timer = new FakeClock(); @@ -96,7 +99,6 @@ public async Task When_task_completes_late_it_should_fail() // Act Func action = () => taskFactory.Awaiting(t => (Task)t.Task).Should(timer).CompleteWithinAsync(100.Milliseconds()); - timer.Complete(); // Assert @@ -185,6 +187,285 @@ public async Task When_task_completes_late_it_should_succeed() } } + public class ThrowAsync + { + [Fact] + public async Task When_subject_is_null_it_should_throw() + { + // Arrange + Func action = null; + + // Act + Func testAction = () => action.Should().ThrowAsync( + "because we want to test the failure {0}", "message"); + + // Assert + await testAction.Should().ThrowAsync() + .WithMessage("*because we want to test the failure message*found *"); + } + + [Fact] + public async Task When_subject_is_null_in_assertion_scope_it_should_throw() + { + // Arrange + Func action = null; + + // Act + Func testAction = async () => + { + using var _ = new AssertionScope(); + await action.Should().ThrowAsync( + "because we want to test the failure {0}", "message"); + }; + + // Assert + await testAction.Should().ThrowAsync() + .WithMessage("*because we want to test the failure message*found *"); + } + + [Fact] + public async Task When_task_throws_it_should_succeed() + { + // Act + Func action = () => + { + return + Awaiting(() => Task.FromException(new InvalidOperationException("foo"))) + .Should().ThrowAsync(); + }; + + // Assert + await action.Should().NotThrowAsync(); + } + + [Fact] + public async Task When_task_throws_unexpected_exception_it_should_fail() + { + // Act + Func action = () => + { + return + Awaiting(() => Task.FromException(new NotSupportedException("foo"))) + .Should().ThrowAsync(); + }; + + // Assert + await action.Should().ThrowAsync().WithMessage( + "Expected a to be thrown," + + " but found :*with message \"foo\"*"); + } + + [Fact] + public async Task When_task_completes_without_exception_it_should_fail() + { + // Act + Func action = () => + { + return + Awaiting(() => Task.CompletedTask) + .Should().ThrowAsync(); + }; + + // Assert + await action.Should().ThrowAsync().WithMessage( + "Expected a to be thrown, but no exception was thrown."); + } + } + + public class ThrowWithinAsync + { + [Fact] + public async Task When_subject_is_null_it_should_throw() + { + // Arrange + Func action = null; + + // Act + Func testAction = () => action.Should().ThrowWithinAsync( + 100.Milliseconds(), "because we want to test the failure {0}", "message"); + + // Assert + await testAction.Should().ThrowAsync() + .WithMessage("*because we want to test the failure message*found *"); + } + + [Fact] + public async Task When_subject_is_null_in_assertion_scope_it_should_throw() + { + // Arrange + Func action = null; + + // Act + Func testAction = async () => + { + using var _ = new AssertionScope(); + await action.Should().ThrowWithinAsync( + 100.Milliseconds(), "because we want to test the failure {0}", "message"); + }; + + // Assert + await testAction.Should().ThrowAsync() + .WithMessage("*because we want to test the failure message*found *"); + } + + [Theory] + [InlineData(99)] + [InlineData(100)] + public async Task When_task_throws_fast_it_should_succeed(int delay) + { + // Arrange + var timer = new FakeClock(); + var taskFactory = new TaskCompletionSource(); + + // Act + Func action = () => + { + return taskFactory + .Awaiting(t => (Task)t.Task) + .Should(timer).ThrowWithinAsync(100.Ticks()); + }; + + timer.Delay(delay.Ticks()); + taskFactory.SetException(new InvalidOperationException("foo")); + + // Assert + await action.Should().NotThrowAsync(); + } + + [Fact] + public async Task When_task_throws_slow_it_should_fail() + { + // Arrange + var timer = new FakeClock(); + var taskFactory = new TaskCompletionSource(); + + // Act + Func action = () => + { + return taskFactory + .Awaiting(t => (Task)t.Task) + .Should(timer).ThrowWithinAsync(100.Ticks()); + }; + + timer.Delay(101.Ticks()); + taskFactory.SetException(new InvalidOperationException("foo")); + timer.Complete(); + + // Assert + await action.Should().ThrowAsync(); + } + + [Fact] + public async Task When_task_throws_asynchronous_it_should_succeed() + { + // Arrange + var timer = new FakeClock(); + var taskFactory = new TaskCompletionSource(); + + // Act + Func action = () => + { + return Awaiting(() => (Task)taskFactory.Task) + .Should(timer).ThrowWithinAsync(1.Seconds()); + }; + _ = action.Invoke(); + taskFactory.SetException(new InvalidOperationException("foo")); + + // Assert + await action.Should().NotThrowAsync(); + } + + [Fact] + public async Task When_task_not_completes_it_should_fail() + { + // Arrange + var timer = new FakeClock(); + var taskFactory = new TaskCompletionSource(); + + // Act + Func action = () => + { + return taskFactory + .Awaiting(t => (Task)t.Task) + .Should(timer).ThrowWithinAsync( + 100.Ticks(), "because we want to test the failure {0}", "message"); + }; + timer.Delay(101.Ticks()); + + // Assert + await action.Should().ThrowAsync().WithMessage( + "Expected a to be thrown within 10.0µs" + + " because we want to test the failure message," + + " but no exception was thrown."); + } + + [Fact] + public async Task When_task_completes_without_exception_it_should_fail() + { + // Arrange + var timer = new FakeClock(); + var taskFactory = new TaskCompletionSource(); + + // Act + Func action = () => + { + return taskFactory + .Awaiting(t => (Task)t.Task) + .Should(timer).ThrowWithinAsync(100.Milliseconds()); + }; + taskFactory.SetResult(true); + timer.Complete(); + + // Assert + await action.Should().ThrowAsync().WithMessage( + "Expected a to be thrown within 100ms, but no exception was thrown."); + } + + [Fact] + public async Task When_task_throws_unexpected_exception_it_should_fail() + { + // Arrange + var timer = new FakeClock(); + var taskFactory = new TaskCompletionSource(); + + // Act + Func action = () => + { + return taskFactory + .Awaiting(t => (Task)t.Task) + .Should(timer).ThrowWithinAsync(100.Milliseconds()); + }; + taskFactory.SetException(new NotSupportedException("foo")); + + // Assert + await action.Should().ThrowAsync().WithMessage( + "Expected a to be thrown within 100ms," + + " but found :*with message \"foo\"*"); + } + + [Fact] + public async Task When_task_throws_unexpected_exception_asynchronous_it_should_fail() + { + // Arrange + var timer = new FakeClock(); + var taskFactory = new TaskCompletionSource(); + + // Act + Func action = () => + { + return Awaiting(() => (Task)taskFactory.Task) + .Should(timer).ThrowWithinAsync(1.Seconds()); + }; + _ = action.Invoke(); + taskFactory.SetException(new NotSupportedException("foo")); + + // Assert + await action.Should().ThrowAsync().WithMessage( + "Expected a to be thrown within 1s," + + " but found :*with message \"foo\"*"); + } + } + [Collection("UIFacts")] public class CompleteWithinAsyncUIFacts { diff --git a/docs/_pages/executiontime.md b/docs/_pages/executiontime.md index 3e0f2a6083..41551dfc3f 100644 --- a/docs/_pages/executiontime.md +++ b/docs/_pages/executiontime.md @@ -55,6 +55,7 @@ If you're dealing with a `Task`, you can also assert that it completed within a Func someAsyncWork = () => SomethingReturningATask(); await someAsyncWork.Should().CompleteWithinAsync(100.Milliseconds()); await someAsyncWork.Should().NotCompleteWithinAsync(100.Milliseconds()); +await someAsyncWork.Should().ThrowWithinAsync(100.Milliseconds()); ``` If the `Task` is generic and returns a value, you can use that to write a continuing assertion: diff --git a/docs/_pages/releases.md b/docs/_pages/releases.md index ae332296fc..35b336c0da 100644 --- a/docs/_pages/releases.md +++ b/docs/_pages/releases.md @@ -10,6 +10,7 @@ sidebar: ## Unreleased ### What's new +* Added `ThrowWithinAsync` for assertions on `Task` - [#1974](https://github.com/fluentassertions/fluentassertions/pull/1974) ### Fixes * Improved robustness of several assertions when they're wrapped in an `AssertionScope` - [#2133](https://github.com/fluentassertions/fluentassertions/pull/2133) From 909760140fa32526e2f8395fbc58cd0e4ff7d521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=BCtzmacher?= Date: Sat, 14 Jan 2023 18:51:31 +0100 Subject: [PATCH 48/98] Consolidate documentation of exception typeparam --- Src/FluentAssertions/Specialized/AsyncFunctionAssertions.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Src/FluentAssertions/Specialized/AsyncFunctionAssertions.cs b/Src/FluentAssertions/Specialized/AsyncFunctionAssertions.cs index e7f0c24db3..a4ba2c51e2 100644 --- a/Src/FluentAssertions/Specialized/AsyncFunctionAssertions.cs +++ b/Src/FluentAssertions/Specialized/AsyncFunctionAssertions.cs @@ -112,9 +112,7 @@ public async Task> NotCompleteWithinAsync( /// - /// + /// /// /// A formatted phrase as is supported by /// Asserts that the current throws an exception of the exact type (and not a derived exception type). /// - /// The type of the exception it should throw. - /// The type of exception expected to be thrown. explaining why the assertion /// is needed. If the phrase does not start with the word , it is prepended automatically. @@ -156,6 +154,7 @@ public async Taskbecause> ThrowExactlyAsync /// + /// /// /// A formatted phrase as is supported by /// Asserts that the current throws an exception of type . /// The type of exception expected to be thrown. explaining why the assertion /// is needed. If the phrase does not start with the word , it is prepended automatically. @@ -316,6 +315,7 @@ public async Taskbecause> NotThrowAsync(string because = "", /// + /// /// /// A formatted phrase as is supported by /// Asserts that the current does not throw an exception of type . /// The type of exception expected to not be thrown. explaining why the assertion /// is needed. If the phrase does not start with the word , it is prepended automatically. From c1c8cce95aefca468aca6cf5e1173b9fe5e023ef Mon Sep 17 00:00:00 2001 From: sdelarosbil because Date: Mon, 20 Mar 2023 17:05:30 -0400 Subject: [PATCH 49/98] Add support to convert into to enum --- .../Equivalency/Steps/AutoConversionStep.cs | 13 ++++++++++ .../MemberConversionSpecs.cs | 26 +++++++++++++++++++ docs/_pages/releases.md | 1 + 3 files changed, 40 insertions(+) diff --git a/Src/FluentAssertions/Equivalency/Steps/AutoConversionStep.cs b/Src/FluentAssertions/Equivalency/Steps/AutoConversionStep.cs index 51c67b8e80..adffc9e5fa 100644 --- a/Src/FluentAssertions/Equivalency/Steps/AutoConversionStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/AutoConversionStep.cs @@ -56,6 +56,19 @@ private static bool TryChangeType(object subject, Type expectationType, out obje try { + if (expectationType.IsEnum) + { + if (Enum.IsDefined(expectationType, subject)) + { + conversionResult = Enum.ToObject(expectationType, subject); + return true; + } + else + { + return false; + } + } + conversionResult = Convert.ChangeType(subject, expectationType, CultureInfo.InvariantCulture); return true; } diff --git a/Tests/FluentAssertions.Equivalency.Specs/MemberConversionSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/MemberConversionSpecs.cs index c5896a6a29..fac5faa0a6 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/MemberConversionSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/MemberConversionSpecs.cs @@ -51,6 +51,32 @@ public void When_an_int_is_compared_equivalent_to_a_string_representing_the_numb act.Should().NotThrow(); } + [Fact] + public void Numbers_can_be_converted_to_enums() + { + // Arrange + var expectation = new { Property = EnumFour.Three }; + var subject = new { Property = 3 }; + + // Act / Assert + subject.Should().BeEquivalentTo(expectation, options => options.WithAutoConversion()); + } + + [Fact] + public void Numbers_that_are_out_of_range_cannot_be_converted_to_enums() + { + // Arrange + var expectation = new { Property = EnumFour.Three }; + var subject = new { Property = 4 }; + + // Act + Action act = () => subject.Should().BeEquivalentTo(expectation, options => options.WithAutoConversion()); + + // Assert + act.Should().Throw() + .WithMessage("*subject*Property*EnumFour*"); + } + [Fact] public void When_injecting_a_null_predicate_into_WithAutoConversionFor_it_should_throw() { diff --git a/docs/_pages/releases.md b/docs/_pages/releases.md index 35b336c0da..6eaf8826ae 100644 --- a/docs/_pages/releases.md +++ b/docs/_pages/releases.md @@ -11,6 +11,7 @@ sidebar: ### What's new * Added `ThrowWithinAsync` for assertions on `Task` - [#1974](https://github.com/fluentassertions/fluentassertions/pull/1974) +* Added support for converting integers to enums using `AutoConversion` - [#2147](https://github.com/fluentassertions/fluentassertions/pull/2147) ### Fixes * Improved robustness of several assertions when they're wrapped in an `AssertionScope` - [#2133](https://github.com/fluentassertions/fluentassertions/pull/2133) From 81d3fbf7154f8d9cf80ca0fa72759f863132cf94 Mon Sep 17 00:00:00 2001 From: Samuel Delarosbil <126594693+sdelarosbil@users.noreply.github.com> Date: Fri, 24 Mar 2023 02:24:51 -0400 Subject: [PATCH 50/98] Use ToString to format exceptions (#2150) --- .../Formatting/ExceptionValueFormatter.cs | 13 +------------ .../Exceptions/FunctionExceptionAssertionSpecs.cs | 2 +- .../Exceptions/NotThrowSpecs.cs | 4 ++-- .../Formatting/FormatterSpecs.cs | 14 ++++++++++++++ .../Specialized/TaskAssertionSpecs.cs | 6 +++--- docs/_pages/releases.md | 1 + 6 files changed, 22 insertions(+), 18 deletions(-) diff --git a/Src/FluentAssertions/Formatting/ExceptionValueFormatter.cs b/Src/FluentAssertions/Formatting/ExceptionValueFormatter.cs index 8f9f144a85..a4975af707 100644 --- a/Src/FluentAssertions/Formatting/ExceptionValueFormatter.cs +++ b/Src/FluentAssertions/Formatting/ExceptionValueFormatter.cs @@ -1,5 +1,4 @@ using System; -using static System.FormattableString; namespace FluentAssertions.Formatting; @@ -19,16 +18,6 @@ public bool CanHandle(object value) public void Format(object value, FormattedObjectGraph formattedGraph, FormattingContext context, FormatChild formatChild) { - var exception = (Exception)value; - - formattedGraph.AddFragment(Invariant($"{exception.GetType().FullName} with message \"{exception.Message}\"")); - - if (exception.StackTrace is not null) - { - foreach (string line in exception.StackTrace.Split(new[] { Environment.NewLine }, StringSplitOptions.None)) - { - formattedGraph.AddLine(" " + line); - } - } + formattedGraph.AddFragment(((Exception)value).ToString()); } } diff --git a/Tests/FluentAssertions.Specs/Exceptions/FunctionExceptionAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Exceptions/FunctionExceptionAssertionSpecs.cs index 582a6a27e1..859aabe359 100644 --- a/Tests/FluentAssertions.Specs/Exceptions/FunctionExceptionAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Exceptions/FunctionExceptionAssertionSpecs.cs @@ -653,7 +653,7 @@ public void When_function_does_throw_exception_and_that_exception_was_not_expect // Assert action.Should().Throw() .WithMessage( - "*Did not expect System.InvalidOperationException because it was so fast, but found System.InvalidOperationException with message*custom message*"); + "*Did not expect System.InvalidOperationException because it was so fast, but found System.InvalidOperationException: custom message*"); } [Fact] diff --git a/Tests/FluentAssertions.Specs/Exceptions/NotThrowSpecs.cs b/Tests/FluentAssertions.Specs/Exceptions/NotThrowSpecs.cs index 61d089b2e6..448b553067 100644 --- a/Tests/FluentAssertions.Specs/Exceptions/NotThrowSpecs.cs +++ b/Tests/FluentAssertions.Specs/Exceptions/NotThrowSpecs.cs @@ -45,7 +45,7 @@ public void When_a_specific_exception_should_not_be_thrown_but_it_was_it_should_ action .Should().Throw().WithMessage( "Did not expect System.ArgumentException because we passed valid arguments, " + - "but found*with message \"An exception was forced\"*"); + "but found System.ArgumentException: An exception was forced*"); } [Fact] @@ -81,7 +81,7 @@ public void When_no_exception_should_be_thrown_but_it_was_it_should_throw() action .Should().Throw().WithMessage( "Did not expect any exception because we passed valid arguments, " + - "but found System.ArgumentException with message \"An exception was forced\"*"); + "but found System.ArgumentException: An exception was forced*"); } [Fact] diff --git a/Tests/FluentAssertions.Specs/Formatting/FormatterSpecs.cs b/Tests/FluentAssertions.Specs/Formatting/FormatterSpecs.cs index 9ad739ebbf..106ef5fff9 100644 --- a/Tests/FluentAssertions.Specs/Formatting/FormatterSpecs.cs +++ b/Tests/FluentAssertions.Specs/Formatting/FormatterSpecs.cs @@ -155,6 +155,20 @@ public void When_a_property_throws_an_exception_it_should_ignore_that_and_still_ result.Should().Contain("Member 'ThrowingProperty' threw an exception: 'CustomMessage'"); } + [Fact] + public void When_an_exception_contains_an_inner_exception_they_should_both_appear_in_the_error_message() + { + // Arrange + Exception subject = new("OuterExceptionMessage", new InvalidOperationException("InnerExceptionMessage")); + + // Act + string result = Formatter.ToString(subject); + + // Assert + result.Should().Contain("OuterExceptionMessage") + .And.Contain("InnerExceptionMessage"); + } + [Fact] public void When_the_object_is_a_generic_type_without_custom_string_representation_it_should_show_the_properties() { diff --git a/Tests/FluentAssertions.Specs/Specialized/TaskAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Specialized/TaskAssertionSpecs.cs index f1787663b8..54baca8eab 100644 --- a/Tests/FluentAssertions.Specs/Specialized/TaskAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Specialized/TaskAssertionSpecs.cs @@ -252,7 +252,7 @@ public async Task When_task_throws_unexpected_exception_it_should_fail() // Assert await action.Should().ThrowAsync().WithMessage( "Expected a to be thrown," - + " but found :*with message \"foo\"*"); + + " but found : *foo*"); } [Fact] @@ -440,7 +440,7 @@ public async Task When_task_throws_unexpected_exception_it_should_fail() // Assert await action.Should().ThrowAsync().WithMessage( "Expected a to be thrown within 100ms," - + " but found :*with message \"foo\"*"); + + " but found : *foo*"); } [Fact] @@ -462,7 +462,7 @@ public async Task When_task_throws_unexpected_exception_asynchronous_it_should_f // Assert await action.Should().ThrowAsync().WithMessage( "Expected a to be thrown within 1s," - + " but found :*with message \"foo\"*"); + + " but found : *foo*"); } } diff --git a/docs/_pages/releases.md b/docs/_pages/releases.md index 6eaf8826ae..29a3127871 100644 --- a/docs/_pages/releases.md +++ b/docs/_pages/releases.md @@ -12,6 +12,7 @@ sidebar: ### What's new * Added `ThrowWithinAsync` for assertions on `Task` - [#1974](https://github.com/fluentassertions/fluentassertions/pull/1974) * Added support for converting integers to enums using `AutoConversion` - [#2147](https://github.com/fluentassertions/fluentassertions/pull/2147) +* Changed exception formatting to include any inner exception - [#2150](https://github.com/fluentassertions/fluentassertions/pull/2150) ### Fixes * Improved robustness of several assertions when they're wrapped in an `AssertionScope` - [#2133](https://github.com/fluentassertions/fluentassertions/pull/2133) From b05f09dc2500ecfc908c3d5dbc4563a5461952d5 Mon Sep 17 00:00:00 2001 From: Dennis Doomen Date: Sat, 11 Mar 2023 15:48:46 +0100 Subject: [PATCH 51/98] Cleaned-up the cyclic reference detection specs --- FluentAssertions.sln.DotSettings | 3 +- .../BasicSpecs.cs | 30 +++ .../CyclicReferencesSpecs.cs | 184 +++++------------- .../TestTypes.cs | 28 --- 4 files changed, 85 insertions(+), 160 deletions(-) diff --git a/FluentAssertions.sln.DotSettings b/FluentAssertions.sln.DotSettings index c52d714bf8..692c8c68da 100644 --- a/FluentAssertions.sln.DotSettings +++ b/FluentAssertions.sln.DotSettings @@ -182,4 +182,5 @@ public void When_$scenario$_it_should_$behavior$() - + + diff --git a/Tests/FluentAssertions.Equivalency.Specs/BasicSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/BasicSpecs.cs index a2d2c94c8e..4c071a4b71 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/BasicSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/BasicSpecs.cs @@ -9,6 +9,36 @@ namespace FluentAssertions.Equivalency.Specs; public class BasicSpecs { + [Fact] + public void A_null_configuration_is_invalid() + { + // Arrange + var actual = new { }; + var expectation = new { }; + + // Act + Action act = () => actual.Should().BeEquivalentTo(expectation, config: null); + + // Assert + act.Should().ThrowExactlyInCSharpFile2.0TrueTrueTrueTrue() + .WithParameterName("config"); + } + + [Fact] + public void A_null_as_the_configuration_is_not_valid_for_inequivalency_assertions() + { + // Arrange + var actual = new { }; + var expectation = new { }; + + // Act + Action act = () => actual.Should().NotBeEquivalentTo(expectation, config: null); + + // Assert + act.Should().ThrowExactly() + .WithParameterName("config"); + } + [Fact] public void When_expectation_is_null_it_should_throw() { diff --git a/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs index ef92dce8dd..9a57bdcd13 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs @@ -9,7 +9,7 @@ namespace FluentAssertions.Equivalency.Specs; public class CyclicReferencesSpecs { [Fact] - public void When_validating_nested_properties_that_have_cyclic_references_it_should_throw() + public void By_default_cyclic_references_are_not_valid() { // Arrange var cyclicRoot = new CyclicRoot @@ -44,41 +44,7 @@ public void When_validating_nested_properties_that_have_cyclic_references_it_sho } [Fact] - public void When_validating_nested_properties_and_ignoring_cyclic_references_it_should_succeed() - { - // Arrange - var cyclicRoot = new CyclicRoot - { - Text = "Root" - }; - - cyclicRoot.Level = new CyclicLevel1 - { - Text = "Level1", - Root = cyclicRoot - }; - - var cyclicRootDto = new CyclicRootDto - { - Text = "Root" - }; - - cyclicRootDto.Level = new CyclicLevel1Dto - { - Text = "Level1", - Root = cyclicRootDto - }; - - // Act - Action act = () => - cyclicRoot.Should().BeEquivalentTo(cyclicRootDto, options => options.IgnoringCyclicReferences()); - - // Assert - act.Should().NotThrow(); - } - - [Fact] - public void When_two_cyclic_graphs_are_equivalent_when_ignoring_cycle_references_it_should_succeed() + public void Two_graphs_with_ignored_cyclic_references_can_be_compared() { // Arrange var actual = new Parent(); @@ -98,14 +64,14 @@ public void When_two_cyclic_graphs_are_equivalent_when_ignoring_cycle_references act.Should().NotThrow(); } - public class Parent + private class Parent { public Child Child1 { get; set; } public Child Child2 { get; set; } } - public class Child + private class Child { public Child(Parent parent, int stuff = 0) { @@ -113,13 +79,13 @@ public Child(Parent parent, int stuff = 0) Stuff = stuff; } - public Parent Parent { get; set; } + public Parent Parent { get; } - public int Stuff { get; set; } + public int Stuff { get; } } [Fact] - public void When_validating_nested_properties_that_are_null_it_should_not_throw_on_cyclic_references() + public void Nested_properties_that_are_null_are_not_treated_as_cyclic_references() { // Arrange var actual = new CyclicRoot @@ -142,15 +108,12 @@ public void When_validating_nested_properties_that_are_null_it_should_not_throw_ } }; - // Act - Action act = () => actual.Should().BeEquivalentTo(expectation); - - // Assert - act.Should().NotThrow(); + // Act / Assert + actual.Should().BeEquivalentTo(expectation); } [Fact] - public void When_the_graph_contains_the_same_value_object_it_should_not_be_treated_as_a_cyclic_reference() + public void Equivalent_value_objects_are_not_treated_as_cyclic_references() { // Arrange var actual = new CyclicRootWithValueObject @@ -173,15 +136,12 @@ public void When_the_graph_contains_the_same_value_object_it_should_not_be_treat } }; - // Act - Action act = () => actual.Should().BeEquivalentTo(expectation); - - // Assert - act.Should().NotThrow(); + // Act / Assert + actual.Should().BeEquivalentTo(expectation); } [Fact] - public void When_asserting_types_with_infinite_object_graphs_are_equivalent_it_should_not_overflow_the_stack() + public void Cyclic_references_do_not_trigger_stack_overflows() { // Arrange var recursiveClass1 = new ClassWithInfinitelyRecursiveProperty(); @@ -196,24 +156,18 @@ public void When_asserting_types_with_infinite_object_graphs_are_equivalent_it_s } [Fact] - public void - When_asserting_equivalence_on_objects_needing_high_recursion_depth_and_disabling_recursion_depth_limit_it_should_recurse_to_completion() + public void Cyclic_references_can_be_ignored_in_equivalency_assertions() { // Arrange var recursiveClass1 = new ClassWithFiniteRecursiveProperty(15); var recursiveClass2 = new ClassWithFiniteRecursiveProperty(15); - // Act - Action act = - () => recursiveClass1.Should().BeEquivalentTo(recursiveClass2, - options => options.AllowingInfiniteRecursion()); - - // Assert - act.Should().NotThrow(); + // Act / Assert + recursiveClass1.Should().BeEquivalentTo(recursiveClass2, options => options.AllowingInfiniteRecursion()); } [Fact] - public void Allowing_infinite_recursion_is_described_in_the_failure_message() + public void Allowing_infinite_recursion_is_reported_in_the_failure_message() { // Arrange var recursiveClass1 = new ClassWithFiniteRecursiveProperty(1); @@ -229,54 +183,19 @@ public void Allowing_infinite_recursion_is_described_in_the_failure_message() } [Fact] - public void When_injecting_a_null_config_to_BeEquivalentTo_it_should_throw() - { - // Arrange - var recursiveClass1 = new ClassWithFiniteRecursiveProperty(15); - var recursiveClass2 = new ClassWithFiniteRecursiveProperty(15); - - // Act - Action act = () => recursiveClass1.Should().BeEquivalentTo(recursiveClass2, config: null); - - // Assert - act.Should().ThrowExactly() - .WithParameterName("config"); - } - - [Fact] - public void - When_asserting_inequivalence_on_objects_needing_high_recursion_depth_and_disabling_recursion_depth_limit_it_should_recurse_to_completion() + public void Can_ignore_cyclic_references_for_inequivalency_assertions() { // Arrange var recursiveClass1 = new ClassWithFiniteRecursiveProperty(15); var recursiveClass2 = new ClassWithFiniteRecursiveProperty(16); - // Act - Action act = - () => recursiveClass1.Should().NotBeEquivalentTo(recursiveClass2, + // Act / Assert + recursiveClass1.Should().NotBeEquivalentTo(recursiveClass2, options => options.AllowingInfiniteRecursion()); - - // Assert - act.Should().NotThrow(); - } - - [Fact] - public void When_injecting_a_null_config_to_NotBeEquivalentTo_it_should_throw() - { - // Arrange - var recursiveClass1 = new ClassWithFiniteRecursiveProperty(15); - var recursiveClass2 = new ClassWithFiniteRecursiveProperty(16); - - // Act - Action act = () => recursiveClass1.Should().NotBeEquivalentTo(recursiveClass2, config: null); - - // Assert - act.Should().ThrowExactly() - .WithParameterName("config"); } [Fact] - public void When_an_enumerable_collection_returns_itself_it_should_detect_the_cyclic_reference() + public void Can_detect_cyclic_references_in_enumerables() { // Act var instance1 = new SelfReturningEnumerable(); @@ -310,30 +229,8 @@ IEnumerator IEnumerable.GetEnumerator() } } - internal class LogbookEntryProjection - { - public virtual LogbookCode Logbook { get; set; } - - public virtual ICollection LogbookRelations { get; set; } - } - - internal class LogbookRelation - { - public virtual LogbookCode Logbook { get; set; } - } - - internal class LogbookCode - { - public LogbookCode(string key) - { - Key = key; - } - - public string Key { get; protected set; } - } - [Fact] - public void When_the_root_object_is_referenced_from_a_nested_object_it_should_treat_it_as_a_cyclic_reference() + public void Can_detect_cyclic_references_in_nested_objects_referring_to_the_root() { // Arrange var company1 = new MyCompany @@ -376,11 +273,8 @@ public void When_the_root_object_is_referenced_from_a_nested_object_it_should_tr company2.Logo = logo2; - // Act - Action action = () => company1.Should().BeEquivalentTo(company2, o => o.IgnoringCyclicReferences()); - - // Assert - action.Should().NotThrow(); + // Act / Assert + company1.Should().BeEquivalentTo(company2, o => o.IgnoringCyclicReferences()); } [Fact] @@ -425,7 +319,7 @@ public void Allow_ignoring_cyclic_references_in_value_types_compared_by_members( .Which.Message.Should().NotContain("maximum recursion depth was reached"); } - public class ValueTypeCircularDependency + private class ValueTypeCircularDependency { public string Title { get; set; } @@ -448,4 +342,32 @@ public override int GetHashCode() return Title.GetHashCode(); } } + + private class ClassWithInfinitelyRecursiveProperty + { + public ClassWithInfinitelyRecursiveProperty Self + { + get { return new ClassWithInfinitelyRecursiveProperty(); } + } + } + + private class ClassWithFiniteRecursiveProperty + { + private readonly int depth; + + public ClassWithFiniteRecursiveProperty(int recursiveDepth) + { + depth = recursiveDepth; + } + + public ClassWithFiniteRecursiveProperty Self + { + get + { + return depth > 0 + ? new ClassWithFiniteRecursiveProperty(depth - 1) + : null; + } + } + } } diff --git a/Tests/FluentAssertions.Equivalency.Specs/TestTypes.cs b/Tests/FluentAssertions.Equivalency.Specs/TestTypes.cs index 75f378f4b5..1ab9c89f23 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/TestTypes.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/TestTypes.cs @@ -142,34 +142,6 @@ internal struct StructWithNoMembers { } -internal class ClassWithInfinitelyRecursiveProperty -{ - public ClassWithInfinitelyRecursiveProperty Self - { - get { return new ClassWithInfinitelyRecursiveProperty(); } - } -} - -internal class ClassWithFiniteRecursiveProperty -{ - private readonly int depth; - - public ClassWithFiniteRecursiveProperty(int recursiveDepth) - { - depth = recursiveDepth; - } - - public ClassWithFiniteRecursiveProperty Self - { - get - { - return depth > 0 - ? new ClassWithFiniteRecursiveProperty(depth - 1) - : null; - } - } -} - internal class ClassWithSomeFieldsAndProperties { public string Field1; From f0af5f0c3576ba3a650e42e3ccc8285fda8326b9 Mon Sep 17 00:00:00 2001 From: Dennis Doomen Date: Sat, 11 Mar 2023 16:00:19 +0100 Subject: [PATCH 52/98] Properly define and cover the maximum recursion depth --- .../Equivalency/EquivalencyValidator.cs | 4 +-- Src/FluentAssertions/Equivalency/INode.cs | 4 +++ .../CyclicReferencesSpecs.cs | 25 +++++++++++++++++++ docs/_pages/releases.md | 1 + 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Src/FluentAssertions/Equivalency/EquivalencyValidator.cs b/Src/FluentAssertions/Equivalency/EquivalencyValidator.cs index cc8cf0f89f..caeeedd5a6 100644 --- a/Src/FluentAssertions/Equivalency/EquivalencyValidator.cs +++ b/Src/FluentAssertions/Equivalency/EquivalencyValidator.cs @@ -45,11 +45,11 @@ public void RecursivelyAssertEquality(Comparands comparands, IEquivalencyValidat private static bool ShouldCompareNodesThisDeep(INode currentNode, IEquivalencyAssertionOptions options, AssertionScope assertionScope) { - bool shouldRecurse = options.AllowInfiniteRecursion || currentNode.Depth < MaxDepth; + bool shouldRecurse = options.AllowInfiniteRecursion || currentNode.Depth <= MaxDepth; if (!shouldRecurse) { - assertionScope.FailWith("The maximum recursion depth was reached. "); + assertionScope.FailWith($"The maximum recursion depth of {MaxDepth} was reached. "); } return shouldRecurse; diff --git a/Src/FluentAssertions/Equivalency/INode.cs b/Src/FluentAssertions/Equivalency/INode.cs index ce6e612ba5..b4cfc1e0f3 100644 --- a/Src/FluentAssertions/Equivalency/INode.cs +++ b/Src/FluentAssertions/Equivalency/INode.cs @@ -56,6 +56,10 @@ public interface INode /// + /// int Depth { get; } /// public class ConversionSelector { - private class ConversionSelectorRule + private sealed class ConversionSelectorRule { public Func /// Gets a zero-based number representing the depth within the object graph /// + /// The root object has a depth of , the next nested object a depth of , etc. + /// See also + /// 01this article diff --git a/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs index 9a57bdcd13..ca99887b63 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/CyclicReferencesSpecs.cs @@ -8,6 +8,31 @@ namespace FluentAssertions.Equivalency.Specs; public class CyclicReferencesSpecs { + [Fact] + public void Graphs_up_to_the_maximum_depth_are_supported() + { + // Arrange + var actual = new ClassWithFiniteRecursiveProperty(recursiveDepth: 10); + var expectation = new ClassWithFiniteRecursiveProperty(recursiveDepth: 10); + + // Act/Assert + actual.Should().BeEquivalentTo(expectation); + } + + [Fact] + public void Graphs_deeper_than_the_maximum_depth_are_not_supported() + { + // Arrange + var actual = new ClassWithFiniteRecursiveProperty(recursiveDepth: 11); + var expectation = new ClassWithFiniteRecursiveProperty(recursiveDepth: 11); + + // Act + Action act = () => actual.Should().BeEquivalentTo(expectation); + + // Assert + act.Should().Throw().WithMessage("*maximum*depth*10*"); + } + [Fact] public void By_default_cyclic_references_are_not_valid() { diff --git a/docs/_pages/releases.md b/docs/_pages/releases.md index 29a3127871..ce4d03e234 100644 --- a/docs/_pages/releases.md +++ b/docs/_pages/releases.md @@ -16,6 +16,7 @@ sidebar: ### Fixes * Improved robustness of several assertions when they're wrapped in an `AssertionScope` - [#2133](https://github.com/fluentassertions/fluentassertions/pull/2133) +* The maximum depth `BeEquivalentTo` uses for recursive comparisons was 9 instead of the expected 10 - [#2145](https://github.com/fluentassertions/fluentassertions/pull/2145) ## 6.10.0 From 9c739160e948f6fc677f5f42c366b6924879666d Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Mon, 27 Mar 2023 19:10:32 +0200 Subject: [PATCH 53/98] Remove always-true code Seems to irrelevant since 5f4f371e691d04cb4b205b6e195b450eb6e4207f where `ExceptionAssertions` was changed to having a more pure constructor --- Src/FluentAssertions/Specialized/ExceptionAssertions.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Src/FluentAssertions/Specialized/ExceptionAssertions.cs b/Src/FluentAssertions/Specialized/ExceptionAssertions.cs index da0b4a4e0d..3d061f8424 100644 --- a/Src/FluentAssertions/Specialized/ExceptionAssertions.cs +++ b/Src/FluentAssertions/Specialized/ExceptionAssertions.cs @@ -220,14 +220,8 @@ private IEnumerable AssertInnerExceptions(Type innerException, string Execute.Assertion .BecauseOf(because, becauseArgs) - .WithExpectation("Expected inner {0}{reason}, but ", innerException) - .ForCondition(Subject is not null) - .FailWith("no exception was thrown.") - .Then .ForCondition(Subject.Any(e => e.InnerException is not null)) - .FailWith("the thrown exception has no inner exception.") - .Then - .ClearExpectation(); + .FailWith("Expected inner {0}{reason}, but the thrown exception has no inner exception.", innerException); Exception[] expectedInnerExceptions = Subject .Select(e => e.InnerException) From 6ad2cc2faa55e0f4ea63dd27e09031aa741c13c4 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Mon, 27 Mar 2023 19:13:57 +0200 Subject: [PATCH 54/98] Optimize `AssertInnerExceptionExactly` By not doing the almost exact same work twice --- .../Specialized/ExceptionAssertions.cs | 5 ++++- .../Exceptions/InnerExceptionSpecs.cs | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Src/FluentAssertions/Specialized/ExceptionAssertions.cs b/Src/FluentAssertions/Specialized/ExceptionAssertions.cs index 3d061f8424..74c878b6b1 100644 --- a/Src/FluentAssertions/Specialized/ExceptionAssertions.cs +++ b/Src/FluentAssertions/Specialized/ExceptionAssertions.cs @@ -199,7 +199,10 @@ private IEnumerable AssertInnerExceptionExactly(Type innerException, { Guard.ThrowIfArgumentIsNull(innerException); - AssertInnerExceptions(innerException, because, becauseArgs); + Execute.Assertion + .BecauseOf(because, becauseArgs) + .ForCondition(Subject.Any(e => e.InnerException is not null)) + .FailWith("Expected inner {0}{reason}, but the thrown exception has no inner exception.", innerException); Exception[] expectedExceptions = Subject .Select(e => e.InnerException) diff --git a/Tests/FluentAssertions.Specs/Exceptions/InnerExceptionSpecs.cs b/Tests/FluentAssertions.Specs/Exceptions/InnerExceptionSpecs.cs index e2b818bae8..4fe10d575f 100644 --- a/Tests/FluentAssertions.Specs/Exceptions/InnerExceptionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Exceptions/InnerExceptionSpecs.cs @@ -165,6 +165,21 @@ public void WithInnerExceptionExactly_when_subject_throws_expected_inner_excepti .WithInnerExceptionExactly("because {0} should do just that", "the action"); } + [Fact] + public void An_exception_without_the_expected_inner_exception_has_a_descriptive_message() + { + // Arrange + Action subject = () => throw new BadImageFormatException(""); + + // Act + Action act = () => subject.Should().Throw() + .WithInnerExceptionExactly("some {0}", "message"); + + // Assert + act.Should().Throw() + .WithMessage("*some message*no inner exception*"); + } + [Fact] public void When_subject_throws_an_exception_with_an_unexpected_inner_exception_it_should_throw_with_clear_description() { From 1d069286e8d606dc084e253c3a8559865a32409d Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Mon, 27 Mar 2023 19:15:00 +0200 Subject: [PATCH 55/98] Move guards closer public methods --- Src/FluentAssertions/Specialized/ExceptionAssertions.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Src/FluentAssertions/Specialized/ExceptionAssertions.cs b/Src/FluentAssertions/Specialized/ExceptionAssertions.cs index 74c878b6b1..98f2460f59 100644 --- a/Src/FluentAssertions/Specialized/ExceptionAssertions.cs +++ b/Src/FluentAssertions/Specialized/ExceptionAssertions.cs @@ -125,6 +125,8 @@ public virtual ExceptionAssertions WithInnerException WithInnerException(Type innerException, string because = "", params object[] becauseArgs) { + Guard.ThrowIfArgumentIsNull(innerException); + return new ExceptionAssertions(AssertInnerExceptions(innerException, because, becauseArgs)); } @@ -161,6 +163,8 @@ public virtual ExceptionAssertions WithInnerExceptionExactly WithInnerExceptionExactly(Type innerException, string because = "", params object[] becauseArgs) { + Guard.ThrowIfArgumentIsNull(innerException); + return new ExceptionAssertions(AssertInnerExceptionExactly(innerException, because, becauseArgs)); } @@ -197,8 +201,6 @@ public ExceptionAssertions Where(Expression> private IEnumerable AssertInnerExceptionExactly(Type innerException, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(innerException); - Execute.Assertion .BecauseOf(because, becauseArgs) .ForCondition(Subject.Any(e => e.InnerException is not null)) @@ -219,8 +221,6 @@ private IEnumerable AssertInnerExceptionExactly(Type innerException, private IEnumerable AssertInnerExceptions(Type innerException, string because = "", params object[] becauseArgs) { - Guard.ThrowIfArgumentIsNull(innerException); - Execute.Assertion .BecauseOf(because, becauseArgs) .ForCondition(Subject.Any(e => e.InnerException is not null)) From 6d63421357b4ff19008b8b08dfb0ac73926d2a4c Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Mon, 27 Mar 2023 19:22:13 +0200 Subject: [PATCH 56/98] Consolidate identical tests We can test the provided reason in the same test --- .../Exceptions/InnerExceptionSpecs.cs | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/Tests/FluentAssertions.Specs/Exceptions/InnerExceptionSpecs.cs b/Tests/FluentAssertions.Specs/Exceptions/InnerExceptionSpecs.cs index 4fe10d575f..a39a633832 100644 --- a/Tests/FluentAssertions.Specs/Exceptions/InnerExceptionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Exceptions/InnerExceptionSpecs.cs @@ -213,26 +213,6 @@ public void When_subject_throws_an_exception_without_expected_inner_exception_it { Does testSubject = Does.Throw(); - testSubject.Invoking(x => x.Do()).Should().Throw() - .WithInnerException(); - - throw new XunitException("This point should not be reached"); - } - catch (XunitException ex) - { - ex.Message.Should().Be( - "Expected inner System.InvalidOperationException, but the thrown exception has no inner exception."); - } - } - - [Fact] - public void - When_subject_throws_an_exception_without_expected_inner_exception_and_has_reason_it_should_throw_with_clear_description() - { - try - { - Does testSubject = Does.Throw(); - testSubject.Invoking(x => x.Do()).Should().Throw() .WithInnerException("because {0} should do that", "Does.Do"); From 2f82224499b1577f1f3d0461e2face5411b3e769 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Mon, 27 Mar 2023 19:35:03 +0200 Subject: [PATCH 57/98] Seal private classes --- .../Collections/MaximumMatching/MaximumMatchingSolver.cs | 4 ++-- Src/FluentAssertions/Equivalency/ConversionSelector.cs | 2 +- .../Equivalency/Steps/DataRowCollectionEquivalencyStep.cs | 2 +- .../Equivalency/Steps/DataRowEquivalencyStep.cs | 2 +- .../Equivalency/Steps/GenericDictionaryEquivalencyStep.cs | 2 +- Src/FluentAssertions/Formatting/Formatter.cs | 2 +- Src/FluentAssertions/ObjectAssertionsExtensions.cs | 2 +- Src/FluentAssertions/Specialized/ExceptionAssertions.cs | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Src/FluentAssertions/Collections/MaximumMatching/MaximumMatchingSolver.cs b/Src/FluentAssertions/Collections/MaximumMatching/MaximumMatchingSolver.cs index dd64434b33..988964539a 100644 --- a/Src/FluentAssertions/Collections/MaximumMatching/MaximumMatchingSolver.cs +++ b/Src/FluentAssertions/Collections/MaximumMatching/MaximumMatchingSolver.cs @@ -96,7 +96,7 @@ private struct Match public Element Element; } - private class MatchCollection : IEnumerable + private sealed class MatchCollection : IEnumerable { private readonly Dictionary, Match> matchesByElement = new(); @@ -120,7 +120,7 @@ public Predicate GetMatchedPredicate(Element element) IEnumerator IEnumerable.GetEnumerator() => matchesByElement.Values.GetEnumerator(); } - private class BreadthFirstSearchTracker + private sealed class BreadthFirstSearchTracker { private readonly Queue> unmatchedPredicatesQueue = new(); private readonly Dictionary, Match> previousMatchByPredicate = new(); diff --git a/Src/FluentAssertions/Equivalency/ConversionSelector.cs b/Src/FluentAssertions/Equivalency/ConversionSelector.cs index b0de07e3e1..41d4386387 100644 --- a/Src/FluentAssertions/Equivalency/ConversionSelector.cs +++ b/Src/FluentAssertions/Equivalency/ConversionSelector.cs @@ -14,7 +14,7 @@ namespace FluentAssertions.Equivalency; /// Predicate { get; } diff --git a/Src/FluentAssertions/Equivalency/Steps/DataRowCollectionEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataRowCollectionEquivalencyStep.cs index 1206932a38..dc2b47d4f0 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataRowCollectionEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataRowCollectionEquivalencyStep.cs @@ -188,7 +188,7 @@ private static void GatherRowsByPrimaryKeyAndCompareData(IEquivalencyValidator p } } - private class CompoundKey : IEquatable + private sealed class CompoundKey : IEquatable { private readonly object[] values; diff --git a/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs index f4214668b7..4256a720ba 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs @@ -180,7 +180,7 @@ private static void CompareFieldValue(IEquivalencyValidationContext context, IEq } } - private class SelectedDataRowMembers + private sealed class SelectedDataRowMembers { public bool HasErrors { get; set; } diff --git a/Src/FluentAssertions/Equivalency/Steps/GenericDictionaryEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/GenericDictionaryEquivalencyStep.cs index c4f5bd2782..b11a4d1a35 100644 --- a/Src/FluentAssertions/Equivalency/Steps/GenericDictionaryEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/GenericDictionaryEquivalencyStep.cs @@ -223,7 +223,7 @@ private static void AssertDictionaryEquivalence + private sealed class KeyDifference { public KeyDifference(List missingKeys, List additionalKeys) { diff --git a/Src/FluentAssertions/Formatting/Formatter.cs b/Src/FluentAssertions/Formatting/Formatter.cs index e8baec4993..893715db28 100644 --- a/Src/FluentAssertions/Formatting/Formatter.cs +++ b/Src/FluentAssertions/Formatting/Formatter.cs @@ -185,7 +185,7 @@ public static void AddFormatter(IValueFormatter formatter) /// - private class ObjectGraph + private sealed class ObjectGraph { private readonly CyclicReferenceDetector tracker; private readonly Stack /// Is used to detect the maximum recursion depth as well as cyclic references in the graph. /// pathStack; diff --git a/Src/FluentAssertions/ObjectAssertionsExtensions.cs b/Src/FluentAssertions/ObjectAssertionsExtensions.cs index f856f5e922..aebc033df2 100644 --- a/Src/FluentAssertions/ObjectAssertionsExtensions.cs +++ b/Src/FluentAssertions/ObjectAssertionsExtensions.cs @@ -158,7 +158,7 @@ private static object CreateCloneUsingBinarySerializer(object subject) #pragma warning restore SYSLIB0011 } - private class SimpleBinder : SerializationBinder + private sealed class SimpleBinder : SerializationBinder { private readonly Type type; diff --git a/Src/FluentAssertions/Specialized/ExceptionAssertions.cs b/Src/FluentAssertions/Specialized/ExceptionAssertions.cs index da0b4a4e0d..cbed1f09c4 100644 --- a/Src/FluentAssertions/Specialized/ExceptionAssertions.cs +++ b/Src/FluentAssertions/Specialized/ExceptionAssertions.cs @@ -266,7 +266,7 @@ private static string BuildExceptionsString(IEnumerable exceptions) "\t" + Formatter.ToString(exception))); } - private class ExceptionMessageAssertion + private sealed class ExceptionMessageAssertion { public ExceptionMessageAssertion() { From f934cbeb0bde7ed79cdc54a817daeb4929c9688c Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Mon, 27 Mar 2023 19:39:25 +0200 Subject: [PATCH 58/98] Ignore missing GetHashCode for SonarLint --- Src/FluentAssertions/Collections/GenericCollectionAssertions.cs | 2 +- Src/FluentAssertions/Numeric/NumericAssertions.cs | 2 +- Src/FluentAssertions/Primitives/BooleanAssertions.cs | 2 +- Src/FluentAssertions/Primitives/DateOnlyAssertions.cs | 2 +- Src/FluentAssertions/Primitives/DateTimeAssertions.cs | 2 +- Src/FluentAssertions/Primitives/DateTimeOffsetAssertions.cs | 2 +- .../Primitives/DateTimeOffsetRangeAssertions.cs | 2 +- Src/FluentAssertions/Primitives/DateTimeRangeAssertions.cs | 2 +- Src/FluentAssertions/Primitives/EnumAssertions.cs | 2 +- Src/FluentAssertions/Primitives/GuidAssertions.cs | 2 +- Src/FluentAssertions/Primitives/ObjectAssertions.cs | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs b/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs index 57cce3e30d..84f5654999 100644 --- a/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs +++ b/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs @@ -34,7 +34,7 @@ public GenericCollectionAssertions(TCollection actualValue) } } -#pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals [DebuggerNonUserCode] public class GenericCollectionAssertions : ReferenceTypeAssertions diff --git a/Src/FluentAssertions/Numeric/NumericAssertions.cs b/Src/FluentAssertions/Numeric/NumericAssertions.cs index eab57c3669..28ccf6a2ea 100644 --- a/Src/FluentAssertions/Numeric/NumericAssertions.cs +++ b/Src/FluentAssertions/Numeric/NumericAssertions.cs @@ -22,7 +22,7 @@ public NumericAssertions(T value) } } -#pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals /// /// Contains a number of methods to assert that an is in the expected state. diff --git a/Src/FluentAssertions/Primitives/BooleanAssertions.cs b/Src/FluentAssertions/Primitives/BooleanAssertions.cs index 446e0c34a1..69ba629c9a 100644 --- a/Src/FluentAssertions/Primitives/BooleanAssertions.cs +++ b/Src/FluentAssertions/Primitives/BooleanAssertions.cs @@ -17,7 +17,7 @@ public BooleanAssertions(bool? value) } } -#pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals /// /// Contains a number of methods to assert that a is in the expected state. diff --git a/Src/FluentAssertions/Primitives/DateOnlyAssertions.cs b/Src/FluentAssertions/Primitives/DateOnlyAssertions.cs index 0010847916..f610c6ee6e 100644 --- a/Src/FluentAssertions/Primitives/DateOnlyAssertions.cs +++ b/Src/FluentAssertions/Primitives/DateOnlyAssertions.cs @@ -19,7 +19,7 @@ public DateOnlyAssertions(DateOnly? value) } } -#pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals /// /// Contains a number of methods to assert that a is in the expected state. diff --git a/Src/FluentAssertions/Primitives/DateTimeAssertions.cs b/Src/FluentAssertions/Primitives/DateTimeAssertions.cs index c6c981c303..f511267c2b 100644 --- a/Src/FluentAssertions/Primitives/DateTimeAssertions.cs +++ b/Src/FluentAssertions/Primitives/DateTimeAssertions.cs @@ -23,7 +23,7 @@ public DateTimeAssertions(DateTime? value) } } -#pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals /// /// Contains a number of methods to assert that a is in the expected state. diff --git a/Src/FluentAssertions/Primitives/DateTimeOffsetAssertions.cs b/Src/FluentAssertions/Primitives/DateTimeOffsetAssertions.cs index ce56747d46..490bf3c113 100644 --- a/Src/FluentAssertions/Primitives/DateTimeOffsetAssertions.cs +++ b/Src/FluentAssertions/Primitives/DateTimeOffsetAssertions.cs @@ -24,7 +24,7 @@ public DateTimeOffsetAssertions(DateTimeOffset? value) } } -#pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals /// /// Contains a number of methods to assert that a is in the expected state. diff --git a/Src/FluentAssertions/Primitives/DateTimeOffsetRangeAssertions.cs b/Src/FluentAssertions/Primitives/DateTimeOffsetRangeAssertions.cs index f1f8fa0632..ce99cc3736 100644 --- a/Src/FluentAssertions/Primitives/DateTimeOffsetRangeAssertions.cs +++ b/Src/FluentAssertions/Primitives/DateTimeOffsetRangeAssertions.cs @@ -6,7 +6,7 @@ namespace FluentAssertions.Primitives; -#pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals /// /// Contains a number of methods to assert that two objects differ in the expected way. diff --git a/Src/FluentAssertions/Primitives/DateTimeRangeAssertions.cs b/Src/FluentAssertions/Primitives/DateTimeRangeAssertions.cs index 6eb4fc7c8e..4deabcf6af 100644 --- a/Src/FluentAssertions/Primitives/DateTimeRangeAssertions.cs +++ b/Src/FluentAssertions/Primitives/DateTimeRangeAssertions.cs @@ -5,7 +5,7 @@ namespace FluentAssertions.Primitives; -#pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals /// internal class ByteArrayOrderingRule : IOrderingRule { - public OrderStrictness Evaluate(IObjectInfo memberInfo) + public OrderStrictness Evaluate(IObjectInfo objectInfo) { - return memberInfo.CompileTimeType.IsSameOrInherits(typeof(IEnumerable /// Contains a number of methods to assert that two objects differ in the expected way. diff --git a/Src/FluentAssertions/Primitives/EnumAssertions.cs b/Src/FluentAssertions/Primitives/EnumAssertions.cs index 604eb9f1c6..f6f73515c8 100644 --- a/Src/FluentAssertions/Primitives/EnumAssertions.cs +++ b/Src/FluentAssertions/Primitives/EnumAssertions.cs @@ -20,7 +20,7 @@ public EnumAssertions(TEnum subject) } } -#pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals /// public TypeSelector UnwrapTaskTypes() { - types = types.Select(type => + types = types.ConvertAll(type => { if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Task<>)) { @@ -304,7 +304,7 @@ public TypeSelector UnwrapTaskTypes() } return type == typeof(Task) || type == typeof(ValueTask) ? typeof(void) : type; - }).ToList(); + }); return this; } From 69e8a6bd744ff71e9b48a1cac8882647cc150741 Mon Sep 17 00:00:00 2001 From: Dennis /// Contains a number of methods to assert that a is in the expected state. diff --git a/Src/FluentAssertions/Primitives/GuidAssertions.cs b/Src/FluentAssertions/Primitives/GuidAssertions.cs index 2f086cf29c..7fa6f3ad5f 100644 --- a/Src/FluentAssertions/Primitives/GuidAssertions.cs +++ b/Src/FluentAssertions/Primitives/GuidAssertions.cs @@ -16,7 +16,7 @@ public GuidAssertions(Guid? value) } } -#pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals /// public bool IsOrderingStrictFor(IObjectInfo objectInfo) { - List /// Contains a number of methods to assert that a is in the correct state. diff --git a/Src/FluentAssertions/Primitives/ObjectAssertions.cs b/Src/FluentAssertions/Primitives/ObjectAssertions.cs index 499d137fb9..1db3673882 100644 --- a/Src/FluentAssertions/Primitives/ObjectAssertions.cs +++ b/Src/FluentAssertions/Primitives/ObjectAssertions.cs @@ -18,7 +18,7 @@ public ObjectAssertions(object value) } } -#pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals /// - /// public TSelf IgnoringNonBrowsableMembersOnSubject() { ignoreNonBrowsableOnSubject = true; @@ -742,12 +731,9 @@ public override string ToString() builder.AppendLine("- Do not consider members marked non-browsable on the subject"); } - if (isRecursive) + if (isRecursive && allowInfiniteRecursion) { - if (allowInfiniteRecursion) - { - builder.AppendLine("- Recurse indefinitely"); - } + builder.AppendLine("- Recurse indefinitely"); } builder.AppendFormat(CultureInfo.InvariantCulture, @@ -759,8 +745,9 @@ public override string ToString() builder.AppendLine("- Ignoring cyclic references"); } - builder.AppendLine("- Compare tuples by their properties"); - builder.AppendLine("- Compare anonymous types by their properties"); + builder + .AppendLine("- Compare tuples by their properties") + .AppendLine("- Compare anonymous types by their properties"); if (compareRecordsByValue is true) { diff --git a/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs index 93b6f5ca94..6177f49107 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Data; using System.Diagnostics.CodeAnalysis; using System.Linq; @@ -141,8 +141,6 @@ private static IEnumerable /// Contains a number of methods to assert that a is in the expected state. From 1c954af15ec383b9a1bae0be58bfd284efce3d9b Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Mon, 27 Mar 2023 17:11:19 +0200 Subject: [PATCH 59/98] fix xml docs for time-related assertions --- .../Primitives/NullableDateOnlyAssertions.cs | 4 ++-- .../Primitives/NullableDateTimeAssertions.cs | 6 ++---- .../Primitives/NullableTimeOnlyAssertions.cs | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Src/FluentAssertions/Primitives/NullableDateOnlyAssertions.cs b/Src/FluentAssertions/Primitives/NullableDateOnlyAssertions.cs index 4c5262b463..dece5ba5d6 100644 --- a/Src/FluentAssertions/Primitives/NullableDateOnlyAssertions.cs +++ b/Src/FluentAssertions/Primitives/NullableDateOnlyAssertions.cs @@ -6,7 +6,7 @@ namespace FluentAssertions.Primitives; /// [DebuggerNonUserCode] public class NullableDateOnlyAssertions : NullableDateOnlyAssertions -/// Contains a number of methods to assert that a nullable or +/// Contains a number of methods to assert that a nullable is in the expected state. /// @@ -18,7 +18,7 @@ public NullableDateOnlyAssertions(DateOnly? value) } /// [DebuggerNonUserCode] public class NullableDateOnlyAssertions -/// Contains a number of methods to assert that a nullable or +/// Contains a number of methods to assert that a nullable is in the expected state. /// : DateOnlyAssertions diff --git a/Src/FluentAssertions/Primitives/NullableDateTimeAssertions.cs b/Src/FluentAssertions/Primitives/NullableDateTimeAssertions.cs index 86f891225c..a533d7a2de 100644 --- a/Src/FluentAssertions/Primitives/NullableDateTimeAssertions.cs +++ b/Src/FluentAssertions/Primitives/NullableDateTimeAssertions.cs @@ -6,8 +6,7 @@ namespace FluentAssertions.Primitives; /// /// -/// Contains a number of methods to assert that a nullable or -/// is in the expected state. +/// Contains a number of methods to assert that a nullable is in the expected state. /// /// You can use the for a more fluent way of specifying a . @@ -22,8 +21,7 @@ public NullableDateTimeAssertions(DateTime? expected) } /// /// internal interface IParsingStrategy { /// - /// public TSelf ExcludingNonBrowsableMembers() { excludeNonBrowsableOnExpectation = true; @@ -342,7 +332,6 @@ public TSelf ExcludingNonBrowsableMembers() /// Instructs the comparison to treat non-browsable members in the subject as though they do not exist. If you need to /// ignore non-browsable members in the expectation, use -/// Contains a number of methods to assert that a nullable or -/// is in the expected state. +/// Contains a number of methods to assert that a nullable is in the expected state. /// /// You can use the for a more fluent way of specifying a . diff --git a/Src/FluentAssertions/Primitives/NullableTimeOnlyAssertions.cs b/Src/FluentAssertions/Primitives/NullableTimeOnlyAssertions.cs index 43ff35b01c..a9011308b7 100644 --- a/Src/FluentAssertions/Primitives/NullableTimeOnlyAssertions.cs +++ b/Src/FluentAssertions/Primitives/NullableTimeOnlyAssertions.cs @@ -6,7 +6,7 @@ namespace FluentAssertions.Primitives; /// [DebuggerNonUserCode] public class NullableTimeOnlyAssertions : NullableTimeOnlyAssertions -/// Contains a number of methods to assert that a nullable or +/// Contains a number of methods to assert that a nullable is in the expected state. /// @@ -18,7 +18,7 @@ public NullableTimeOnlyAssertions(TimeOnly? value) } /// [DebuggerNonUserCode] public class NullableTimeOnlyAssertions -/// Contains a number of methods to assert that a nullable or +/// Contains a number of methods to assert that a nullable is in the expected state. /// : TimeOnlyAssertions From 88cbf35fd33c19390d3f7f4802861542c2ba0771 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Mon, 27 Mar 2023 20:10:29 +0200 Subject: [PATCH 60/98] await Task when inside using block --- .../Specialized/TaskOfTAssertionSpecs.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Tests/FluentAssertions.Specs/Specialized/TaskOfTAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Specialized/TaskOfTAssertionSpecs.cs index 13556a228f..31bd834ef8 100644 --- a/Tests/FluentAssertions.Specs/Specialized/TaskOfTAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Specialized/TaskOfTAssertionSpecs.cs @@ -40,11 +40,11 @@ public async Task When_subject_is_null_with_AssertionScope_it_should_fail() Func> action = null; // Act - Func testAction = () => + Func testAction = async () => { using var _ = new AssertionScope(); - return action.Should().CompleteWithinAsync( + await action.Should().CompleteWithinAsync( timeSpan, "because we want to test the failure {0}", "message"); }; @@ -152,12 +152,12 @@ public async Task When_task_completes_late_it_in_assertion_scope_should_fail() var taskFactory = new TaskCompletionSource(); // Act - Func action = () => + Func action = async () => { Func> func = () => taskFactory.Task; using var _ = new AssertionScope(); - return func.Should(timer).CompleteWithinAsync(100.Milliseconds()); + await func.Should(timer).CompleteWithinAsync(100.Milliseconds()); }; timer.Complete(); @@ -174,18 +174,18 @@ public async Task When_task_does_not_complete_the_result_extension_does_not_hang var taskFactory = new TaskCompletionSource(); // Act - Func action = () => + Func action = async () => { Func> func = () => taskFactory.Task; using var _ = new AssertionScope(); - return func.Should(timer).CompleteWithinAsync(100.Milliseconds()).WithResult(2); + await func.Should(timer).CompleteWithinAsync(100.Milliseconds()).WithResult(2); }; timer.Complete(); // Assert var assertionTask = action.Should().ThrowAsync() - .WithMessage("Expected*to complete within 100ms.*Expected return*to be 2, but found 0."); + .WithMessage("Expected*to complete within 100ms.*Expected*to be 2, but found 0."); await Awaiting(() => assertionTask).Should().CompleteWithinAsync(200.Seconds()); } From 8797ac755a0b3bb4854ba958717810d2ad09634e Mon Sep 17 00:00:00 2001 From: Christian Liberto Date: Tue, 28 Mar 2023 12:10:23 +0200 Subject: [PATCH 61/98] Add WithoutStrictOrderingFor overload with an expression (#2151) Add WithoutOrderingStrictOrdering for overload with an expression --- .../EquivalencyAssertionOptions.cs | 15 ++++++ .../Ordering/PathBasedOrderingRule.cs | 6 ++- .../FluentAssertions/net47.verified.txt | 1 + .../FluentAssertions/net6.0.verified.txt | 1 + .../netcoreapp2.1.verified.txt | 1 + .../netcoreapp3.0.verified.txt | 1 + .../netstandard2.0.verified.txt | 1 + .../netstandard2.1.verified.txt | 1 + .../CollectionSpecs.cs | 49 +++++++++++++++++++ docs/_pages/releases.md | 2 + 10 files changed, 76 insertions(+), 2 deletions(-) diff --git a/Src/FluentAssertions/Equivalency/EquivalencyAssertionOptions.cs b/Src/FluentAssertions/Equivalency/EquivalencyAssertionOptions.cs index 90790e2673..8094aa0c1f 100644 --- a/Src/FluentAssertions/Equivalency/EquivalencyAssertionOptions.cs +++ b/Src/FluentAssertions/Equivalency/EquivalencyAssertionOptions.cs @@ -75,6 +75,21 @@ public EquivalencyAssertionOptions WithStrictOrderingFor( return this; } + /// + public EquivalencyAssertionOptions + /// Causes the collection identified by to be compared ignoring the order + /// in which the items appear in the expectation. + /// WithoutStrictOrderingFor( + Expression> expression) + { + string expressionMemberPath = expression.GetMemberPath().ToString(); + OrderingRules.Add(new PathBasedOrderingRule(expressionMemberPath) + { + Invert = true + }); + return this; + } + /// diff --git a/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs b/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs index e33b612e7e..3bd3452133 100644 --- a/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs +++ b/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs @@ -16,6 +16,8 @@ public PathBasedOrderingRule(string path) this.path = path; } + public bool Invert { get; set; } + /// @@ -30,7 +32,7 @@ public OrderStrictness Evaluate(IObjectInfo objectInfo) if (currentPropertyPath.Equals(path, StringComparison.OrdinalIgnoreCase)) { - return OrderStrictness.Strict; + return Invert ? OrderStrictness.NotStrict : OrderStrictness.Strict; } else { @@ -62,6 +64,6 @@ private string RemoveInitialIndexQualifier(string sourcePath) public override string ToString() { - return "Be strict about the order of collection items when path is " + path; + return $"Be {(Invert ? "not strict" : "strict")} about the order of collection items when path is " + path; } } diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt index 06c9e60f85..808076a793 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net47.verified.txt @@ -807,6 +807,7 @@ namespace FluentAssertions.Equivalency public FluentAssertions.Equivalency.EquivalencyAssertionOptions /// Creates a new set of options based on the current instance which acts on a a collection of the . /// /// Determines if ordering of the member referred to by the current is relevant. /// WithMapping(System.Linq.Expressions.Expression> expectationMember, System.Linq.Expressions.Expression> subjectMember) { } public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithMapping(string expectationMemberName, string subjectMemberName) { } public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithStrictOrderingFor(System.Linq.Expressions.Expression> expression) { } + public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithoutStrictOrderingFor(System.Linq.Expressions.Expression> expression) { } } public enum EquivalencyResult { diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt index 23f0164ed9..2c17e6c0ab 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/net6.0.verified.txt @@ -820,6 +820,7 @@ namespace FluentAssertions.Equivalency public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithMapping(System.Linq.Expressions.Expression> expectationMember, System.Linq.Expressions.Expression> subjectMember) { } public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithMapping(string expectationMemberName, string subjectMemberName) { } public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithStrictOrderingFor(System.Linq.Expressions.Expression> expression) { } + public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithoutStrictOrderingFor(System.Linq.Expressions.Expression> expression) { } } public enum EquivalencyResult { diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt index 6ed48ec4e9..80d3f9d910 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp2.1.verified.txt @@ -807,6 +807,7 @@ namespace FluentAssertions.Equivalency public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithMapping(System.Linq.Expressions.Expression> expectationMember, System.Linq.Expressions.Expression> subjectMember) { } public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithMapping(string expectationMemberName, string subjectMemberName) { } public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithStrictOrderingFor(System.Linq.Expressions.Expression> expression) { } + public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithoutStrictOrderingFor(System.Linq.Expressions.Expression> expression) { } } public enum EquivalencyResult { diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt index 6ed48ec4e9..80d3f9d910 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netcoreapp3.0.verified.txt @@ -807,6 +807,7 @@ namespace FluentAssertions.Equivalency public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithMapping(System.Linq.Expressions.Expression> expectationMember, System.Linq.Expressions.Expression> subjectMember) { } public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithMapping(string expectationMemberName, string subjectMemberName) { } public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithStrictOrderingFor(System.Linq.Expressions.Expression> expression) { } + public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithoutStrictOrderingFor(System.Linq.Expressions.Expression> expression) { } } public enum EquivalencyResult { diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt index 21e89e850a..d52f422343 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.0.verified.txt @@ -800,6 +800,7 @@ namespace FluentAssertions.Equivalency public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithMapping(System.Linq.Expressions.Expression> expectationMember, System.Linq.Expressions.Expression> subjectMember) { } public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithMapping(string expectationMemberName, string subjectMemberName) { } public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithStrictOrderingFor(System.Linq.Expressions.Expression> expression) { } + public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithoutStrictOrderingFor(System.Linq.Expressions.Expression> expression) { } } public enum EquivalencyResult { diff --git a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt index 6ed48ec4e9..80d3f9d910 100644 --- a/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt +++ b/Tests/Approval.Tests/ApprovedApi/FluentAssertions/netstandard2.1.verified.txt @@ -807,6 +807,7 @@ namespace FluentAssertions.Equivalency public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithMapping(System.Linq.Expressions.Expression> expectationMember, System.Linq.Expressions.Expression> subjectMember) { } public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithMapping(string expectationMemberName, string subjectMemberName) { } public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithStrictOrderingFor(System.Linq.Expressions.Expression> expression) { } + public FluentAssertions.Equivalency.EquivalencyAssertionOptions WithoutStrictOrderingFor(System.Linq.Expressions.Expression> expression) { } } public enum EquivalencyResult { diff --git a/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs index 67fdfe5861..5e539ab959 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs @@ -1476,6 +1476,31 @@ public void When_an_unordered_collection_must_not_be_strict_using_a_predicate_it action.Should().NotThrow(); } + [Fact] + public void When_an_unordered_collection_must_not_be_strict_using_an_expression_it_should_not_throw() + { + // Arrange + var subject = new[] + { + new { Name = "John", UnorderedCollection = new[] { 1, 2, 3, 4, 5 } }, + new { Name = "Jane", UnorderedCollection = new int[0] } + }; + + var expectation = new[] + { + new { Name = "John", UnorderedCollection = new[] { 5, 4, 3, 2, 1 } }, + new { Name = "Jane", UnorderedCollection = new int[0] } + }; + + // Act + Action action = () => subject.Should().BeEquivalentTo(expectation, options => options + .WithStrictOrdering() + .WithoutStrictOrderingFor(x => x.UnorderedCollection)); + + // Assert + action.Should().NotThrow(); + } + [Fact] public void When_an_unordered_collection_must_not_be_strict_using_a_predicate_and_order_was_reset_to_strict_it_should_throw() @@ -1505,6 +1530,30 @@ public void "*Expected*subject[0].UnorderedCollection[0]*to be 2, but found 1.*Expected subject[0].UnorderedCollection[1]*to be 1, but found 2*"); } + [Fact] + public void When_an_unordered_collection_must_not_be_strict_using_an_expression_and_collection_is_not_equal_it_should_throw() + { + // Arrange + var subject = new + { + UnorderedCollection = new[] { 1 } + }; + + var expectation = new + { + UnorderedCollection = new[] { 2 } + }; + + // Act + Action action = () => subject.Should().BeEquivalentTo(expectation, options => options + .WithStrictOrdering() + .WithoutStrictOrderingFor(x => x.UnorderedCollection)); + + // Assert + action.Should().Throw() + .WithMessage("*not strict*"); + } + [Fact] public void When_asserting_equivalence_of_collections_and_configured_to_use_runtime_properties_it_should_respect_the_runtime_type() diff --git a/docs/_pages/releases.md b/docs/_pages/releases.md index ce4d03e234..9d023592c4 100644 --- a/docs/_pages/releases.md +++ b/docs/_pages/releases.md @@ -14,6 +14,8 @@ sidebar: * Added support for converting integers to enums using `AutoConversion` - [#2147](https://github.com/fluentassertions/fluentassertions/pull/2147) * Changed exception formatting to include any inner exception - [#2150](https://github.com/fluentassertions/fluentassertions/pull/2150) +* Added an expression overload for `WithoutStrictOrderingFor` - [#2151](https://github.com/fluentassertions/fluentassertions/pull/2151) + ### Fixes * Improved robustness of several assertions when they're wrapped in an `AssertionScope` - [#2133](https://github.com/fluentassertions/fluentassertions/pull/2133) * The maximum depth `BeEquivalentTo` uses for recursive comparisons was 9 instead of the expected 10 - [#2145](https://github.com/fluentassertions/fluentassertions/pull/2145) From 1a21903b06848fa95d1907c28da53845514eb8e4 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Mon, 27 Mar 2023 17:56:34 +0200 Subject: [PATCH 62/98] Prevent NullReferenceException When FailWith does not cause immediate termination we must guard against it. --- .../Matching/MustMatchByNameRule.cs | 7 +++++-- .../SelectionRulesSpecs.cs | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Src/FluentAssertions/Equivalency/Matching/MustMatchByNameRule.cs b/Src/FluentAssertions/Equivalency/Matching/MustMatchByNameRule.cs index 0c1e572187..e06f7ea6cd 100644 --- a/Src/FluentAssertions/Equivalency/Matching/MustMatchByNameRule.cs +++ b/Src/FluentAssertions/Equivalency/Matching/MustMatchByNameRule.cs @@ -35,13 +35,16 @@ public IMember Match(IMember expectedMember, object subject, INode parent, IEqui Execute.Assertion.FailWith( $"Expectation has {expectedMember.Description} that the other object does not have."); } - - if (options.IgnoreNonBrowsableOnSubject && !subjectMember.IsBrowsable) + else if (options.IgnoreNonBrowsableOnSubject && !subjectMember.IsBrowsable) { Execute.Assertion.FailWith( $"Expectation has {expectedMember.Description} that is non-browsable in the other object, and non-browsable " + "members on the subject are ignored with the current configuration"); } + else + { + // Everything is fine + } return subjectMember; } diff --git a/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs index 228d6ba86f..b81c7a68d8 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs @@ -2230,6 +2230,27 @@ public void When_non_browsable_property_on_subject_is_ignored_but_is_present_on_ "members on the subject are ignored with the current configuration*"); } + [Fact] + public void Only_ignore_non_browsable_matching_members() + { + // Arrange + var subject = new + { + NonExisting = 0 + }; + + var expectation = new + { + Existing = 1 + }; + + // Act + Action action = () => subject.Should().BeEquivalentTo(expectation, config => config.IgnoringNonBrowsableMembersOnSubject()); + + // Assert + action.Should().Throw(); + } + [Fact] public void When_property_is_non_browsable_only_in_expectation_excluding_non_browsable_members_should_make_it_succeed() { From 6bd9d3ca3ec57555192ebe0a2758f00983f379ae Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Tue, 28 Mar 2023 12:24:13 +0200 Subject: [PATCH 63/98] Use init properties As PolySharp generates `IsExternalInit` for older runtimes we can use init properties for at minimum internal types --- .../Equivalency/Ordering/PathBasedOrderingRule.cs | 2 +- .../Equivalency/Ordering/PredicateBasedOrderingRule.cs | 2 +- .../Equivalency/Steps/DataRowEquivalencyStep.cs | 4 ++-- .../Equivalency/Steps/EnumerableEquivalencyValidator.cs | 4 ++-- .../Primitives/StringWildcardMatchingValidator.cs | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs b/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs index 3bd3452133..1c706445d6 100644 --- a/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs +++ b/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs @@ -16,7 +16,7 @@ public PathBasedOrderingRule(string path) this.path = path; } - public bool Invert { get; set; } + public bool Invert { get; init; } /// +/// /// Determines if ordering of the member referred to by the current is relevant. diff --git a/Src/FluentAssertions/Equivalency/Ordering/PredicateBasedOrderingRule.cs b/Src/FluentAssertions/Equivalency/Ordering/PredicateBasedOrderingRule.cs index 6cfba463f3..06b18b9d6a 100644 --- a/Src/FluentAssertions/Equivalency/Ordering/PredicateBasedOrderingRule.cs +++ b/Src/FluentAssertions/Equivalency/Ordering/PredicateBasedOrderingRule.cs @@ -14,7 +14,7 @@ public PredicateBasedOrderingRule(Expression> predicate) this.predicate = predicate.Compile(); } - public bool Invert { get; set; } + public bool Invert { get; init; } public OrderStrictness Evaluate(IObjectInfo objectInfo) { diff --git a/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs index 4256a720ba..7ada41c909 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs @@ -182,9 +182,9 @@ private static void CompareFieldValue(IEquivalencyValidationContext context, IEq private sealed class SelectedDataRowMembers { - public bool HasErrors { get; set; } + public bool HasErrors { get; init; } - public bool RowState { get; set; } + public bool RowState { get; init; } } private static readonly ConcurrentDictionary<(Type CompileTimeType, Type RuntimeType, IEquivalencyAssertionOptions Config), diff --git a/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyValidator.cs b/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyValidator.cs index 89e1d694fb..8ad413c2ed 100644 --- a/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyValidator.cs +++ b/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyValidator.cs @@ -28,9 +28,9 @@ public EnumerableEquivalencyValidator(IEquivalencyValidator parent, IEquivalency Recursive = false; } - public bool Recursive { get; set; } + public bool Recursive { get; init; } - public OrderingRuleCollection OrderingRules { get; set; } + public OrderingRuleCollection OrderingRules { get; init; } public void Execute(object[] subject, T[] expectation) { diff --git a/Src/FluentAssertions/Primitives/StringWildcardMatchingValidator.cs b/Src/FluentAssertions/Primitives/StringWildcardMatchingValidator.cs index f1d1d447f4..3acef10854 100644 --- a/Src/FluentAssertions/Primitives/StringWildcardMatchingValidator.cs +++ b/Src/FluentAssertions/Primitives/StringWildcardMatchingValidator.cs @@ -70,15 +70,15 @@ protected override string ExpectationDescription /// - public bool Negate { get; set; } + public bool Negate { get; init; } /// - public bool IgnoreCase { get; set; } + public bool IgnoreCase { get; init; } /// - public bool IgnoreNewLineDifferences { get; set; } + public bool IgnoreNewLineDifferences { get; init; } } From c10871586cd80cb53d722f46b452d4d00441b932 Mon Sep 17 00:00:00 2001 From: Dennis /// Gets or sets a value indicating whether the subject should not match the pattern. /// /// Gets or sets a value indicating whether the matching process should ignore any casing difference. /// /// Ignores the difference between environment newline differences /// Date: Wed, 29 Mar 2023 14:40:19 +0200 Subject: [PATCH 64/98] Use tags in XML comments to nicely format paragraphs --- .../CallerIdentification/IParsingStrategy.cs | 5 +++-- Src/FluentAssertions/Data/DataColumnAssertions.cs | 5 ++++- Src/FluentAssertions/Data/DataRowAssertions.cs | 5 ++++- Src/FluentAssertions/Data/DataSetAssertions.cs | 11 ++++++++--- Src/FluentAssertions/Data/DataTableAssertions.cs | 9 ++++++--- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Src/FluentAssertions/CallerIdentification/IParsingStrategy.cs b/Src/FluentAssertions/CallerIdentification/IParsingStrategy.cs index 3721d74b89..1076b460ae 100644 --- a/Src/FluentAssertions/CallerIdentification/IParsingStrategy.cs +++ b/Src/FluentAssertions/CallerIdentification/IParsingStrategy.cs @@ -4,10 +4,11 @@ namespace FluentAssertions.CallerIdentification; /// +/// /// Represents a stateful parsing strategy that is used to help identify the "caller" to use in an assertion message. -/// +/// /// The strategies will be instantiated at the beginning of a "caller identification" task, and will live until /// the statement can be identified (and thus some are stateful). -/// diff --git a/Src/FluentAssertions/Data/DataColumnAssertions.cs b/Src/FluentAssertions/Data/DataColumnAssertions.cs index 1a2cbfe22a..9adec7bea8 100644 --- a/Src/FluentAssertions/Data/DataColumnAssertions.cs +++ b/Src/FluentAssertions/Data/DataColumnAssertions.cs @@ -88,12 +88,15 @@ public AndConstraint BeEquivalentTo(DataColumn expectation /// /// /// + /// + /// /// /// A Unique /// Testing of any property can be overridden using the callback. Exclude specific properties using /// . - /// + /// /// If or a related function is /// used and the exclusion matches the subject , then the equivalency test will never /// fail. + /// with the expected configuration. /// diff --git a/Src/FluentAssertions/Data/DataRowAssertions.cs b/Src/FluentAssertions/Data/DataRowAssertions.cs index 591813c454..6f65842c99 100644 --- a/Src/FluentAssertions/Data/DataRowAssertions.cs +++ b/Src/FluentAssertions/Data/DataRowAssertions.cs @@ -153,16 +153,19 @@ public AndConstraint> BeEquivalentTo(DataRow expecta /// /// /// + /// + /// /// /// /// You can use RowState /// The objects must be of the same type; if two objects /// are equivalent in all ways, except that one is part of a typed and is of a subclass /// of , then by default, they will not be considered equivalent. - /// + /// /// This, as well as testing of any property can be overridden using the callback. /// By calling , two /// objects of differing types can be considered equivalent. Exclude specific properties using /// . /// Exclude columns of the data table (which also excludes the related field data in /// objects) using or a related function. + /// diff --git a/Src/FluentAssertions/Data/DataSetAssertions.cs b/Src/FluentAssertions/Data/DataSetAssertions.cs index 0c465c9763..2cf8559437 100644 --- a/Src/FluentAssertions/Data/DataSetAssertions.cs +++ b/Src/FluentAssertions/Data/DataSetAssertions.cs @@ -198,16 +198,19 @@ public AndConstraint> BeEquivalentTo(DataSet expecta /// /// /// + /// + /// + /// + /// /// /// A SchemaSerializationMode /// The objects must be of the same type; if two objects /// are equivalent in all ways, except that one is a custom subclass of (e.g. to provide /// typed accessors for values contained by the ), then by default, /// they will not be considered equivalent. - /// + /// /// This, as well as testing of any property can be overridden using the callback. /// By calling , two /// objects of differing types can be considered equivalent. This setting applies to all types recursively tested /// as part of the . - /// + /// /// Exclude specific properties using . /// Exclude specific tables within the data set using /// or a related function. You can also indicate that columns should be excluded within the @@ -215,9 +218,11 @@ public AndConstraint> BeEquivalentTo(DataSet expecta /// or a related function. The method /// can be used to exclude columns across all objects in the that share /// the same name. - /// + /// /// You can use /// and related functions to exclude properties on other related System.Data types. + /// with the expected configuration. /// diff --git a/Src/FluentAssertions/Data/DataTableAssertions.cs b/Src/FluentAssertions/Data/DataTableAssertions.cs index 9167928057..1eb85b8bec 100644 --- a/Src/FluentAssertions/Data/DataTableAssertions.cs +++ b/Src/FluentAssertions/Data/DataTableAssertions.cs @@ -219,11 +219,12 @@ public AndConstraint> BeEquivalentTo(DataTable e /// /// /// - /// + /// + /// + /// /// /// A PrimaryKeyRows /// The objects must be of the same type; if two objects /// are equivalent in all ways, except that one is a typed that is a subclass /// of , then by default, they will not be considered equivalent. - /// + /// /// This, as well as testing of any property can be overridden using the callback. /// By calling , two /// objects of differing types can be considered equivalent. Exclude specific properties using @@ -231,9 +232,11 @@ public AndConstraint> BeEquivalentTo(DataTable e /// Exclude columns of the data table using /// or a related function -- this excludes both the objects in /// and associated field data in objects within the . - /// + /// /// You can use /// and related functions to exclude properties on other related System.Data types. + /// with the expected configuration. /// From bf319eca742d9a6edebf95666abc3f08ffe7bef6 Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 29 Mar 2023 14:41:03 +0200 Subject: [PATCH 65/98] Remove unnecessary use of partial for non-partial classes --- Tests/FluentAssertions.Specs/Execution/CallerIdentifierSpecs.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/FluentAssertions.Specs/Execution/CallerIdentifierSpecs.cs b/Tests/FluentAssertions.Specs/Execution/CallerIdentifierSpecs.cs index b80dff08dc..edede0ace7 100644 --- a/Tests/FluentAssertions.Specs/Execution/CallerIdentifierSpecs.cs +++ b/Tests/FluentAssertions.Specs/Execution/CallerIdentifierSpecs.cs @@ -460,7 +460,7 @@ public void When_the_method_has_Should_prefix_it_should_read_whole_method() } [Collection("UIFacts")] - public partial class UIFacts + public class UIFacts { [UIFact] public async Task Caller_identification_should_also_work_for_statements_following_async_code() From fae1515acc3632b18647984b3be94fead0e21f83 Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 29 Mar 2023 14:43:08 +0200 Subject: [PATCH 66/98] Remove unnecessary intermediate variables --- .../GenericCollectionAssertions.cs | 4 +- .../SubsequentOrderingAssertions.cs | 4 +- ...elfReferenceEquivalencyAssertionOptions.cs | 39 +++++++------------ .../Steps/DataColumnEquivalencyStep.cs | 6 +-- 4 files changed, 17 insertions(+), 36 deletions(-) diff --git a/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs b/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs index 84f5654999..570ace5d4b 100644 --- a/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs +++ b/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs @@ -3347,9 +3347,7 @@ private static string GetExpressionOrderString(Expression(TType o) diff --git a/Src/FluentAssertions/Collections/SubsequentOrderingAssertions.cs b/Src/FluentAssertions/Collections/SubsequentOrderingAssertions.cs index 77d8e29531..64dfccd02b 100644 --- a/Src/FluentAssertions/Collections/SubsequentOrderingAssertions.cs +++ b/Src/FluentAssertions/Collections/SubsequentOrderingAssertions.cs @@ -172,11 +172,9 @@ internal sealed override IOrderedEnumerable GetOrderedEnumerable( { Func keySelector = propertyExpression.Compile(); - IOrderedEnumerable expectation = direction == SortOrder.Ascending + return direction == SortOrder.Ascending ? previousOrderedEnumerable.ThenBy(keySelector, comparer) : previousOrderedEnumerable.ThenByDescending(keySelector, comparer); - - return expectation; } return base.GetOrderedEnumerable(propertyExpression, comparer, direction, unordered); diff --git a/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs b/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs index 22af9a1f1f..cdc90381db 100644 --- a/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs +++ b/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs @@ -184,41 +184,32 @@ EqualityStrategy IEquivalencyAssertionOptions.GetEqualityStrategy(Type type) // be aware if the cache must be cleared on mutating the members. return equalityStrategyCache.GetOrAdd(type, typeKey => { - EqualityStrategy strategy; - if (!typeKey.IsPrimitive && referenceTypes.Count > 0 && referenceTypes.Any(t => typeKey.IsSameOrInherits(t))) { - strategy = EqualityStrategy.ForceMembers; + return EqualityStrategy.ForceMembers; } else if (valueTypes.Count > 0 && valueTypes.Any(t => typeKey.IsSameOrInherits(t))) { - strategy = EqualityStrategy.ForceEquals; + return EqualityStrategy.ForceEquals; } else if (!typeKey.IsPrimitive && referenceTypes.Count > 0 && referenceTypes.Any(t => typeKey.IsAssignableToOpenGeneric(t))) { - strategy = EqualityStrategy.ForceMembers; + return EqualityStrategy.ForceMembers; } else if (valueTypes.Count > 0 && valueTypes.Any(t => typeKey.IsAssignableToOpenGeneric(t))) { - strategy = EqualityStrategy.ForceEquals; + return EqualityStrategy.ForceEquals; } else if ((compareRecordsByValue.HasValue || getDefaultEqualityStrategy is null) && typeKey.IsRecord()) { - strategy = compareRecordsByValue is true ? EqualityStrategy.ForceEquals : EqualityStrategy.ForceMembers; + return compareRecordsByValue is true ? EqualityStrategy.ForceEquals : EqualityStrategy.ForceMembers; } - else + else if (getDefaultEqualityStrategy is not null) { - if (getDefaultEqualityStrategy is not null) - { - strategy = getDefaultEqualityStrategy(typeKey); - } - else - { - strategy = typeKey.HasValueSemantics() ? EqualityStrategy.Equals : EqualityStrategy.Members; - } + return getDefaultEqualityStrategy(typeKey); } - return strategy; + return typeKey.HasValueSemantics() ? EqualityStrategy.Equals : EqualityStrategy.Members; }); } @@ -331,7 +322,6 @@ public TSelf ExcludingProperties() /// ). It is not required that they be marked non-browsable in the subject. Use /// to ignore non-browsable members in the subject. /// . /// GetMembersFromExpectation(INode currentNode, new MemberSelectionContext(comparands.CompileTimeType, comparands.RuntimeType, config)); } - members = members.Where(member => CandidateMembers.Contains(member.Name)); - - return members; + return members.Where(member => CandidateMembers.Contains(member.Name)); } } From b1c78549df69fb7392de5fac895b017a0a5c467b Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 29 Mar 2023 14:45:40 +0200 Subject: [PATCH 67/98] Replace First() with the much faster [0] indexer. --- .../Collections/GenericDictionaryAssertions.cs | 4 ++-- .../Equivalency/Steps/DictionaryInterfaceInfo.cs | 2 +- Src/FluentAssertions/EventRaisingExtensions.cs | 2 +- Src/FluentAssertions/Formatting/AttributeBasedFormatter.cs | 2 +- Src/FluentAssertions/Formatting/XElementValueFormatter.cs | 4 ++-- Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs b/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs index 2ae317b7e6..ef6330fad4 100644 --- a/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs +++ b/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -715,7 +715,7 @@ public AndConstraint Contain(params KeyValuePair[] ex Execute.Assertion .BecauseOf(because, becauseArgs) .FailWith("Expected {context:dictionary} {0} to contain key {1}{reason}.", Subject, - expectedKeys.First()); + expectedKeys[0]); } } diff --git a/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs b/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs index 64af83c60a..d1ee6a4fcf 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs @@ -126,7 +126,7 @@ public bool TryConvertFrom(object convertable, out object dictionary) var suitableKeyValuePairCollection = enumerables .Select(enumerable => enumerable.GenericTypeArguments[0]) .Where(itemType => itemType.IsGenericType && itemType.GetGenericTypeDefinition() == typeof(KeyValuePair<,>)) - .SingleOrDefault(itemType => itemType.GenericTypeArguments.First() == Key); + .SingleOrDefault(itemType => itemType.GenericTypeArguments[0] == Key); if (suitableKeyValuePairCollection != null) { diff --git a/Src/FluentAssertions/EventRaisingExtensions.cs b/Src/FluentAssertions/EventRaisingExtensions.cs index b3e92228c0..663fcf70f7 100644 --- a/Src/FluentAssertions/EventRaisingExtensions.cs +++ b/Src/FluentAssertions/EventRaisingExtensions.cs @@ -33,7 +33,7 @@ public static IEventRecording WithSender(this IEventRecording eventRecording, ob if (hasSender) { - object sender = @event.Parameters.First(); + object sender = @event.Parameters[0]; if (ReferenceEquals(sender, expectedSender)) { diff --git a/Src/FluentAssertions/Formatting/AttributeBasedFormatter.cs b/Src/FluentAssertions/Formatting/AttributeBasedFormatter.cs index a73c5d94eb..e76edb2b34 100644 --- a/Src/FluentAssertions/Formatting/AttributeBasedFormatter.cs +++ b/Src/FluentAssertions/Formatting/AttributeBasedFormatter.cs @@ -89,7 +89,7 @@ where method.IsStatic where method.IsDecoratedWithOrInherit() let methodParameters = method.GetParameters() where methodParameters.Length == 2 - select new { Type = methodParameters.First().ParameterType, Method = method } + select new { Type = methodParameters[0].ParameterType, Method = method } into formatter group formatter by formatter.Type into formatterGroup diff --git a/Src/FluentAssertions/Formatting/XElementValueFormatter.cs b/Src/FluentAssertions/Formatting/XElementValueFormatter.cs index 62abf3fd32..bde91445ff 100644 --- a/Src/FluentAssertions/Formatting/XElementValueFormatter.cs +++ b/Src/FluentAssertions/Formatting/XElementValueFormatter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using System.Xml.Linq; using FluentAssertions.Common; @@ -39,7 +39,7 @@ private static string FormatElementWithChildren(XElement element) // Can't use env.newline because the input doc may have unix or windows style // line-breaks - string firstLine = lines.First().RemoveNewLines(); + string firstLine = lines[0].RemoveNewLines(); string lastLine = lines.Last().RemoveNewLines(); string formattedElement = firstLine + "…" + lastLine; diff --git a/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs index 113fc221e4..ec41d1ac2e 100644 --- a/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.ComponentModel; using System.Linq; using FluentAssertions.Events; @@ -385,7 +385,7 @@ public void When_a_specific_sender_is_expected_it_should_return_only_relevant_ev .Raise(nameof(observable.PropertyChanged)) .WithSender(observable); - recording.Should().ContainSingle().Which.Parameters.First().Should().BeSameAs(observable); + recording.Should().ContainSingle().Which.Parameters[0].Should().BeSameAs(observable); } [Fact] From 3af9b7956822033256d4cc066244c1c05b84dd71 Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 29 Mar 2023 14:47:48 +0200 Subject: [PATCH 68/98] Replace LINQ usage with faster alternatives --- Src/FluentAssertions/Equivalency/OrderingRuleCollection.cs | 2 +- Src/FluentAssertions/Equivalency/Steps/AssertionResultSet.cs | 2 +- Src/FluentAssertions/Execution/LateBoundTestFramework.cs | 5 ++--- Src/FluentAssertions/Execution/NSpecFramework.cs | 5 ++--- Src/FluentAssertions/Types/TypeSelector.cs | 4 ++-- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/Src/FluentAssertions/Equivalency/OrderingRuleCollection.cs b/Src/FluentAssertions/Equivalency/OrderingRuleCollection.cs index 160a87015f..d0e4231ab6 100644 --- a/Src/FluentAssertions/Equivalency/OrderingRuleCollection.cs +++ b/Src/FluentAssertions/Equivalency/OrderingRuleCollection.cs @@ -67,7 +67,7 @@ internal void Clear() /// results = rules.Select(r => r.Evaluate(objectInfo)).ToList(); + List results = rules.ConvertAll(r => r.Evaluate(objectInfo)); return results.Contains(OrderStrictness.Strict) && !results.Contains(OrderStrictness.NotStrict); } } diff --git a/Src/FluentAssertions/Equivalency/Steps/AssertionResultSet.cs b/Src/FluentAssertions/Equivalency/Steps/AssertionResultSet.cs index 0185c1329d..f7bae2311d 100644 --- a/Src/FluentAssertions/Equivalency/Steps/AssertionResultSet.cs +++ b/Src/FluentAssertions/Equivalency/Steps/AssertionResultSet.cs @@ -38,7 +38,7 @@ public string[] SelectClosestMatchFor(object key = null) KeyValuePair[] bestResultSets = GetBestResultSets(); - KeyValuePair bestMatch = bestResultSets.FirstOrDefault(r => r.Key.Equals(key)); + KeyValuePair bestMatch = Array.Find(bestResultSets, r => r.Key.Equals(key)); if ((bestMatch.Key, bestMatch.Value) == default) { diff --git a/Src/FluentAssertions/Execution/LateBoundTestFramework.cs b/Src/FluentAssertions/Execution/LateBoundTestFramework.cs index ad40e206ff..d242455a38 100644 --- a/Src/FluentAssertions/Execution/LateBoundTestFramework.cs +++ b/Src/FluentAssertions/Execution/LateBoundTestFramework.cs @@ -29,9 +29,8 @@ public bool IsAvailable { string prefix = AssemblyName + ","; - assembly = AppDomain.CurrentDomain - .GetAssemblies() - .FirstOrDefault(a => a.FullName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)); + assembly = Array.Find(AppDomain.CurrentDomain + .GetAssemblies(), a => a.FullName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)); return assembly is not null; } diff --git a/Src/FluentAssertions/Execution/NSpecFramework.cs b/Src/FluentAssertions/Execution/NSpecFramework.cs index cd903275f3..a22b9ad308 100644 --- a/Src/FluentAssertions/Execution/NSpecFramework.cs +++ b/Src/FluentAssertions/Execution/NSpecFramework.cs @@ -13,9 +13,8 @@ public bool IsAvailable { get { - assembly = AppDomain.CurrentDomain - .GetAssemblies() - .FirstOrDefault(a => a.FullName.StartsWith("nspec,", StringComparison.OrdinalIgnoreCase)); + assembly = Array.Find(AppDomain.CurrentDomain + .GetAssemblies(), a => a.FullName.StartsWith("nspec,", StringComparison.OrdinalIgnoreCase)); if (assembly is null) { diff --git a/Src/FluentAssertions/Types/TypeSelector.cs b/Src/FluentAssertions/Types/TypeSelector.cs index 0946f8fb49..4dc0c80b71 100644 --- a/Src/FluentAssertions/Types/TypeSelector.cs +++ b/Src/FluentAssertions/Types/TypeSelector.cs @@ -291,7 +291,7 @@ public TypeSelector ThatSatisfy(Func predicate) /// Date: Wed, 29 Mar 2023 14:48:41 +0200 Subject: [PATCH 69/98] Use chaining if possible --- .../Equivalency/Steps/ConstraintEquivalencyStep.cs | 10 +++++----- .../Primitives/StringWildcardMatchingValidator.cs | 9 +++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Src/FluentAssertions/Equivalency/Steps/ConstraintEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/ConstraintEquivalencyStep.cs index 5420d16788..b6568dffad 100644 --- a/Src/FluentAssertions/Equivalency/Steps/ConstraintEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/ConstraintEquivalencyStep.cs @@ -223,11 +223,11 @@ private static void CompareConstraintColumns(DataColumn[] subjectColumns, DataCo failureMessage.Append("columns ").Append(missingColumnNames.JoinUsingWritingStyle()); } - failureMessage.Append("{reason}, but constraint does not include "); - - failureMessage.Append(missingColumnNames.Count == 1 - ? "that column. " - : "these columns. "); + failureMessage + .Append("{reason}, but constraint does not include ") + .Append(missingColumnNames.Count == 1 + ? "that column. " + : "these columns. "); } if (extraColumnNames.Any()) diff --git a/Src/FluentAssertions/Primitives/StringWildcardMatchingValidator.cs b/Src/FluentAssertions/Primitives/StringWildcardMatchingValidator.cs index 3acef10854..7a8ce1e7b9 100644 --- a/Src/FluentAssertions/Primitives/StringWildcardMatchingValidator.cs +++ b/Src/FluentAssertions/Primitives/StringWildcardMatchingValidator.cs @@ -58,10 +58,11 @@ protected override string ExpectationDescription get { var builder = new StringBuilder(); - builder.Append(Negate ? "Did not expect " : "Expected "); - builder.Append("{context:string}"); - builder.Append(IgnoreCase ? " to match the equivalent of" : " to match"); - builder.Append(" {0}{reason}, "); + builder + .Append(Negate ? "Did not expect " : "Expected ") + .Append("{context:string}") + .Append(IgnoreCase ? " to match the equivalent of" : " to match") + .Append(" {0}{reason}, "); return builder.ToString(); } From c5587668b17bedd012c53b7c9acbee9fa680d94a Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 29 Mar 2023 14:49:41 +0200 Subject: [PATCH 70/98] Use the parameter names from the interface that is implemented --- .../Equivalency/Ordering/ByteArrayOrderingRule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Src/FluentAssertions/Equivalency/Ordering/ByteArrayOrderingRule.cs b/Src/FluentAssertions/Equivalency/Ordering/ByteArrayOrderingRule.cs index 756ee4b0ba..15e36daec1 100644 --- a/Src/FluentAssertions/Equivalency/Ordering/ByteArrayOrderingRule.cs +++ b/Src/FluentAssertions/Equivalency/Ordering/ByteArrayOrderingRule.cs @@ -9,9 +9,9 @@ namespace FluentAssertions.Equivalency.Ordering; /// )) + return objectInfo.CompileTimeType.IsSameOrInherits(typeof(IEnumerable)) ? OrderStrictness.Strict : OrderStrictness.Irrelevant; } From e2ca1f4378964418296d923b74aed36a0091682b Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 29 Mar 2023 14:50:37 +0200 Subject: [PATCH 71/98] Sealed internal classes --- Src/FluentAssertions/Equivalency/Steps/AssertionContext.cs | 2 +- .../Equivalency/Steps/DictionaryInterfaceInfo.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Src/FluentAssertions/Equivalency/Steps/AssertionContext.cs b/Src/FluentAssertions/Equivalency/Steps/AssertionContext.cs index 022255804f..0e87fea241 100644 --- a/Src/FluentAssertions/Equivalency/Steps/AssertionContext.cs +++ b/Src/FluentAssertions/Equivalency/Steps/AssertionContext.cs @@ -1,6 +1,6 @@ namespace FluentAssertions.Equivalency.Steps; -internal class AssertionContext : IAssertionContext +internal sealed class AssertionContext : IAssertionContext { private AssertionContext(INode currentNode, TSubject subject, TSubject expectation, string because, object[] becauseArgs) diff --git a/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs b/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs index d1ee6a4fcf..1ee8c186b5 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; @@ -11,7 +11,7 @@ namespace FluentAssertions.Equivalency.Steps; /// -internal class DictionaryInterfaceInfo +internal sealed class DictionaryInterfaceInfo { // ReSharper disable once PossibleNullReferenceException private static readonly MethodInfo ConvertToDictionaryMethod = From b001e6e1090f77ca502cb92cfe6cff8a4de52a38 Mon Sep 17 00:00:00 2001 From: Dennis /// Provides Reflection-backed meta-data information about a type implementing the interface. /// Date: Wed, 29 Mar 2023 14:50:59 +0200 Subject: [PATCH 72/98] Replace nested conditional statements with if/else constructs --- .../NumericAssertionsExtensions.cs | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/Src/FluentAssertions/NumericAssertionsExtensions.cs b/Src/FluentAssertions/NumericAssertionsExtensions.cs index d96fb306b8..4bb65302f8 100644 --- a/Src/FluentAssertions/NumericAssertionsExtensions.cs +++ b/Src/FluentAssertions/NumericAssertionsExtensions.cs @@ -1483,11 +1483,19 @@ private static void FailIfDifferenceWithinPrecision( private static long GetMinValue(long value, ulong delta) { - long minValue = delta <= (ulong.MaxValue / 2) - ? value - (long)delta - : value < 0 - ? long.MinValue - : -(long)(delta - (ulong)value); + long minValue; + if (delta <= (ulong.MaxValue / 2)) + { + minValue = value - (long)delta; + } + else if (value < 0) + { + minValue = long.MinValue; + } + else + { + minValue = -(long)(delta - (ulong)value); + } if (minValue > value) { @@ -1499,11 +1507,19 @@ private static long GetMinValue(long value, ulong delta) private static long GetMaxValue(long value, ulong delta) { - long maxValue = delta <= (ulong.MaxValue / 2) - ? value + (long)delta - : value >= 0 - ? long.MaxValue - : (long)((ulong)value + delta); + long maxValue; + if (delta <= (ulong.MaxValue / 2)) + { + maxValue = value + (long)delta; + } + else if (value >= 0) + { + maxValue = long.MaxValue; + } + else + { + maxValue = (long)((ulong)value + delta); + } if (maxValue < value) { From 362b873db2f81d5ca0107ce756d0db67cccefe44 Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 29 Mar 2023 14:55:37 +0200 Subject: [PATCH 73/98] Improve nested ifs and if/else constructs --- .../GenericDictionaryAssertions.cs | 43 ++++++--------- Src/FluentAssertions/Common/Iterator.cs | 18 +++--- Src/FluentAssertions/Common/TypeExtensions.cs | 12 ++-- .../Matching/MappedMemberMatchingRule.cs | 20 +++---- .../Ordering/PathBasedOrderingRule.cs | 6 +- .../Ordering/PredicateBasedOrderingRule.cs | 6 +- .../IncludeMemberByPredicateSelectionRule.cs | 7 +-- .../Equivalency/Steps/AutoConversionStep.cs | 6 +- .../Steps/DataColumnEquivalencyStep.cs | 5 +- .../Steps/DataRelationEquivalencyStep.cs | 31 +++++------ .../Steps/DataRowEquivalencyStep.cs | 55 +++++++++---------- .../Steps/DataSetEquivalencyStep.cs | 45 +++++++-------- .../Steps/DataTableEquivalencyStep.cs | 49 ++++++++--------- .../Steps/DictionaryEquivalencyStep.cs | 31 +++++------ .../Steps/DictionaryInterfaceInfo.cs | 16 +++--- .../Steps/EnumerableEquivalencyValidator.cs | 6 +- .../Steps/GenericDictionaryEquivalencyStep.cs | 16 ++---- .../Steps/ValueTypeEquivalencyStep.cs | 6 +- .../Equivalency/Tracing/Tracer.cs | 6 +- .../Formatting/DefaultValueFormatter.cs | 13 ++--- .../ObjectAssertionsExtensions.cs | 6 +- .../Primitives/StringValidator.cs | 7 +-- 22 files changed, 171 insertions(+), 239 deletions(-) diff --git a/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs b/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs index ef6330fad4..bfded5b693 100644 --- a/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs +++ b/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -349,15 +349,12 @@ public AndConstraint NotContainKey(TKey unexpected, .BecauseOf(because, becauseArgs) .FailWith("Expected {context:dictionary} not to contain key {0}{reason}, but found .", unexpected); - if (success) + if (success && ContainsKey(Subject, unexpected)) { - if (ContainsKey(Subject, unexpected)) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} {0} not to contain key {1}{reason}, but found it anyhow.", Subject, - unexpected); - } + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} {0} not to contain key {1}{reason}, but found it anyhow.", Subject, + unexpected); } return new AndConstraint((TAssertions)this); @@ -569,15 +566,12 @@ public AndConstraint NotContainValue(TValue unexpected, .BecauseOf(because, becauseArgs) .FailWith("Expected {context:dictionary} not to contain value {0}{reason}, but found .", unexpected); - if (success) + if (success && GetValues(Subject).Contains(unexpected)) { - if (GetValues(Subject).Contains(unexpected)) - { - Execute.Assertion - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} {0} not to contain value {1}{reason}, but found it anyhow.", Subject, - unexpected); - } + Execute.Assertion + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} {0} not to contain value {1}{reason}, but found it anyhow.", Subject, + unexpected); } return new AndConstraint((TAssertions)this); @@ -946,16 +940,13 @@ public AndConstraint NotContain(TKey key, TValue value, .FailWith("Expected {context:dictionary} not to contain value {0} at key {1}{reason}, but dictionary is .", value, key); - if (success) + if (success && TryGetValue(Subject, key, out TValue actual)) { - if (TryGetValue(Subject, key, out TValue actual)) - { - Execute.Assertion - .ForCondition(!ObjectExtensions.GetComparer()(actual, value)) - .BecauseOf(because, becauseArgs) - .FailWith("Expected {context:dictionary} not to contain value {0} at key {1}{reason}, but found it anyhow.", - value, key); - } + Execute.Assertion + .ForCondition(!ObjectExtensions.GetComparer()(actual, value)) + .BecauseOf(because, becauseArgs) + .FailWith("Expected {context:dictionary} not to contain value {0} at key {1}{reason}, but found it anyhow.", + value, key); } return new AndConstraint((TAssertions)this); diff --git a/Src/FluentAssertions/Common/Iterator.cs b/Src/FluentAssertions/Common/Iterator.cs index 0ee86c231d..efb1dc3371 100644 --- a/Src/FluentAssertions/Common/Iterator.cs +++ b/Src/FluentAssertions/Common/Iterator.cs @@ -71,13 +71,10 @@ private set public bool MoveNext() { - if (!hasCompleted) + if (!hasCompleted && FetchCurrent()) { - if (FetchCurrent()) - { - PrefetchNext(); - return true; - } + PrefetchNext(); + return true; } hasCompleted = true; @@ -101,11 +98,10 @@ private bool FetchCurrent() return true; } - else - { - hasCompleted = true; - return false; - } + + hasCompleted = true; + + return false; } public bool HasReachedMaxItems => Index == maxItems; diff --git a/Src/FluentAssertions/Common/TypeExtensions.cs b/Src/FluentAssertions/Common/TypeExtensions.cs index 008e14ec67..f8882a66fc 100644 --- a/Src/FluentAssertions/Common/TypeExtensions.cs +++ b/Src/FluentAssertions/Common/TypeExtensions.cs @@ -292,10 +292,8 @@ private static IEnumerable GetMembersFromHierarchy( { return GetInterfaceMembers(typeToReflect, getMembers); } - else - { - return GetClassMembers(typeToReflect, getMembers); - } + + return GetClassMembers(typeToReflect, getMembers); } private static List GetInterfaceMembers(Type typeToReflect, @@ -471,10 +469,8 @@ public static bool IsAssignableToOpenGeneric(this Type type, Type definition) { return type.IsImplementationOfOpenGeneric(definition); } - else - { - return type == definition || type.IsDerivedFromOpenGeneric(definition); - } + + return type == definition || type.IsDerivedFromOpenGeneric(definition); } private static bool IsImplementationOfOpenGeneric(this Type type, Type definition) diff --git a/Src/FluentAssertions/Equivalency/Matching/MappedMemberMatchingRule.cs b/Src/FluentAssertions/Equivalency/Matching/MappedMemberMatchingRule.cs index 0ea3b698ed..f2447baff2 100644 --- a/Src/FluentAssertions/Equivalency/Matching/MappedMemberMatchingRule.cs +++ b/Src/FluentAssertions/Equivalency/Matching/MappedMemberMatchingRule.cs @@ -31,20 +31,18 @@ public MappedMemberMatchingRule(string expectationMemberName, string subjectMemb public IMember Match(IMember expectedMember, object subject, INode parent, IEquivalencyAssertionOptions options) { - if (parent.Type.IsSameOrInherits(typeof(TExpectation)) && subject is TSubject) + if (parent.Type.IsSameOrInherits(typeof(TExpectation)) && subject is TSubject && + expectedMember.Name == expectationMemberName) { - if (expectedMember.Name == expectationMemberName) - { - var member = MemberFactory.Find(subject, subjectMemberName, parent); - - if (member is null) - { - throw new ArgumentException( - $"Subject of type {typeof(TSubject)} does not have member {subjectMemberName}"); - } + var member = MemberFactory.Find(subject, subjectMemberName, parent); - return member; + if (member is null) + { + throw new ArgumentException( + $"Subject of type {typeof(TSubject)} does not have member {subjectMemberName}"); } + + return member; } return null; diff --git a/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs b/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs index 1c706445d6..c9f03fdc5b 100644 --- a/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs +++ b/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs @@ -34,10 +34,8 @@ public OrderStrictness Evaluate(IObjectInfo objectInfo) { return Invert ? OrderStrictness.NotStrict : OrderStrictness.Strict; } - else - { - return OrderStrictness.Irrelevant; - } + + return OrderStrictness.Irrelevant; } private static bool ContainsIndexingQualifiers(string path) diff --git a/Src/FluentAssertions/Equivalency/Ordering/PredicateBasedOrderingRule.cs b/Src/FluentAssertions/Equivalency/Ordering/PredicateBasedOrderingRule.cs index 06b18b9d6a..006ccac5da 100644 --- a/Src/FluentAssertions/Equivalency/Ordering/PredicateBasedOrderingRule.cs +++ b/Src/FluentAssertions/Equivalency/Ordering/PredicateBasedOrderingRule.cs @@ -22,10 +22,8 @@ public OrderStrictness Evaluate(IObjectInfo objectInfo) { return Invert ? OrderStrictness.NotStrict : OrderStrictness.Strict; } - else - { - return OrderStrictness.Irrelevant; - } + + return OrderStrictness.Irrelevant; } public override string ToString() diff --git a/Src/FluentAssertions/Equivalency/Selection/IncludeMemberByPredicateSelectionRule.cs b/Src/FluentAssertions/Equivalency/Selection/IncludeMemberByPredicateSelectionRule.cs index 4a10a48ff5..7d009ebf9e 100644 --- a/Src/FluentAssertions/Equivalency/Selection/IncludeMemberByPredicateSelectionRule.cs +++ b/Src/FluentAssertions/Equivalency/Selection/IncludeMemberByPredicateSelectionRule.cs @@ -33,12 +33,9 @@ public IEnumerable SelectMembers(INode currentNode, IEnumerable p.IsEquivalentTo(member))) { - if (!members.Any(p => p.IsEquivalentTo(member))) - { - members.Add(member); - } + members.Add(member); } } diff --git a/Src/FluentAssertions/Equivalency/Steps/AutoConversionStep.cs b/Src/FluentAssertions/Equivalency/Steps/AutoConversionStep.cs index adffc9e5fa..6f6a78ae17 100644 --- a/Src/FluentAssertions/Equivalency/Steps/AutoConversionStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/AutoConversionStep.cs @@ -63,10 +63,8 @@ private static bool TryChangeType(object subject, Type expectationType, out obje conversionResult = Enum.ToObject(expectationType, subject); return true; } - else - { - return false; - } + + return false; } conversionResult = Convert.ChangeType(subject, expectationType, CultureInfo.InvariantCulture); diff --git a/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs index 6177f49107..69b32e25b3 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs @@ -23,10 +23,8 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc AssertionScope.Current.FailWith("Expected {context:DataColumn} value to be null, but found {0}", subject); } } - else + else if (subject is null) { - if (subject is null) - { if (comparands.Subject is null) { AssertionScope.Current.FailWith("Expected {context:DataColumn} to be non-null, but found null"); @@ -41,7 +39,6 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc { CompareSubjectAndExpectationOfTypeDataColumn(comparands, context, nestedValidator, subject); } - } return EquivalencyResult.AssertionCompleted; } diff --git a/Src/FluentAssertions/Equivalency/Steps/DataRelationEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataRelationEquivalencyStep.cs index a84a754262..0ec9c92051 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataRelationEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataRelationEquivalencyStep.cs @@ -23,31 +23,28 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc AssertionScope.Current.FailWith("Expected {context:DataRelation} to be null, but found {0}", subject); } } - else + else if (subject is null) { - if (subject is null) + if (comparands.Subject is null) { - if (comparands.Subject is null) - { - AssertionScope.Current.FailWith("Expected {context:DataRelation} value to be non-null, but found null"); - } - else - { - AssertionScope.Current.FailWith("Expected {context:DataRelation} of type {0}, but found {1} instead", - expectation.GetType(), comparands.Subject.GetType()); - } + AssertionScope.Current.FailWith("Expected {context:DataRelation} value to be non-null, but found null"); } else { - var selectedMembers = GetMembersFromExpectation(context.CurrentNode, comparands, context.Options) - .ToDictionary(member => member.Name); + AssertionScope.Current.FailWith("Expected {context:DataRelation} of type {0}, but found {1} instead", + expectation.GetType(), comparands.Subject.GetType()); + } + } + else + { + var selectedMembers = GetMembersFromExpectation(context.CurrentNode, comparands, context.Options) + .ToDictionary(member => member.Name); - CompareScalarProperties(subject, expectation, selectedMembers); + CompareScalarProperties(subject, expectation, selectedMembers); - CompareCollections(context, comparands, nestedValidator, context.Options, selectedMembers); + CompareCollections(context, comparands, nestedValidator, context.Options, selectedMembers); - CompareRelationConstraints(context, nestedValidator, subject, expectation, selectedMembers); - } + CompareRelationConstraints(context, nestedValidator, subject, expectation, selectedMembers); } return EquivalencyResult.AssertionCompleted; diff --git a/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs index 7ada41c909..ef25da0db8 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs @@ -25,44 +25,41 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc AssertionScope.Current.FailWith("Expected {context:DataRow} value to be null, but found {0}", subject); } } - else + else if (subject is null) { - if (subject is null) + if (comparands.Subject is null) { - if (comparands.Subject is null) - { - AssertionScope.Current.FailWith("Expected {context:DataRow} to be non-null, but found null"); - } - else - { - AssertionScope.Current.FailWith("Expected {context:DataRow} to be of type {0}, but found {1} instead", - expectation.GetType(), comparands.Subject.GetType()); - } + AssertionScope.Current.FailWith("Expected {context:DataRow} to be non-null, but found null"); } else { - var dataSetConfig = context.Options as DataEquivalencyAssertionOptions; - var dataTableConfig = context.Options as DataEquivalencyAssertionOptions; - var dataRowConfig = context.Options as DataEquivalencyAssertionOptions; + AssertionScope.Current.FailWith("Expected {context:DataRow} to be of type {0}, but found {1} instead", + expectation.GetType(), comparands.Subject.GetType()); + } + } + else + { + var dataSetConfig = context.Options as DataEquivalencyAssertionOptions; + var dataTableConfig = context.Options as DataEquivalencyAssertionOptions; + var dataRowConfig = context.Options as DataEquivalencyAssertionOptions; - if (dataSetConfig?.AllowMismatchedTypes != true - && dataTableConfig?.AllowMismatchedTypes != true - && dataRowConfig?.AllowMismatchedTypes != true) - { - AssertionScope.Current - .ForCondition(subject.GetType() == expectation.GetType()) - .FailWith("Expected {context:DataRow} to be of type {0}{reason}, but found {1}", - expectation.GetType(), subject.GetType()); - } + if (dataSetConfig?.AllowMismatchedTypes != true + && dataTableConfig?.AllowMismatchedTypes != true + && dataRowConfig?.AllowMismatchedTypes != true) + { + AssertionScope.Current + .ForCondition(subject.GetType() == expectation.GetType()) + .FailWith("Expected {context:DataRow} to be of type {0}{reason}, but found {1}", + expectation.GetType(), subject.GetType()); + } - SelectedDataRowMembers selectedMembers = - GetMembersFromExpectation(comparands, context.CurrentNode, context.Options); + SelectedDataRowMembers selectedMembers = + GetMembersFromExpectation(comparands, context.CurrentNode, context.Options); - CompareScalarProperties(subject, expectation, selectedMembers); + CompareScalarProperties(subject, expectation, selectedMembers); - CompareFieldValues(context, nestedValidator, subject, expectation, dataSetConfig, dataTableConfig, - dataRowConfig); - } + CompareFieldValues(context, nestedValidator, subject, expectation, dataSetConfig, dataTableConfig, + dataRowConfig); } return EquivalencyResult.AssertionCompleted; diff --git a/Src/FluentAssertions/Equivalency/Steps/DataSetEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataSetEquivalencyStep.cs index 8c2f838df6..b460d78923 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataSetEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataSetEquivalencyStep.cs @@ -20,39 +20,36 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc AssertionScope.Current.FailWith("Expected {context:DataSet} value to be null, but found {0}", subject); } } - else + else if (subject is null) { - if (subject is null) + if (comparands.Subject is null) { - if (comparands.Subject is null) - { - AssertionScope.Current.FailWith("Expected {context:DataSet} to be non-null, but found null"); - } - else - { - AssertionScope.Current.FailWith("Expected {context:DataSet} to be of type {0}, but found {1} instead", - expectation.GetType(), comparands.Subject.GetType()); - } + AssertionScope.Current.FailWith("Expected {context:DataSet} to be non-null, but found null"); } else { - var dataConfig = context.Options as DataEquivalencyAssertionOptions; + AssertionScope.Current.FailWith("Expected {context:DataSet} to be of type {0}, but found {1} instead", + expectation.GetType(), comparands.Subject.GetType()); + } + } + else + { + var dataConfig = context.Options as DataEquivalencyAssertionOptions; - if (dataConfig?.AllowMismatchedTypes != true) - { - AssertionScope.Current - .ForCondition(subject.GetType() == expectation.GetType()) - .FailWith("Expected {context:DataSet} to be of type {0}{reason}, but found {1}", expectation.GetType(), - subject.GetType()); - } + if (dataConfig?.AllowMismatchedTypes != true) + { + AssertionScope.Current + .ForCondition(subject.GetType() == expectation.GetType()) + .FailWith("Expected {context:DataSet} to be of type {0}{reason}, but found {1}", expectation.GetType(), + subject.GetType()); + } - var selectedMembers = GetMembersFromExpectation(comparands, context.CurrentNode, context.Options) - .ToDictionary(member => member.Name); + var selectedMembers = GetMembersFromExpectation(comparands, context.CurrentNode, context.Options) + .ToDictionary(member => member.Name); - CompareScalarProperties(subject, expectation, selectedMembers); + CompareScalarProperties(subject, expectation, selectedMembers); - CompareCollections(context, nestedValidator, context.Options, subject, expectation, dataConfig, selectedMembers); - } + CompareCollections(context, nestedValidator, context.Options, subject, expectation, dataConfig, selectedMembers); } return EquivalencyResult.AssertionCompleted; diff --git a/Src/FluentAssertions/Equivalency/Steps/DataTableEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataTableEquivalencyStep.cs index 1ec6f5fd43..4caefeab9d 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataTableEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataTableEquivalencyStep.cs @@ -23,41 +23,38 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc AssertionScope.Current.FailWith("Expected {context:DataTable} value to be null, but found {0}", subject); } } - else + else if (subject is null) { - if (subject is null) + if (comparands.Subject is null) { - if (comparands.Subject is null) - { - AssertionScope.Current.FailWith("Expected {context:DataTable} to be non-null, but found null"); - } - else - { - AssertionScope.Current.FailWith("Expected {context:DataTable} to be of type {0}, but found {1} instead", - expectation.GetType(), comparands.Subject.GetType()); - } + AssertionScope.Current.FailWith("Expected {context:DataTable} to be non-null, but found null"); } else { - var dataSetConfig = context.Options as DataEquivalencyAssertionOptions; - var dataTableConfig = context.Options as DataEquivalencyAssertionOptions; + AssertionScope.Current.FailWith("Expected {context:DataTable} to be of type {0}, but found {1} instead", + expectation.GetType(), comparands.Subject.GetType()); + } + } + else + { + var dataSetConfig = context.Options as DataEquivalencyAssertionOptions; + var dataTableConfig = context.Options as DataEquivalencyAssertionOptions; - if (dataSetConfig?.AllowMismatchedTypes != true - && dataTableConfig?.AllowMismatchedTypes != true) - { - AssertionScope.Current - .ForCondition(subject.GetType() == expectation.GetType()) - .FailWith("Expected {context:DataTable} to be of type {0}{reason}, but found {1}", expectation.GetType(), - subject.GetType()); - } + if (dataSetConfig?.AllowMismatchedTypes != true + && dataTableConfig?.AllowMismatchedTypes != true) + { + AssertionScope.Current + .ForCondition(subject.GetType() == expectation.GetType()) + .FailWith("Expected {context:DataTable} to be of type {0}{reason}, but found {1}", expectation.GetType(), + subject.GetType()); + } - var selectedMembers = GetMembersFromExpectation(context.CurrentNode, comparands, context.Options) - .ToDictionary(member => member.Name); + var selectedMembers = GetMembersFromExpectation(context.CurrentNode, comparands, context.Options) + .ToDictionary(member => member.Name); - CompareScalarProperties(subject, expectation, selectedMembers); + CompareScalarProperties(subject, expectation, selectedMembers); - CompareCollections(comparands, context, nestedValidator, context.Options, selectedMembers); - } + CompareCollections(comparands, context, nestedValidator, context.Options, selectedMembers); } return EquivalencyResult.AssertionCompleted; diff --git a/Src/FluentAssertions/Equivalency/Steps/DictionaryEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DictionaryEquivalencyStep.cs index d6b3433fbc..e0acf0f406 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DictionaryEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DictionaryEquivalencyStep.cs @@ -14,28 +14,25 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc var subject = comparands.Subject as IDictionary; var expectation = comparands.Expectation as IDictionary; - if (PreconditionsAreMet(expectation, subject)) + if (PreconditionsAreMet(expectation, subject) && expectation is not null) { - if (expectation is not null) + foreach (object key in expectation.Keys) { - foreach (object key in expectation.Keys) + if (context.Options.IsRecursive) { - if (context.Options.IsRecursive) - { - context.Tracer.WriteLine(member => - Invariant($"Recursing into dictionary item {key} at {member.Description}")); + context.Tracer.WriteLine(member => + Invariant($"Recursing into dictionary item {key} at {member.Description}")); - nestedValidator.RecursivelyAssertEquality(new Comparands(subject[key], expectation[key], typeof(object)), - context.AsDictionaryItem(key)); - } - else - { - context.Tracer.WriteLine(member => - Invariant( - $"Comparing dictionary item {key} at {member.Description} between subject and expectation")); + nestedValidator.RecursivelyAssertEquality(new Comparands(subject[key], expectation[key], typeof(object)), + context.AsDictionaryItem(key)); + } + else + { + context.Tracer.WriteLine(member => + Invariant( + $"Comparing dictionary item {key} at {member.Description} between subject and expectation")); - subject[key].Should().Be(expectation[key], context.Reason.FormattedMessage, context.Reason.Arguments); - } + subject[key].Should().Be(expectation[key], context.Reason.FormattedMessage, context.Reason.Arguments); } } } diff --git a/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs b/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs index 1ee8c186b5..8d221cddce 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; @@ -102,14 +102,12 @@ private static DictionaryInterfaceInfo[] GetDictionaryInterfacesFrom(Type target { return Array.Empty(); } - else - { - return key - .GetClosedGenericInterfaces(typeof(IDictionary<,>)) - .Select(@interface => @interface.GetGenericArguments()) - .Select(arguments => new DictionaryInterfaceInfo(arguments[0], arguments[1])) - .ToArray(); - } + + return key + .GetClosedGenericInterfaces(typeof(IDictionary<,>)) + .Select(@interface => @interface.GetGenericArguments()) + .Select(arguments => new DictionaryInterfaceInfo(arguments[0], arguments[1])) + .ToArray(); }); } diff --git a/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyValidator.cs b/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyValidator.cs index 8ad413c2ed..4231b55890 100644 --- a/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyValidator.cs +++ b/Src/FluentAssertions/Equivalency/Steps/EnumerableEquivalencyValidator.cs @@ -175,10 +175,8 @@ private bool LooselyMatchAgainst(IList subjects, T expectation, int e indexToBeRemoved = metaIndex; break; } - else - { - context.Tracer.WriteLine(_ => $"Contained {failures.Length} failures"); - } + + context.Tracer.WriteLine(_ => $"Contained {failures.Length} failures"); } if (indexToBeRemoved != -1) diff --git a/Src/FluentAssertions/Equivalency/Steps/GenericDictionaryEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/GenericDictionaryEquivalencyStep.cs index b11a4d1a35..a827a76d86 100644 --- a/Src/FluentAssertions/Equivalency/Steps/GenericDictionaryEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/GenericDictionaryEquivalencyStep.cs @@ -48,12 +48,9 @@ private static void Handle(Comparands comparands, DictionaryInterfaceInfo expect { var (isDictionary, actualDictionary) = EnsureSubjectIsDictionary(comparands, expectedDictionary); - if (isDictionary) + if (isDictionary && AssertSameLength(comparands, actualDictionary, expectedDictionary)) { - if (AssertSameLength(comparands, actualDictionary, expectedDictionary)) - { - AssertDictionaryEquivalence(comparands, context, nestedValidator, actualDictionary, expectedDictionary); - } + AssertDictionaryEquivalence(comparands, context, nestedValidator, actualDictionary, expectedDictionary); } } } @@ -78,13 +75,10 @@ private static (bool isDictionary, DictionaryInterfaceInfo info) EnsureSubjectIs bool isDictionary = DictionaryInterfaceInfo.TryGetFromWithKey(comparands.Subject.GetType(), "subject", expectedDictionary.Key, out var actualDictionary); - if (!isDictionary) + if (!isDictionary && expectedDictionary.TryConvertFrom(comparands.Subject, out var convertedSubject)) { - if (expectedDictionary.TryConvertFrom(comparands.Subject, out var convertedSubject)) - { - comparands.Subject = convertedSubject; - isDictionary = DictionaryInterfaceInfo.TryGetFrom(comparands.Subject.GetType(), "subject", out actualDictionary); - } + comparands.Subject = convertedSubject; + isDictionary = DictionaryInterfaceInfo.TryGetFrom(comparands.Subject.GetType(), "subject", out actualDictionary); } if (!isDictionary) diff --git a/Src/FluentAssertions/Equivalency/Steps/ValueTypeEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/ValueTypeEquivalencyStep.cs index 9340e807c7..71a131c275 100644 --- a/Src/FluentAssertions/Equivalency/Steps/ValueTypeEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/ValueTypeEquivalencyStep.cs @@ -30,9 +30,7 @@ public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationCon return EquivalencyResult.AssertionCompleted; } - else - { - return EquivalencyResult.ContinueWithNext; - } + + return EquivalencyResult.ContinueWithNext; } } diff --git a/Src/FluentAssertions/Equivalency/Tracing/Tracer.cs b/Src/FluentAssertions/Equivalency/Tracing/Tracer.cs index 465278ed81..8e93c3e0cf 100644 --- a/Src/FluentAssertions/Equivalency/Tracing/Tracer.cs +++ b/Src/FluentAssertions/Equivalency/Tracing/Tracer.cs @@ -41,10 +41,8 @@ public IDisposable WriteBlock(GetTraceMessage getTraceMessage) { return traceWriter.AddBlock(getTraceMessage(currentNode)); } - else - { - return new Disposable(() => { }); - } + + return new Disposable(() => { }); } public override string ToString() => traceWriter is not null ? traceWriter.ToString() : string.Empty; diff --git a/Src/FluentAssertions/Formatting/DefaultValueFormatter.cs b/Src/FluentAssertions/Formatting/DefaultValueFormatter.cs index 945c8e4ac5..a65ab4cc2b 100644 --- a/Src/FluentAssertions/Formatting/DefaultValueFormatter.cs +++ b/Src/FluentAssertions/Formatting/DefaultValueFormatter.cs @@ -38,16 +38,13 @@ public void Format(object value, FormattedObjectGraph formattedGraph, Formatting { WriteTypeAndMemberValues(value, formattedGraph, formatChild); } + else if (context.UseLineBreaks) + { + formattedGraph.AddFragmentOnNewLine(value.ToString()); + } else { - if (context.UseLineBreaks) - { - formattedGraph.AddFragmentOnNewLine(value.ToString()); - } - else - { - formattedGraph.AddFragment(value.ToString()); - } + formattedGraph.AddFragment(value.ToString()); } } diff --git a/Src/FluentAssertions/ObjectAssertionsExtensions.cs b/Src/FluentAssertions/ObjectAssertionsExtensions.cs index aebc033df2..eddacfe79b 100644 --- a/Src/FluentAssertions/ObjectAssertionsExtensions.cs +++ b/Src/FluentAssertions/ObjectAssertionsExtensions.cs @@ -173,10 +173,8 @@ public override Type BindToType(string assemblyName, string typeName) { return type; } - else - { - return null; - } + + return null; } } diff --git a/Src/FluentAssertions/Primitives/StringValidator.cs b/Src/FluentAssertions/Primitives/StringValidator.cs index fd4ad57083..0b2edd0bdf 100644 --- a/Src/FluentAssertions/Primitives/StringValidator.cs +++ b/Src/FluentAssertions/Primitives/StringValidator.cs @@ -39,12 +39,9 @@ public void Validate() Assertion = Assertion.UsingLineBreaks; } - if (ValidateAgainstSuperfluousWhitespace()) + if (ValidateAgainstSuperfluousWhitespace() && ValidateAgainstLengthDifferences()) { - if (ValidateAgainstLengthDifferences()) - { - ValidateAgainstMismatch(); - } + ValidateAgainstMismatch(); } } } From 5d65ed1714161ba49bf34084955cbf9518d93207 Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 29 Mar 2023 14:56:41 +0200 Subject: [PATCH 74/98] Added Roslynator analyzers with a customized rule set --- .editorconfig | 35 +++++++++++++++++++ .../Common/ExpressionExtensions.cs | 2 +- .../Equivalency/Execution/ObjectReference.cs | 2 +- .../Matching/MappedMemberMatchingRule.cs | 9 ++--- .../Steps/DataColumnEquivalencyStep.cs | 24 ++++++------- Src/FluentAssertions/FluentAssertions.csproj | 4 +++ .../Formatting/XElementValueFormatter.cs | 2 +- Tests/.editorconfig | 6 ++++ .../FluentAssertions.Equivalency.Specs.csproj | 4 +++ .../Events/EventAssertionSpecs.cs | 4 ++- .../FluentAssertions.Specs.csproj | 4 +++ .../Formatting/FormatterSpecs.cs | 4 +-- 12 files changed, 75 insertions(+), 25 deletions(-) diff --git a/.editorconfig b/.editorconfig index 38c686df03..b3aa99effe 100644 --- a/.editorconfig +++ b/.editorconfig @@ -302,3 +302,38 @@ resharper_blank_lines_before_multiline_statements = 1 resharper_parentheses_non_obvious_operations = arithmetic, multiplicative, equality, relational, additive resharper_parentheses_redundancy_style = remove_if_not_clarifies_precedence + +dotnet_analyzer_diagnostic.category-roslynator.severity = error + +# Remove suffix 'Async' from non-asynchronous method name. Disabled because we like that suffix for now. +dotnet_diagnostic.RCS1047.severity = none + +# Combine 'Enumerable.Where' method chain. It doesn't make it more readable in all cases. +dotnet_diagnostic.RCS1112.severity = suggestion + +# Inline local variable. +dotnet_diagnostic.RCS1124.severity = suggestion + +# Add exception to documentation comment. Nice suggestion, but we don't want to document exceptions for internal code. +dotnet_diagnostic.RCS1140.severity = suggestion + +# Use conditional access. Suggestion because it doesn't always improve readability +dotnet_diagnostic.RCS1146.severity = suggestion + +# Enum should declare explicit values. Disabled because we're not storing them. +dotnet_diagnostic.RCS1161.severity = none + +# Static member in generic type should use a type parameter. Disabled because it's not always applicable. +dotnet_diagnostic.RCS1158.severity = none + +# Add region name to #endregion. +dotnet_diagnostic.RCS1189.severity = none + +# Convert comment to documentation comment. Disabled because it also complains about SMELL/REFACTOR comments +dotnet_diagnostic.RCS1181.severity = none + +# Use Regex instance instead of static method. Disabled because it's not always worth it. +dotnet_diagnostic.RCS1186.severity = none + +# Use bit shift operator. +dotnet_diagnostic.RCS1237.severity = none diff --git a/Src/FluentAssertions/Common/ExpressionExtensions.cs b/Src/FluentAssertions/Common/ExpressionExtensions.cs index 72e62c405e..f5e586b131 100644 --- a/Src/FluentAssertions/Common/ExpressionExtensions.cs +++ b/Src/FluentAssertions/Common/ExpressionExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; diff --git a/Src/FluentAssertions/Equivalency/Execution/ObjectReference.cs b/Src/FluentAssertions/Equivalency/Execution/ObjectReference.cs index b2a5f94b2a..ae711e48ed 100644 --- a/Src/FluentAssertions/Equivalency/Execution/ObjectReference.cs +++ b/Src/FluentAssertions/Equivalency/Execution/ObjectReference.cs @@ -69,5 +69,5 @@ public override string ToString() return Invariant($"{{\"{path}\", {@object}}}"); } - public bool IsComplexType => isComplexType ?? (@object is not null && !@object.GetType().OverridesEquals()); + public bool IsComplexType => isComplexType ?? (@object?.GetType().OverridesEquals() == false); } diff --git a/Src/FluentAssertions/Equivalency/Matching/MappedMemberMatchingRule.cs b/Src/FluentAssertions/Equivalency/Matching/MappedMemberMatchingRule.cs index f2447baff2..e630ca6f55 100644 --- a/Src/FluentAssertions/Equivalency/Matching/MappedMemberMatchingRule.cs +++ b/Src/FluentAssertions/Equivalency/Matching/MappedMemberMatchingRule.cs @@ -36,13 +36,8 @@ public IMember Match(IMember expectedMember, object subject, INode parent, IEqui { var member = MemberFactory.Find(subject, subjectMemberName, parent); - if (member is null) - { - throw new ArgumentException( - $"Subject of type {typeof(TSubject)} does not have member {subjectMemberName}"); - } - - return member; + return member ?? throw new ArgumentException( + $"Subject of type {typeof(TSubject)} does not have member {subjectMemberName}"); } return null; diff --git a/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs index 69b32e25b3..54ef3e307b 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Data; using System.Diagnostics.CodeAnalysis; using System.Linq; @@ -25,20 +25,20 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc } else if (subject is null) { - if (comparands.Subject is null) - { - AssertionScope.Current.FailWith("Expected {context:DataColumn} to be non-null, but found null"); - } - else - { - AssertionScope.Current.FailWith("Expected {context:DataColumn} to be of type {0}, but found {1} instead", - expectation.GetType(), comparands.Subject.GetType()); - } + if (comparands.Subject is null) + { + AssertionScope.Current.FailWith("Expected {context:DataColumn} to be non-null, but found null"); } else { - CompareSubjectAndExpectationOfTypeDataColumn(comparands, context, nestedValidator, subject); + AssertionScope.Current.FailWith("Expected {context:DataColumn} to be of type {0}, but found {1} instead", + expectation.GetType(), comparands.Subject.GetType()); } + } + else + { + CompareSubjectAndExpectationOfTypeDataColumn(comparands, context, nestedValidator, subject); + } return EquivalencyResult.AssertionCompleted; } @@ -103,7 +103,7 @@ where match is not null return query.FirstOrDefault(); } - // Note: This list of candidate members is duplicated in the XML documentation for the + // NOTE: This list of candidate members is duplicated in the XML documentation for the // DataColumn.BeEquivalentTo extension method in DataColumnAssertions.cs. If this ever // needs to change, keep them in sync. private static readonly ISet CandidateMembers = diff --git a/Src/FluentAssertions/FluentAssertions.csproj b/Src/FluentAssertions/FluentAssertions.csproj index 844940a78a..50aebc6266 100644 --- a/Src/FluentAssertions/FluentAssertions.csproj +++ b/Src/FluentAssertions/FluentAssertions.csproj @@ -117,5 +117,9 @@ + diff --git a/Src/FluentAssertions/Formatting/XElementValueFormatter.cs b/Src/FluentAssertions/Formatting/XElementValueFormatter.cs index bde91445ff..c9176a47ce 100644 --- a/Src/FluentAssertions/Formatting/XElementValueFormatter.cs +++ b/Src/FluentAssertions/Formatting/XElementValueFormatter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using System.Xml.Linq; using FluentAssertions.Common; diff --git a/Tests/.editorconfig b/Tests/.editorconfig index 7fc6546234..58d20558d7 100644 --- a/Tests/.editorconfig +++ b/Tests/.editorconfig @@ -150,3 +150,9 @@ resharper_expression_is_always_null_highlighting = none # ReSharper properties resharper_keep_user_linebreaks = true + +# Use EventHandlerallruntime; build; native; contentfiles; analyzers; buildtransitive + + + allruntime; build; native; contentfiles; analyzers; buildtransitive. We have some special cases for testing. +dotnet_diagnostic.RCS1159.severity = error + +# Implement IComparable when implementing IComparable. Disabled since we don't want to be so strict in tests. +dotnet_diagnostic.RCS1241.severity = none diff --git a/Tests/FluentAssertions.Equivalency.Specs/FluentAssertions.Equivalency.Specs.csproj b/Tests/FluentAssertions.Equivalency.Specs/FluentAssertions.Equivalency.Specs.csproj index 84b8d40c22..43bf3e3a99 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/FluentAssertions.Equivalency.Specs.csproj +++ b/Tests/FluentAssertions.Equivalency.Specs/FluentAssertions.Equivalency.Specs.csproj @@ -79,6 +79,10 @@ + diff --git a/Src/FluentAssertions/Formatting/DateTimeOffsetValueFormatter.cs b/Src/FluentAssertions/Formatting/DateTimeOffsetValueFormatter.cs index 3fb53bd65e..9e916f4a92 100644 --- a/Src/FluentAssertions/Formatting/DateTimeOffsetValueFormatter.cs +++ b/Src/FluentAssertions/Formatting/DateTimeOffsetValueFormatter.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using FluentAssertions.Common; @@ -18,6 +19,7 @@ public bool CanHandle(object value) return value is DateTime or DateTimeOffset; } + [SuppressMessage("Design", "MA0051:Method is too long", Justification = "Needs to be refactored")] public void Format(object value, FormattedObjectGraph formattedGraph, FormattingContext context, FormatChild formatChild) { DateTimeOffset dateTimeOffset; diff --git a/Src/FluentAssertions/Formatting/MultidimensionalArrayFormatter.cs b/Src/FluentAssertions/Formatting/MultidimensionalArrayFormatter.cs index 3bf43400df..340a490edd 100644 --- a/Src/FluentAssertions/Formatting/MultidimensionalArrayFormatter.cs +++ b/Src/FluentAssertions/Formatting/MultidimensionalArrayFormatter.cs @@ -1,5 +1,6 @@ using System; using System.Collections; +using System.Diagnostics.CodeAnalysis; using System.Linq; namespace FluentAssertions.Formatting; @@ -18,6 +19,7 @@ public bool CanHandle(object value) return value is Array { Rank: >= 2 }; } + [SuppressMessage("Design", "MA0051:Method is too long", Justification = "Required refactoring")] public void Format(object value, FormattedObjectGraph formattedGraph, FormattingContext context, FormatChild formatChild) { var arr = (Array)value; diff --git a/Src/FluentAssertions/Specialized/TaskCompletionSourceAssertions.cs b/Src/FluentAssertions/Specialized/TaskCompletionSourceAssertions.cs index 6038c9c756..993e6e3ffd 100644 --- a/Src/FluentAssertions/Specialized/TaskCompletionSourceAssertions.cs +++ b/Src/FluentAssertions/Specialized/TaskCompletionSourceAssertions.cs @@ -1,5 +1,4 @@ using System; -using System.Threading; using System.Threading.Tasks; using FluentAssertions.Common; using FluentAssertions.Execution; @@ -171,40 +170,3 @@ public async Taskallruntime; build; native; contentfiles; analyzers; buildtransitive + + + allruntime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs index ec41d1ac2e..e19570513b 100644 --- a/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.ComponentModel; using System.Linq; using FluentAssertions.Events; @@ -991,7 +991,9 @@ public class C public class ClassThatRaisesEventsItself : IInheritsEventRaisingInterface { +#pragma warning disable RCS1159 public event PropertyChangedEventHandler PropertyChanged; +#pragma warning restore RCS1159 public event EventHandler InterfaceEvent; diff --git a/Tests/FluentAssertions.Specs/FluentAssertions.Specs.csproj b/Tests/FluentAssertions.Specs/FluentAssertions.Specs.csproj index 65810cb194..d20f072e19 100644 --- a/Tests/FluentAssertions.Specs/FluentAssertions.Specs.csproj +++ b/Tests/FluentAssertions.Specs/FluentAssertions.Specs.csproj @@ -82,6 +82,10 @@ + allruntime; build; native; contentfiles; analyzers; buildtransitive + + + allruntime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Tests/FluentAssertions.Specs/Formatting/FormatterSpecs.cs b/Tests/FluentAssertions.Specs/Formatting/FormatterSpecs.cs index 106ef5fff9..0f3eb9303b 100644 --- a/Tests/FluentAssertions.Specs/Formatting/FormatterSpecs.cs +++ b/Tests/FluentAssertions.Specs/Formatting/FormatterSpecs.cs @@ -691,9 +691,9 @@ public class StuffWithAField public string Description { get; set; } public string Field; -#pragma warning disable 169, CA1823, IDE0044 +#pragma warning disable 169, CA1823, IDE0044, RCS1169 private string privateField; -#pragma warning restore 169, CA1823, IDE0044 +#pragma warning restore 169, CA1823, IDE0044, RCS1169 } public class Stuff : BaseStuff From 9625e1f23773ad58d54e4b7ec4ad7bbfaed5229c Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 29 Mar 2023 15:40:24 +0200 Subject: [PATCH 75/98] Added Meziantou.Analyzer and addressed the violations --- .editorconfig | 27 +++ .../GenericCollectionAssertions.cs | 2 + .../GenericDictionaryAssertions.cs | 2 + .../SubsequentOrderingAssertions.cs | 167 ----------------- ...uentOrderingGenericCollectionAssertions.cs | 174 ++++++++++++++++++ .../Common/ExpressionExtensions.cs | 2 + Src/FluentAssertions/Equivalency/Digit.cs | 51 +++++ .../Equivalency/EqualityStrategy.cs | 24 +++ .../Equivalency/EquivalencyResult.cs | 7 + .../Equivalency/EquivalencyValidator.cs | 2 +- .../Equivalency/Execution/ObjectReference.cs | 8 +- .../Equivalency/GetSubjectId.cs | 6 + .../IEquivalencyAssertionOptions.cs | 23 --- .../Equivalency/IEquivalencyStep.cs | 6 - Src/FluentAssertions/Equivalency/INode.cs | 5 - .../Matching/MappedMemberMatchingRule.cs | 6 +- .../Matching/MappedPathMatchingRule.cs | 4 +- .../MultiDimensionalArrayEquivalencyStep.cs | 49 ----- ...elfReferenceEquivalencyAssertionOptions.cs | 2 + .../Steps/ConstraintEquivalencyStep.cs | 2 + .../Steps/DataRowEquivalencyStep.cs | 2 + .../Steps/DataSetEquivalencyStep.cs | 2 + .../Steps/DataTableEquivalencyStep.cs | 1 + .../Steps/DictionaryInterfaceInfo.cs | 3 +- .../Execution/AssertionScope.cs | 4 +- Src/FluentAssertions/FluentAssertions.csproj | 4 + .../DateTimeOffsetValueFormatter.cs | 2 + .../MultidimensionalArrayFormatter.cs | 2 + .../TaskCompletionSourceAssertions.cs | 38 ---- .../TaskCompletionSourceAssertionsBase.cs | 46 +++++ .../Xml/Equivalency/XmlReaderValidator.cs | 2 + Tests/.editorconfig | 30 +++ .../DataSpecs.cs | 2 + .../FluentAssertions.Equivalency.Specs.csproj | 4 + .../MemberMatchingSpecs.cs | 4 +- .../Events/EventAssertionSpecs.cs | 10 +- .../FluentAssertions.Specs.csproj | 6 +- 37 files changed, 425 insertions(+), 306 deletions(-) create mode 100644 Src/FluentAssertions/Collections/SubsequentOrderingGenericCollectionAssertions.cs create mode 100644 Src/FluentAssertions/Equivalency/Digit.cs create mode 100644 Src/FluentAssertions/Equivalency/EqualityStrategy.cs create mode 100644 Src/FluentAssertions/Equivalency/EquivalencyResult.cs create mode 100644 Src/FluentAssertions/Equivalency/GetSubjectId.cs create mode 100644 Src/FluentAssertions/Specialized/TaskCompletionSourceAssertionsBase.cs diff --git a/.editorconfig b/.editorconfig index b3aa99effe..f0f44a4cee 100644 --- a/.editorconfig +++ b/.editorconfig @@ -337,3 +337,30 @@ dotnet_diagnostic.RCS1186.severity = none # Use bit shift operator. dotnet_diagnostic.RCS1237.severity = none + +# Use an overload that has a IEqualityComparer or IComparer parameter +dotnet_diagnostic.MA0002.severity = suggestion + +# Use Task.ConfigureAwait(false) as the current SynchronizationContext is not needed +dotnet_diagnostic.MA0004.severity = none + +# Use string.Equals instead of Equals operator +dotnet_diagnostic.MA0006.severity = none + +# Add regex evaluation timeout +dotnet_diagnostic.MA0009.severity = none + +# Use an overload of 'ToString' that has a 'System.IFormatProvider' parameter. Already caught by CA1305. +dotnet_diagnostic.MA0011.severity = none + +# Use an overload of 'System.ArgumentException' with the parameter name. Just a suggestion since we have a bunch of justified exceptions. +dotnet_diagnostic.MA0015.severity = suggestion + +# Use an explicit StringComparer to compute hash codes +dotnet_diagnostic.MA0021.severity = none + +# Declare types in namespaces. Already caught by CA1050 +dotnet_diagnostic.MA0047.severity = none + +# Use an overload of 'GetHashCode' that has a StringComparison parameter +dotnet_diagnostic.MA0074.severity = none diff --git a/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs b/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs index 570ace5d4b..4b6cb668f3 100644 --- a/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs +++ b/Src/FluentAssertions/Collections/GenericCollectionAssertions.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Linq.Expressions; @@ -2291,6 +2292,7 @@ public AndConstraint NotContainEquivalentOf(TExpectat /// Zero or more objects to format using the placeholders in . /// /// + [SuppressMessage("Design", "MA0051:Method is too long", Justification = "Needs refactoring")] public AndConstraint is . NotContainEquivalentOf(TExpectation unexpected, Func, EquivalencyAssertionOptions> config, string because = "", params object[] becauseArgs) diff --git a/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs b/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs index bfded5b693..c14e1c948f 100644 --- a/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs +++ b/Src/FluentAssertions/Collections/GenericDictionaryAssertions.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using FluentAssertions.Common; using FluentAssertions.Equivalency; @@ -673,6 +674,7 @@ public AndConstraint Contain(params KeyValuePair[] ex /// /// /// + [SuppressMessage("Design", "MA0051:Method is too long", Justification = "Needs refactoring")] public new AndConstraint is . is empty. Contain(IEnumerable> expected, string because = "", params object[] becauseArgs) { diff --git a/Src/FluentAssertions/Collections/SubsequentOrderingAssertions.cs b/Src/FluentAssertions/Collections/SubsequentOrderingAssertions.cs index 64dfccd02b..8d1faebf3b 100644 --- a/Src/FluentAssertions/Collections/SubsequentOrderingAssertions.cs +++ b/Src/FluentAssertions/Collections/SubsequentOrderingAssertions.cs @@ -1,9 +1,6 @@ -using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using System.Linq.Expressions; -using FluentAssertions.Common; namespace FluentAssertions.Collections; @@ -16,167 +13,3 @@ public SubsequentOrderingAssertions(IEnumerable actualValue, IOrderedEnumerab { } } - -[DebuggerNonUserCode] -public class SubsequentOrderingGenericCollectionAssertions - : SubsequentOrderingGenericCollectionAssertions> - where TCollection : IEnumerable -{ - public SubsequentOrderingGenericCollectionAssertions(TCollection actualValue, IOrderedEnumerable previousOrderedEnumerable) - : base(actualValue, previousOrderedEnumerable) - { - } -} - -[DebuggerNonUserCode] -public class SubsequentOrderingGenericCollectionAssertions - : GenericCollectionAssertions - where TCollection : IEnumerable - where TAssertions : SubsequentOrderingGenericCollectionAssertions -{ - private readonly IOrderedEnumerable previousOrderedEnumerable; - private bool subsequentOrdering; - - public SubsequentOrderingGenericCollectionAssertions(TCollection actualValue, IOrderedEnumerable previousOrderedEnumerable) - : base(actualValue) - { - this.previousOrderedEnumerable = previousOrderedEnumerable; - } - - /// - /// - /// A lambda expression that references the property that should be used to determine the expected ordering. - /// - /// - /// A formatted phrase as is supported by - /// Asserts that a subsequence is ordered in ascending order according to the value of the specified - /// . - /// explaining why the assertion - /// is needed. If the phrase does not start with the word , it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in because. - /// - /// - public AndConstraint - /// Empty and single element collections are considered to be ordered both in ascending and descending order at the same time. - /// > ThenBeInAscendingOrder( - Expression> propertyExpression, string because = "", params object[] becauseArgs) - { - return ThenBeInAscendingOrder(propertyExpression, GetComparer(), because, becauseArgs); - } - - /// - /// - /// A lambda expression that references the property that should be used to determine the expected ordering. - /// - /// - /// The object that should be used to determine the expected ordering. - /// - /// - /// A formatted phrase as is supported by - /// Asserts that a subsequence is ordered in ascending order according to the value of the specified - /// and implementation. - /// explaining why the assertion - /// is needed. If the phrase does not start with the word , it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in because. - /// - /// - /// - public AndConstraint - /// Empty and single element collections are considered to be ordered both in ascending and descending order at the same time. - /// is .> ThenBeInAscendingOrder( - Expression> propertyExpression, IComparer comparer, string because = "", - params object[] becauseArgs) - { - Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), - "Cannot assert collection ordering without specifying a comparer."); - - return ThenBeOrderedBy(propertyExpression, comparer, SortOrder.Ascending, because, becauseArgs); - } - - /// - /// - /// A lambda expression that references the property that should be used to determine the expected ordering. - /// - /// - /// A formatted phrase as is supported by - /// Asserts that a subsequence is ordered in descending order according to the value of the specified - /// . - /// explaining why the assertion - /// is needed. If the phrase does not start with the word , it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in because. - /// - /// - public AndConstraint - /// Empty and single element collections are considered to be ordered both in ascending and descending order at the same time. - /// > ThenBeInDescendingOrder( - Expression> propertyExpression, string because = "", params object[] becauseArgs) - { - return ThenBeInDescendingOrder(propertyExpression, GetComparer(), because, becauseArgs); - } - - /// - /// - /// A lambda expression that references the property that should be used to determine the expected ordering. - /// - /// - /// The object that should be used to determine the expected ordering. - /// - /// - /// A formatted phrase as is supported by - /// Asserts that a subsequence is ordered in descending order according to the value of the specified - /// and implementation. - /// explaining why the assertion - /// is needed. If the phrase does not start with the word , it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in because. - /// - /// - /// - public AndConstraint - /// Empty and single element collections are considered to be ordered both in ascending and descending order at the same time. - /// is .> ThenBeInDescendingOrder( - Expression> propertyExpression, IComparer comparer, string because = "", - params object[] becauseArgs) - { - Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), - "Cannot assert collection ordering without specifying a comparer."); - - return ThenBeOrderedBy(propertyExpression, comparer, SortOrder.Descending, because, becauseArgs); - } - - private AndConstraint> ThenBeOrderedBy( - Expression> propertyExpression, - IComparer comparer, - SortOrder direction, - string because, - object[] becauseArgs) - { - subsequentOrdering = true; - return BeOrderedBy(propertyExpression, comparer, direction, because, becauseArgs); - } - - internal sealed override IOrderedEnumerable GetOrderedEnumerable( - Expression> propertyExpression, - IComparer comparer, - SortOrder direction, - ICollection unordered) - { - if (subsequentOrdering) - { - Func keySelector = propertyExpression.Compile(); - - return direction == SortOrder.Ascending - ? previousOrderedEnumerable.ThenBy(keySelector, comparer) - : previousOrderedEnumerable.ThenByDescending(keySelector, comparer); - } - - return base.GetOrderedEnumerable(propertyExpression, comparer, direction, unordered); - } -} diff --git a/Src/FluentAssertions/Collections/SubsequentOrderingGenericCollectionAssertions.cs b/Src/FluentAssertions/Collections/SubsequentOrderingGenericCollectionAssertions.cs new file mode 100644 index 0000000000..9d8291c53f --- /dev/null +++ b/Src/FluentAssertions/Collections/SubsequentOrderingGenericCollectionAssertions.cs @@ -0,0 +1,174 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Linq.Expressions; +using FluentAssertions.Common; + +namespace FluentAssertions.Collections; + +[DebuggerNonUserCode] +public class SubsequentOrderingGenericCollectionAssertions + : GenericCollectionAssertions + where TCollection : IEnumerable + where TAssertions : SubsequentOrderingGenericCollectionAssertions +{ + private readonly IOrderedEnumerable previousOrderedEnumerable; + private bool subsequentOrdering; + + public SubsequentOrderingGenericCollectionAssertions(TCollection actualValue, IOrderedEnumerable previousOrderedEnumerable) + : base(actualValue) + { + this.previousOrderedEnumerable = previousOrderedEnumerable; + } + + /// + /// + /// A lambda expression that references the property that should be used to determine the expected ordering. + /// + /// + /// A formatted phrase as is supported by + /// Asserts that a subsequence is ordered in ascending order according to the value of the specified + /// . + /// explaining why the assertion + /// is needed. If the phrase does not start with the word , it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in because. + /// + /// + public AndConstraint + /// Empty and single element collections are considered to be ordered both in ascending and descending order at the same time. + /// > ThenBeInAscendingOrder( + Expression> propertyExpression, string because = "", params object[] becauseArgs) + { + return ThenBeInAscendingOrder(propertyExpression, GetComparer(), because, becauseArgs); + } + + /// + /// + /// A lambda expression that references the property that should be used to determine the expected ordering. + /// + /// + /// The object that should be used to determine the expected ordering. + /// + /// + /// A formatted phrase as is supported by + /// Asserts that a subsequence is ordered in ascending order according to the value of the specified + /// and implementation. + /// explaining why the assertion + /// is needed. If the phrase does not start with the word , it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in because. + /// + /// + /// + public AndConstraint + /// Empty and single element collections are considered to be ordered both in ascending and descending order at the same time. + /// is .> ThenBeInAscendingOrder( + Expression> propertyExpression, IComparer comparer, string because = "", + params object[] becauseArgs) + { + Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), + "Cannot assert collection ordering without specifying a comparer."); + + return ThenBeOrderedBy(propertyExpression, comparer, SortOrder.Ascending, because, becauseArgs); + } + + /// + /// + /// A lambda expression that references the property that should be used to determine the expected ordering. + /// + /// + /// A formatted phrase as is supported by + /// Asserts that a subsequence is ordered in descending order according to the value of the specified + /// . + /// explaining why the assertion + /// is needed. If the phrase does not start with the word , it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in because. + /// + /// + public AndConstraint + /// Empty and single element collections are considered to be ordered both in ascending and descending order at the same time. + /// > ThenBeInDescendingOrder( + Expression> propertyExpression, string because = "", params object[] becauseArgs) + { + return ThenBeInDescendingOrder(propertyExpression, GetComparer(), because, becauseArgs); + } + + /// + /// + /// A lambda expression that references the property that should be used to determine the expected ordering. + /// + /// + /// The object that should be used to determine the expected ordering. + /// + /// + /// A formatted phrase as is supported by + /// Asserts that a subsequence is ordered in descending order according to the value of the specified + /// and implementation. + /// explaining why the assertion + /// is needed. If the phrase does not start with the word , it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in because. + /// + /// + /// + public AndConstraint + /// Empty and single element collections are considered to be ordered both in ascending and descending order at the same time. + /// is .> ThenBeInDescendingOrder( + Expression> propertyExpression, IComparer comparer, string because = "", + params object[] becauseArgs) + { + Guard.ThrowIfArgumentIsNull(comparer, nameof(comparer), + "Cannot assert collection ordering without specifying a comparer."); + + return ThenBeOrderedBy(propertyExpression, comparer, SortOrder.Descending, because, becauseArgs); + } + + private AndConstraint> ThenBeOrderedBy( + Expression> propertyExpression, + IComparer comparer, + SortOrder direction, + string because, + object[] becauseArgs) + { + subsequentOrdering = true; + return BeOrderedBy(propertyExpression, comparer, direction, because, becauseArgs); + } + + internal sealed override IOrderedEnumerable GetOrderedEnumerable( + Expression> propertyExpression, + IComparer comparer, + SortOrder direction, + ICollection unordered) + { + if (subsequentOrdering) + { + Func keySelector = propertyExpression.Compile(); + + IOrderedEnumerable expectation = direction == SortOrder.Ascending + ? previousOrderedEnumerable.ThenBy(keySelector, comparer) + : previousOrderedEnumerable.ThenByDescending(keySelector, comparer); + + return expectation; + } + + return base.GetOrderedEnumerable(propertyExpression, comparer, direction, unordered); + } +} + +[DebuggerNonUserCode] +public class SubsequentOrderingGenericCollectionAssertions + : SubsequentOrderingGenericCollectionAssertions> + where TCollection : IEnumerable +{ + public SubsequentOrderingGenericCollectionAssertions(TCollection actualValue, IOrderedEnumerable previousOrderedEnumerable) + : base(actualValue, previousOrderedEnumerable) + { + } +} diff --git a/Src/FluentAssertions/Common/ExpressionExtensions.cs b/Src/FluentAssertions/Common/ExpressionExtensions.cs index f5e586b131..40884bc7e9 100644 --- a/Src/FluentAssertions/Common/ExpressionExtensions.cs +++ b/Src/FluentAssertions/Common/ExpressionExtensions.cs @@ -37,8 +37,10 @@ private static MemberInfo AttemptToGetMemberInfoFromExpression(Expres /// E.g. Parent.Child.Sibling.Name. /// /// +#pragma warning disable MA0051 public static MemberPath GetMemberPath is .( this Expression> expression) +#pragma warning restore MA0051 { Guard.ThrowIfArgumentIsNull(expression, nameof(expression), "Expected an expression, but found ."); diff --git a/Src/FluentAssertions/Equivalency/Digit.cs b/Src/FluentAssertions/Equivalency/Digit.cs new file mode 100644 index 0000000000..29d8f9ddb0 --- /dev/null +++ b/Src/FluentAssertions/Equivalency/Digit.cs @@ -0,0 +1,51 @@ +using System.Collections.Generic; + +namespace FluentAssertions.Equivalency; + +internal class Digit +{ + private readonly int length; + private readonly Digit nextDigit; + private int index; + + public Digit(int length, Digit nextDigit) + { + this.length = length; + this.nextDigit = nextDigit; + } + + public int[] GetIndices() + { + var indices = new List(); + + Digit digit = this; + + while (digit is not null) + { + indices.Add(digit.index); + digit = digit.nextDigit; + } + + return indices.ToArray(); + } + + public bool Increment() + { + bool success = nextDigit?.Increment() == true; + + if (!success) + { + if (index < (length - 1)) + { + index++; + success = true; + } + else + { + index = 0; + } + } + + return success; + } +} diff --git a/Src/FluentAssertions/Equivalency/EqualityStrategy.cs b/Src/FluentAssertions/Equivalency/EqualityStrategy.cs new file mode 100644 index 0000000000..489f758920 --- /dev/null +++ b/Src/FluentAssertions/Equivalency/EqualityStrategy.cs @@ -0,0 +1,24 @@ +namespace FluentAssertions.Equivalency; + +public enum EqualityStrategy +{ + /// + Equals, + + /// + Members, + + /// + ForceEquals, + + /// + ForceMembers, +} diff --git a/Src/FluentAssertions/Equivalency/EquivalencyResult.cs b/Src/FluentAssertions/Equivalency/EquivalencyResult.cs new file mode 100644 index 0000000000..5fb0786888 --- /dev/null +++ b/Src/FluentAssertions/Equivalency/EquivalencyResult.cs @@ -0,0 +1,7 @@ +namespace FluentAssertions.Equivalency; + +public enum EquivalencyResult +{ + ContinueWithNext, + AssertionCompleted +} diff --git a/Src/FluentAssertions/Equivalency/EquivalencyValidator.cs b/Src/FluentAssertions/Equivalency/EquivalencyValidator.cs index caeeedd5a6..57ee7958bd 100644 --- a/Src/FluentAssertions/Equivalency/EquivalencyValidator.cs +++ b/Src/FluentAssertions/Equivalency/EquivalencyValidator.cs @@ -79,7 +79,7 @@ private void RunStepsUntilEquivalencyIsProven(Comparands comparands, IEquivalenc } } - throw new NotImplementedException( + throw new NotSupportedException( $"Do not know how to compare {comparands.Subject} and {comparands.Expectation}. Please report an issue through https://www.fluentassertions.com."); } } diff --git a/Src/FluentAssertions/Equivalency/Execution/ObjectReference.cs b/Src/FluentAssertions/Equivalency/Execution/ObjectReference.cs index ae711e48ed..0e5b9925cf 100644 --- a/Src/FluentAssertions/Equivalency/Execution/ObjectReference.cs +++ b/Src/FluentAssertions/Equivalency/Execution/ObjectReference.cs @@ -43,13 +43,13 @@ private string[] GetPathElements() => pathElements private bool IsParentOrChildOf(ObjectReference other) { - string[] path = GetPathElements(); + string[] elements = GetPathElements(); string[] otherPath = other.GetPathElements(); - int commonElements = Math.Min(path.Length, otherPath.Length); - int longerPathAdditionalElements = Math.Max(path.Length, otherPath.Length) - commonElements; + int commonElements = Math.Min(elements.Length, otherPath.Length); + int longerPathAdditionalElements = Math.Max(elements.Length, otherPath.Length) - commonElements; - return longerPathAdditionalElements > 0 && otherPath.Take(commonElements).SequenceEqual(path.Take(commonElements)); + return longerPathAdditionalElements > 0 && otherPath.Take(commonElements).SequenceEqual(elements.Take(commonElements)); } /// EqualityStrategy GetEqualityStrategy(Type type); } - -public enum EqualityStrategy -{ - /// - Equals, - - /// - Members, - - /// - ForceEquals, - - /// - ForceMembers, -} diff --git a/Src/FluentAssertions/Equivalency/IEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/IEquivalencyStep.cs index 39410326e1..bd55ae1774 100644 --- a/Src/FluentAssertions/Equivalency/IEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/IEquivalencyStep.cs @@ -17,9 +17,3 @@ public interface IEquivalencyStep /// EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator); } - -public enum EquivalencyResult -{ - ContinueWithNext, - AssertionCompleted -} diff --git a/Src/FluentAssertions/Equivalency/INode.cs b/Src/FluentAssertions/Equivalency/INode.cs index b4cfc1e0f3..29274315a0 100644 --- a/Src/FluentAssertions/Equivalency/INode.cs +++ b/Src/FluentAssertions/Equivalency/INode.cs @@ -80,8 +80,3 @@ public interface INode /// bool RootIsCollection { get; } } - -/// -public delegate string GetSubjectId(); diff --git a/Src/FluentAssertions/Equivalency/Matching/MappedMemberMatchingRule.cs b/Src/FluentAssertions/Equivalency/Matching/MappedMemberMatchingRule.cs index e630ca6f55..a324bf0bc3 100644 --- a/Src/FluentAssertions/Equivalency/Matching/MappedMemberMatchingRule.cs +++ b/Src/FluentAssertions/Equivalency/Matching/MappedMemberMatchingRule.cs @@ -17,12 +17,12 @@ public MappedMemberMatchingRule(string expectationMemberName, string subjectMemb { if (Regex.IsMatch(expectationMemberName, @"[\.\[\]]")) { - throw new ArgumentException("The expectation's member name cannot be a nested path"); + throw new ArgumentException("The expectation's member name cannot be a nested path", nameof(expectationMemberName)); } if (Regex.IsMatch(subjectMemberName, @"[\.\[\]]")) { - throw new ArgumentException("The subject's member name cannot be a nested path"); + throw new ArgumentException("The subject's member name cannot be a nested path", nameof(subjectMemberName)); } this.expectationMemberName = expectationMemberName; @@ -36,7 +36,7 @@ public IMember Match(IMember expectedMember, object subject, INode parent, IEqui { var member = MemberFactory.Find(subject, subjectMemberName, parent); - return member ?? throw new ArgumentException( + return member ?? throw new MissingMemberException( $"Subject of type {typeof(TSubject)} does not have member {subjectMemberName}"); } diff --git a/Src/FluentAssertions/Equivalency/Matching/MappedPathMatchingRule.cs b/Src/FluentAssertions/Equivalency/Matching/MappedPathMatchingRule.cs index 9559c48f41..f612908757 100644 --- a/Src/FluentAssertions/Equivalency/Matching/MappedPathMatchingRule.cs +++ b/Src/FluentAssertions/Equivalency/Matching/MappedPathMatchingRule.cs @@ -1,4 +1,4 @@ -using System; +using System; using FluentAssertions.Common; namespace FluentAssertions.Equivalency.Matching; @@ -57,7 +57,7 @@ public IMember Match(IMember expectedMember, object subject, INode parent, IEqui if (member is null) { - throw new ArgumentException( + throw new MissingMemberException( $"Subject of type {subject?.GetType().Name} does not have member {subjectPath.MemberName}"); } diff --git a/Src/FluentAssertions/Equivalency/MultiDimensionalArrayEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/MultiDimensionalArrayEquivalencyStep.cs index b7fcd7acb6..27bb4af3fd 100644 --- a/Src/FluentAssertions/Equivalency/MultiDimensionalArrayEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/MultiDimensionalArrayEquivalencyStep.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Linq; using FluentAssertions.Execution; @@ -99,51 +98,3 @@ private static bool HaveSameRank(object subject, Array expectation) subjectAsArray.Rank); } } - -internal class Digit -{ - private readonly int length; - private readonly Digit nextDigit; - private int index; - - public Digit(int length, Digit nextDigit) - { - this.length = length; - this.nextDigit = nextDigit; - } - - public int[] GetIndices() - { - var indices = new List + /// The object overrides , so use that. + /// + /// The object does not seem to override , so compare by members + /// + /// Compare using , whether or not the object overrides it. + /// + /// Compare the members, regardless of an override exists or not. + /// diff --git a/Src/FluentAssertions/Equivalency/GetSubjectId.cs b/Src/FluentAssertions/Equivalency/GetSubjectId.cs new file mode 100644 index 0000000000..a564a1a36d --- /dev/null +++ b/Src/FluentAssertions/Equivalency/GetSubjectId.cs @@ -0,0 +1,6 @@ +namespace FluentAssertions.Equivalency; + +/// +public delegate string GetSubjectId(); diff --git a/Src/FluentAssertions/Equivalency/IEquivalencyAssertionOptions.cs b/Src/FluentAssertions/Equivalency/IEquivalencyAssertionOptions.cs index b9f49c945e..b0ceeb4e2c 100644 --- a/Src/FluentAssertions/Equivalency/IEquivalencyAssertionOptions.cs +++ b/Src/FluentAssertions/Equivalency/IEquivalencyAssertionOptions.cs @@ -99,26 +99,3 @@ public interface IEquivalencyAssertionOptions /// +/// Allows deferred fetching of the subject ID. +/// - /// The object overrides , so use that. - /// - /// The object does not seem to override , so compare by members - /// - /// Compare using , whether or not the object overrides it. - /// - /// Compare the members, regardless of an override exists or not. - /// -/// Allows deferred fetching of the subject ID. -/// (); - - Digit digit = this; - - while (digit is not null) - { - indices.Add(digit.index); - digit = digit.nextDigit; - } - - return indices.ToArray(); - } - - public bool Increment() - { - bool success = nextDigit?.Increment() == true; - - if (!success) - { - if (index < (length - 1)) - { - index++; - success = true; - } - else - { - index = 0; - } - } - - return success; - } -} diff --git a/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs b/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs index cdc90381db..5e4b6dd0af 100644 --- a/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs +++ b/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Linq.Expressions; @@ -718,6 +719,7 @@ public TSelf WithoutAutoConversionFor(Expression> predic /// A string that represents the current object. /// /// + [SuppressMessage("Design", "MA0051:Method is too long")] public override string ToString() { var builder = new StringBuilder(); diff --git a/Src/FluentAssertions/Equivalency/Steps/ConstraintEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/ConstraintEquivalencyStep.cs index b6568dffad..6ec97c7cdc 100644 --- a/Src/FluentAssertions/Equivalency/Steps/ConstraintEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/ConstraintEquivalencyStep.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Data; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; using FluentAssertions.Execution; @@ -135,6 +136,7 @@ private static void CompareConstraints(IEquivalencyValidator parent, IEquivalenc } } + [SuppressMessage("Design", "MA0051:Method is too long", Justification = "Needs to be refactored")] private static void CompareConstraints(IEquivalencyValidator parent, IEquivalencyValidationContext context, ForeignKeyConstraint subject, ForeignKeyConstraint expectation, Dictionary2 selectedMembers) { diff --git a/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs index ef25da0db8..38240907a8 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataRowEquivalencyStep.cs @@ -86,6 +86,8 @@ private static void CompareScalarProperties(DataRow subject, DataRow expectation } } + [SuppressMessage("Maintainability", "AV1561:Signature contains too many parameters", Justification = "Needs to be refactored")] + [SuppressMessage("Design", "MA0051:Method is too long", Justification = "Needs to be refactored")] private static void CompareFieldValues(IEquivalencyValidationContext context, IEquivalencyValidator parent, DataRow subject, DataRow expectation, DataEquivalencyAssertionOptions dataSetConfig, DataEquivalencyAssertionOptions dataTableConfig, DataEquivalencyAssertionOptions dataRowConfig) diff --git a/Src/FluentAssertions/Equivalency/Steps/DataSetEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataSetEquivalencyStep.cs index b460d78923..6a6c2dea3b 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataSetEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataSetEquivalencyStep.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Data; +using System.Diagnostics.CodeAnalysis; using System.Linq; using FluentAssertions.Data; using FluentAssertions.Execution; @@ -55,6 +56,7 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc return EquivalencyResult.AssertionCompleted; } + [SuppressMessage("Design", "MA0051:Method is too long")] private static void CompareScalarProperties(DataSet subject, DataSet expectation, Dictionary selectedMembers) { // Note: The members here are listed in the XML documentation for the DataSet.BeEquivalentTo extension diff --git a/Src/FluentAssertions/Equivalency/Steps/DataTableEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataTableEquivalencyStep.cs index 4caefeab9d..1f41381272 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataTableEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataTableEquivalencyStep.cs @@ -60,6 +60,7 @@ protected override EquivalencyResult OnHandle(Comparands comparands, IEquivalenc return EquivalencyResult.AssertionCompleted; } + [SuppressMessage("Design", "MA0051:Method is too long")] private static void CompareScalarProperties(DataTable subject, DataTable expectation, Dictionary selectedMembers) { diff --git a/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs b/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs index 8d221cddce..622bf11b7a 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs @@ -47,7 +47,8 @@ public static bool TryGetFrom(Type target, string role, out DictionaryInterfaceI { throw new ArgumentException( $"The {role} implements multiple dictionary types. It is not known which type should be " + - $"use for equivalence.{Environment.NewLine}The following IDictionary interfaces are implemented: {string.Join(", ", (IEnumerable)interfaces)}"); + $"use for equivalence.{Environment.NewLine}The following IDictionary interfaces are implemented: " + + $"{string.Join(", ", (IEnumerable)interfaces)}", nameof(role)); } if (interfaces.Length == 1) diff --git a/Src/FluentAssertions/Execution/AssertionScope.cs b/Src/FluentAssertions/Execution/AssertionScope.cs index 0b0be13621..9c97d781fd 100644 --- a/Src/FluentAssertions/Execution/AssertionScope.cs +++ b/Src/FluentAssertions/Execution/AssertionScope.cs @@ -191,10 +191,10 @@ public AssertionScope WithExpectation(string message, params object[] args) expectation = () => { var messageBuilder = new MessageBuilder(FormattingOptions); - string reason = localReason?.Invoke() ?? string.Empty; + string actualReason = localReason?.Invoke() ?? string.Empty; string identifier = GetIdentifier(); - return messageBuilder.Build(message, args, reason, contextData, identifier, fallbackIdentifier); + return messageBuilder.Build(message, args, actualReason, contextData, identifier, fallbackIdentifier); }; return this; diff --git a/Src/FluentAssertions/FluentAssertions.csproj b/Src/FluentAssertions/FluentAssertions.csproj index 50aebc6266..e3f47fe0fd 100644 --- a/Src/FluentAssertions/FluentAssertions.csproj +++ b/Src/FluentAssertions/FluentAssertions.csproj @@ -121,5 +121,9 @@ + allruntime; build; native; contentfiles; analyzers; buildtransitive + + + allruntime; build; native; contentfiles; analyzers; buildtransitive>> NotCompleteW return new AndConstraint>(this); } } - -/// -public class TaskCompletionSourceAssertionsBase -{ - protected TaskCompletionSourceAssertionsBase(IClock clock) - { - Clock = clock ?? throw new ArgumentNullException(nameof(clock)); - } - - private protected IClock Clock { get; } - - /// -/// Implements base functionality for assertions on TaskCompletionSource. -/// - public override bool Equals(object obj) => - throw new NotSupportedException("Equals is not part of Fluent Assertions. Did you mean CompleteWithinAsync() instead?"); - - /// - private protected async Task - /// Monitors the specified task whether it completes withing the remaining time span. - /// CompletesWithinTimeoutAsync(Task target, TimeSpan remainingTime) - { - using var timeoutCancellationTokenSource = new CancellationTokenSource(); - - Task completedTask = - await Task.WhenAny(target, Clock.DelayAsync(remainingTime, timeoutCancellationTokenSource.Token)); - - if (completedTask != target) - { - return false; - } - - // cancel the clock - timeoutCancellationTokenSource.Cancel(); - return true; - } -} diff --git a/Src/FluentAssertions/Specialized/TaskCompletionSourceAssertionsBase.cs b/Src/FluentAssertions/Specialized/TaskCompletionSourceAssertionsBase.cs new file mode 100644 index 0000000000..74393482c7 --- /dev/null +++ b/Src/FluentAssertions/Specialized/TaskCompletionSourceAssertionsBase.cs @@ -0,0 +1,46 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Threading; +using System.Threading.Tasks; +using FluentAssertions.Common; + +namespace FluentAssertions.Specialized; + +#pragma warning disable CS0659 +/// +public class TaskCompletionSourceAssertionsBase +{ + protected TaskCompletionSourceAssertionsBase(IClock clock) + { + Clock = clock ?? throw new ArgumentNullException(nameof(clock)); + } + + private protected IClock Clock { get; } + + /// +/// Implements base functionality for assertions on TaskCompletionSource. +/// + [SuppressMessage("Design", "CA1065:Do not raise exceptions in unexpected locations")] + public override bool Equals(object obj) => + throw new NotSupportedException("Equals is not part of Fluent Assertions. Did you mean CompleteWithinAsync() instead?"); + + /// + private protected async Task + /// Monitors the specified task whether it completes withing the remaining time span. + /// CompletesWithinTimeoutAsync(Task target, TimeSpan remainingTime) + { + using var timeoutCancellationTokenSource = new CancellationTokenSource(); + + Task completedTask = + await Task.WhenAny(target, Clock.DelayAsync(remainingTime, timeoutCancellationTokenSource.Token)); + + if (completedTask != target) + { + return false; + } + + // cancel the clock + timeoutCancellationTokenSource.Cancel(); + return true; + } +} diff --git a/Src/FluentAssertions/Xml/Equivalency/XmlReaderValidator.cs b/Src/FluentAssertions/Xml/Equivalency/XmlReaderValidator.cs index cc89aab3bf..1ef53ed148 100644 --- a/Src/FluentAssertions/Xml/Equivalency/XmlReaderValidator.cs +++ b/Src/FluentAssertions/Xml/Equivalency/XmlReaderValidator.cs @@ -38,7 +38,9 @@ public void Validate(bool shouldBeEquivalent) } } +#pragma warning disable MA0051 private Failure Validate() +#pragma warning restore MA0051 { if (subjectReader is null && expectationReader is null) { diff --git a/Tests/.editorconfig b/Tests/.editorconfig index 58d20558d7..18c30fb84d 100644 --- a/Tests/.editorconfig +++ b/Tests/.editorconfig @@ -156,3 +156,33 @@ dotnet_diagnostic.RCS1159.severity = error # Implement IComparable when implementing IComparable. Disabled since we don't want to be so strict in tests. dotnet_diagnostic.RCS1241.severity = none + +# Use Array.Empty(). We don't care. +dotnet_diagnostic.MA0005.severity = none + +# 'System.BadImageFormatException' is a reserved exception type. Don't care. +dotnet_diagnostic.MA0012.severity = none + +# Do not raise System.ApplicationException type +dotnet_diagnostic.MA0014.severity = none + +# Prefer returning collection abstraction instead of implementation +dotnet_diagnostic.MA0016.severity = none + +# Implement the functionality (or raise NotSupportedException or PlatformNotSupportedException). We do this on purpose in tests. +dotnet_diagnostic.MA0025.severity = none + +# Fix TODO comment. +dotnet_diagnostic.MA0026.severity = none + +# File name must match type name. Too many purposeful violations. +dotnet_diagnostic.MA0048.severity = none + +# Method is too long. In tests, we tend to go beyond the limit +dotnet_diagnostic.MA0051.severity = none + +# A class that implements IComparable should also implement IEquatable. Don't care about this. +dotnet_diagnostic.MA0096.severity = none + +# A class that implements IComparable or IComparable should override comparison operators. Don't care about this. +dotnet_diagnostic.MA0097.severity = none \ No newline at end of file diff --git a/Tests/FluentAssertions.Equivalency.Specs/DataSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/DataSpecs.cs index 08c7fe3f7b..f9a4e64a73 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/DataSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/DataSpecs.cs @@ -370,7 +370,9 @@ public TypedDataSetSubclass(TypedDataSet copyFrom, bool swapTableOrder = false, Namespace = copyFrom.Namespace; Prefix = copyFrom.Prefix; RemotingFormat = copyFrom.RemotingFormat; +#pragma warning disable MA0056 SchemaSerializationMode = copyFrom.SchemaSerializationMode; +#pragma warning restore MA0056 CopyTable( from: copyFrom.TypedDataTable1, diff --git a/Tests/FluentAssertions.Equivalency.Specs/FluentAssertions.Equivalency.Specs.csproj b/Tests/FluentAssertions.Equivalency.Specs/FluentAssertions.Equivalency.Specs.csproj index 43bf3e3a99..6783db4a69 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/FluentAssertions.Equivalency.Specs.csproj +++ b/Tests/FluentAssertions.Equivalency.Specs/FluentAssertions.Equivalency.Specs.csproj @@ -83,6 +83,10 @@ + allruntime; build; native; contentfiles; analyzers; buildtransitive + + + allruntime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Tests/FluentAssertions.Equivalency.Specs/MemberMatchingSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/MemberMatchingSpecs.cs index f901358434..7808394542 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/MemberMatchingSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/MemberMatchingSpecs.cs @@ -340,7 +340,7 @@ public void Mapping_to_a_non_existing_subject_member_is_not_allowed() // Assert act.Should() - .Throw() + .Throw() .WithMessage("*not have member NonExistingProperty*"); } @@ -425,7 +425,7 @@ public void The_member_name_on_a_nested_type_mapping_must_be_a_valid_member() // Assert act.Should() - .Throw() + .Throw() .WithMessage("*does not have member NonExistingProperty*"); } diff --git a/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs index e19570513b..c211c9f0b8 100644 --- a/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Events/EventAssertionSpecs.cs @@ -973,7 +973,9 @@ public void One_matching_argument_type_with_two_or_more_parameters_matching_a_mi public class A { +#pragma warning disable MA0046 public event EventHandler Event; +#pragma warning restore MA0046 public void OnEvent(object o) { @@ -1064,7 +1066,9 @@ public class EventRaisingClass : INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged = (_, _) => { }; +#pragma warning disable MA0046 public event Action NonConventionalEvent = (_, _, _) => { }; +#pragma warning restore MA0046 public void RaiseNonConventionalEvent(string first, int second, string third) { @@ -1073,9 +1077,9 @@ public void RaiseNonConventionalEvent(string first, int second, string third) public void RaiseEventWithoutSender() { -#pragma warning disable AV1235 // 'sender' is deliberately null +#pragma warning disable AV1235, MA0091 // 'sender' is deliberately null PropertyChanged(null, new PropertyChangedEventArgs("")); -#pragma warning restore AV1235 +#pragma warning restore AV1235, MA0091 } public void RaiseEventWithSender() @@ -1085,7 +1089,9 @@ public void RaiseEventWithSender() public void RaiseEventWithSpecificSender(object sender) { +#pragma warning disable MA0091 PropertyChanged(sender, new PropertyChangedEventArgs("")); +#pragma warning restore MA0091 } public void RaiseEventWithSenderAndPropertyName(string propertyName) diff --git a/Tests/FluentAssertions.Specs/FluentAssertions.Specs.csproj b/Tests/FluentAssertions.Specs/FluentAssertions.Specs.csproj index d20f072e19..1535076957 100644 --- a/Tests/FluentAssertions.Specs/FluentAssertions.Specs.csproj +++ b/Tests/FluentAssertions.Specs/FluentAssertions.Specs.csproj @@ -1,4 +1,4 @@ - + @@ -86,6 +86,10 @@ + allruntime; build; native; contentfiles; analyzers; buildtransitive + + + allruntime; build; native; contentfiles; analyzers; buildtransitive From 94512f8daccf1ca78d0c22e75c0a657430f761c0 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Thu, 30 Mar 2023 15:45:19 +0200 Subject: [PATCH 76/98] Use simple string.Replace --- Src/FluentAssertions/Execution/MessageBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/FluentAssertions/Execution/MessageBuilder.cs b/Src/FluentAssertions/Execution/MessageBuilder.cs index aed96ac9a6..27f1b82e2a 100644 --- a/Src/FluentAssertions/Execution/MessageBuilder.cs +++ b/Src/FluentAssertions/Execution/MessageBuilder.cs @@ -33,7 +33,7 @@ public MessageBuilder(FormattingOptions formattingOptions) public string Build(string message, object[] messageArgs, string reason, ContextDataItems contextData, string identifier, string fallbackIdentifier) { - message = Regex.Replace(message, "{reason}", SanitizeReason(reason)); + message = message.Replace("{reason}", SanitizeReason(reason), StringComparison.Ordinal); message = SubstituteIdentifier(message, identifier?.EscapePlaceholders(), fallbackIdentifier); From ccbd5927130a9b0d6244627e3bfb0e0cab2cf3e7 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Thu, 30 Mar 2023 15:49:32 +0200 Subject: [PATCH 77/98] Explicit ACII digit matching Per default \d and [0-9] is not the same. See https://www.meziantou.net/dotnet-regex-d-is-different-from-0-9.htm --- .../Common/MemberPathSegmentEqualityComparer.cs | 2 +- Src/FluentAssertions/Common/StringExtensions.cs | 4 ++-- Src/FluentAssertions/Equivalency/Node.cs | 2 +- .../Equivalency/Ordering/PathBasedOrderingRule.cs | 2 +- .../Equivalency/Selection/SelectMemberByPathSelectionRule.cs | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Src/FluentAssertions/Common/MemberPathSegmentEqualityComparer.cs b/Src/FluentAssertions/Common/MemberPathSegmentEqualityComparer.cs index ec2b75d05e..edf54813c7 100644 --- a/Src/FluentAssertions/Common/MemberPathSegmentEqualityComparer.cs +++ b/Src/FluentAssertions/Common/MemberPathSegmentEqualityComparer.cs @@ -12,7 +12,7 @@ namespace FluentAssertions.Common; internal class MemberPathSegmentEqualityComparer : IEqualityComparer { private const string AnyIndexQualifier = "*"; - private static readonly Regex IndexQualifierRegex = new(@"^\d+$"); + private static readonly Regex IndexQualifierRegex = new("^[0-9]+$"); /// public static string WithoutSpecificCollectionIndices(this string indexedPath) { - return Regex.Replace(indexedPath, @"\[\d+\]", "[]"); + return Regex.Replace(indexedPath, @"\[[0-9]+\]", "[]"); } /// public static bool ContainsSpecificCollectionIndex(this string indexedPath) { - return Regex.IsMatch(indexedPath, @"\[\d+\]"); + return Regex.IsMatch(indexedPath, @"\[[0-9]+\]"); } /// /// Compares two segments of a . diff --git a/Src/FluentAssertions/Common/StringExtensions.cs b/Src/FluentAssertions/Common/StringExtensions.cs index 162a093c91..73abf90857 100644 --- a/Src/FluentAssertions/Common/StringExtensions.cs +++ b/Src/FluentAssertions/Common/StringExtensions.cs @@ -47,7 +47,7 @@ public static string IndexedSegmentAt(this string value, int index) /// @@ -55,7 +55,7 @@ public static string WithoutSpecificCollectionIndices(this string indexedPath) /// diff --git a/Src/FluentAssertions/Equivalency/Node.cs b/Src/FluentAssertions/Equivalency/Node.cs index c9bb11334d..145d8291f7 100644 --- a/Src/FluentAssertions/Equivalency/Node.cs +++ b/Src/FluentAssertions/Equivalency/Node.cs @@ -8,7 +8,7 @@ namespace FluentAssertions.Equivalency; public class Node : INode { - private static readonly Regex MatchFirstIndex = new(@"^\[\d+\]$"); + private static readonly Regex MatchFirstIndex = new(@"^\[[0-9]+\]$"); private string path; private string name; diff --git a/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs b/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs index c9f03fdc5b..dfe93669c8 100644 --- a/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs +++ b/Src/FluentAssertions/Equivalency/Ordering/PathBasedOrderingRule.cs @@ -45,7 +45,7 @@ private static bool ContainsIndexingQualifiers(string path) private string RemoveInitialIndexQualifier(string sourcePath) { - var indexQualifierRegex = new Regex(@"^\[\d+]\."); + var indexQualifierRegex = new Regex(@"^\[[0-9]+]\."); if (!indexQualifierRegex.IsMatch(path)) { diff --git a/Src/FluentAssertions/Equivalency/Selection/SelectMemberByPathSelectionRule.cs b/Src/FluentAssertions/Equivalency/Selection/SelectMemberByPathSelectionRule.cs index eb4adeeb31..7f8d5f8dfd 100644 --- a/Src/FluentAssertions/Equivalency/Selection/SelectMemberByPathSelectionRule.cs +++ b/Src/FluentAssertions/Equivalency/Selection/SelectMemberByPathSelectionRule.cs @@ -50,7 +50,7 @@ private static bool ContainsIndexingQualifiers(string path) private static string RemoveIndexQualifiers(string path) { - Match match = new Regex(@"^\[\d+]").Match(path); + Match match = new Regex(@"^\[[0-9]+]").Match(path); if (match.Success) { From 1829408210c23801ee8664a43e0852492c4a21df Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 1 Apr 2023 13:21:02 +0200 Subject: [PATCH 78/98] Make Excluding() work on nested collections if root is a collection (#2135) * #1989 Remove ContainsIndexingQualifiers check to make Excluding() work on nested collections if root is a collection * #1989 Added test case for For().Exclude() * #1989 Adapted releases.md * #1989 Refactor rename RemoveRootIndexQualifier * Update docs/_pages/releases.md Co-authored-by: Jonas Nyrup --------- Co-authored-by: Jonas Nyrup --- .../ExcludeMemberByPathSelectionRule.cs | 2 - .../IncludeMemberByPathSelectionRule.cs | 1 - .../SelectMemberByPathSelectionRule.cs | 30 +---- .../CollectionSpecs.cs | 51 +++++++ .../SelectionRulesSpecs.cs | 127 ++++++++++++++++++ docs/_pages/releases.md | 2 + 6 files changed, 182 insertions(+), 31 deletions(-) diff --git a/Src/FluentAssertions/Equivalency/Selection/ExcludeMemberByPathSelectionRule.cs b/Src/FluentAssertions/Equivalency/Selection/ExcludeMemberByPathSelectionRule.cs index 56b3d41093..4430f4eeec 100644 --- a/Src/FluentAssertions/Equivalency/Selection/ExcludeMemberByPathSelectionRule.cs +++ b/Src/FluentAssertions/Equivalency/Selection/ExcludeMemberByPathSelectionRule.cs @@ -11,7 +11,6 @@ internal class ExcludeMemberByPathSelectionRule : SelectMemberByPathSelectionRul private MemberPath memberToExclude; public ExcludeMemberByPathSelectionRule(MemberPath pathToExclude) - : base(pathToExclude.ToString()) { memberToExclude = pathToExclude; } @@ -26,7 +25,6 @@ protected override void AddOrRemoveMembersFrom(List selectedMembers, IN public void AppendPath(MemberPath nextPath) { memberToExclude = memberToExclude.AsParentCollectionOf(nextPath); - SetSelectedPath(memberToExclude.ToString()); } public override string ToString() diff --git a/Src/FluentAssertions/Equivalency/Selection/IncludeMemberByPathSelectionRule.cs b/Src/FluentAssertions/Equivalency/Selection/IncludeMemberByPathSelectionRule.cs index 5a4990623f..c521d7ddc1 100644 --- a/Src/FluentAssertions/Equivalency/Selection/IncludeMemberByPathSelectionRule.cs +++ b/Src/FluentAssertions/Equivalency/Selection/IncludeMemberByPathSelectionRule.cs @@ -12,7 +12,6 @@ internal class IncludeMemberByPathSelectionRule : SelectMemberByPathSelectionRul private readonly MemberPath memberToInclude; public IncludeMemberByPathSelectionRule(MemberPath pathToInclude) - : base(pathToInclude.ToString()) { memberToInclude = pathToInclude; } diff --git a/Src/FluentAssertions/Equivalency/Selection/SelectMemberByPathSelectionRule.cs b/Src/FluentAssertions/Equivalency/Selection/SelectMemberByPathSelectionRule.cs index 7f8d5f8dfd..77b9507bbb 100644 --- a/Src/FluentAssertions/Equivalency/Selection/SelectMemberByPathSelectionRule.cs +++ b/Src/FluentAssertions/Equivalency/Selection/SelectMemberByPathSelectionRule.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; @@ -7,32 +6,12 @@ namespace FluentAssertions.Equivalency.Selection; internal abstract class SelectMemberByPathSelectionRule : IMemberSelectionRule { - private string selectedPath; - - protected SelectMemberByPathSelectionRule(string selectedPath) - { - this.selectedPath = selectedPath; - } - public virtual bool IncludesMembers => false; - protected void SetSelectedPath(string path) - { - selectedPath = path; - } - public IEnumerable SelectMembers(INode currentNode, IEnumerable selectedMembers, MemberSelectionContext context) { - string currentPath = currentNode.PathAndName; - - // If we're part of a collection comparison, the selected path will not include an index, - // so we need to remove it from the current node as well. - if (!ContainsIndexingQualifiers(selectedPath)) - { - currentPath = RemoveIndexQualifiers(currentPath); - } - + var currentPath = RemoveRootIndexQualifier(currentNode.PathAndName); var members = selectedMembers.ToList(); AddOrRemoveMembersFrom(members, currentNode, currentPath, context); @@ -43,12 +22,7 @@ protected abstract void AddOrRemoveMembersFrom(List selectedMembers, INode parent, string parentPath, MemberSelectionContext context); - private static bool ContainsIndexingQualifiers(string path) - { - return path.Contains('[', StringComparison.Ordinal) && path.Contains(']', StringComparison.Ordinal); - } - - private static string RemoveIndexQualifiers(string path) + private static string RemoveRootIndexQualifier(string path) { Match match = new Regex(@"^\[[0-9]+]").Match(path); diff --git a/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs index 5e539ab959..6fa68a230a 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs @@ -597,6 +597,57 @@ public void When_property_in_collection_is_excluded_it_should_not_throw() .Exclude(x => x.Number)); } + [Fact] + public void When_property_in_collection_is_excluded_it_should_not_throw_if_root_is_a_collection() + { + // Arrange + var subject = new + { + Level = new + { + Collection = new[] + { + new + { + Number = 1, + Text = "Text" + }, + new + { + Number = 2, + Text = "Actual" + } + } + } + }; + + var expected = new + { + Level = new + { + Collection = new[] + { + new + { + Number = 1, + Text = "Text" + }, + new + { + Number = 3, + Text = "Actual" + } + } + } + }; + + // Act / Assert + new[] { subject }.Should().BeEquivalentTo(new[] { expected }, + options => options + .For(x => x.Level.Collection) + .Exclude(x => x.Number)); + } + [Fact] public void When_collection_in_collection_is_excluded_it_should_not_throw() { diff --git a/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs index b81c7a68d8..04296b8f86 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/SelectionRulesSpecs.cs @@ -622,6 +622,30 @@ public void When_only_the_excluded_property_doesnt_match_it_should_not_throw() .Excluding(d => d.Id)); } + [Fact] + public void When_only_the_excluded_property_doesnt_match_it_should_not_throw_if_root_is_a_collection() + { + // Arrange + var dto = new Customer + { + Age = 36, + Birthdate = new DateTime(1973, 9, 20), + Name = "John" + }; + + var customer = new Customer + { + Age = 36, + Birthdate = new DateTime(1973, 9, 20), + Name = "Dennis" + }; + + // Act / Assert + new[] { dto }.Should().BeEquivalentTo(new[] { customer }, options => options + .Excluding(d => d.Name) + .Excluding(d => d.Id)); + } + [Fact] [SuppressMessage("ReSharper", "StringLiteralTypo")] public void When_excluding_members_it_should_pass_if_only_the_excluded_members_are_different() @@ -742,6 +766,41 @@ public void When_a_deeply_nested_property_with_a_value_mismatch_is_excluded_it_s act.Should().NotThrow(); } + [Fact] + public void When_a_deeply_nested_property_with_a_value_mismatch_is_excluded_it_should_not_throw_if_root_is_a_collection() + { + // Arrange + var subject = new Root + { + Text = "Root", + Level = new Level1 + { + Text = "Level1", + Level = new Level2 + { + Text = "Mismatch" + } + } + }; + + var expected = new RootDto + { + Text = "Root", + Level = new Level1Dto + { + Text = "Level1", + Level = new Level2Dto + { + Text = "Level2" + } + } + }; + + // Act / Assert + new[] { subject }.Should().BeEquivalentTo(new[] { expected }, + options => options.Excluding(r => r.Level.Level.Text)); + } + [Fact] public void When_a_property_with_a_value_mismatch_is_excluded_using_a_predicate_it_should_not_throw() { @@ -922,6 +981,74 @@ public void When_excluding_properties_via_non_array_indexers_it_should_exclude_t act.Should().NotThrow(); } + [Fact] + public void + When_excluding_properties_via_non_array_indexers_it_should_exclude_the_specified_paths_if_root_is_a_collection() + { + // Arrange + var subject = new + { + List = new[] + { + new + { + Foo = 1, + Bar = 2 + }, + new + { + Foo = 3, + Bar = 4 + } + }.ToList(), + Dictionary = new Dictionary + { + ["Foo"] = new() + { + Value = 1 + }, + ["Bar"] = new() + { + Value = 2 + } + } + }; + + var expected = new + { + List = new[] + { + new + { + Foo = 1, + Bar = 2 + }, + new + { + Foo = 2, + Bar = 4 + } + }.ToList(), + Dictionary = new Dictionary + { + ["Foo"] = new() + { + Value = 1 + }, + ["Bar"] = new() + { + Value = 3 + } + } + }; + + // Act / Assert + new[] { subject }.Should().BeEquivalentTo(new[] { expected }, + options => options + .Excluding(x => x.List[1].Foo) + .Excluding(x => x.Dictionary["Bar"].Value)); + } + [Fact] public void When_excluding_properties_via_non_array_indexers_it_should_not_exclude_paths_with_different_indexes() { diff --git a/docs/_pages/releases.md b/docs/_pages/releases.md index 9d023592c4..1947bb1e99 100644 --- a/docs/_pages/releases.md +++ b/docs/_pages/releases.md @@ -20,6 +20,8 @@ sidebar: * Improved robustness of several assertions when they're wrapped in an `AssertionScope` - [#2133](https://github.com/fluentassertions/fluentassertions/pull/2133) * The maximum depth `BeEquivalentTo` uses for recursive comparisons was 9 instead of the expected 10 - [#2145](https://github.com/fluentassertions/fluentassertions/pull/2145) +* Fixed `.Excluding()` and `.For().Exclude()` not working if root is a collection - [#2135](https://github.com/fluentassertions/fluentassertions/pull/2135) + ## 6.10.0 ### Fixes From a026a8c3eaaabe807121bf9ed3d020d97fbda07f Mon Sep 17 00:00:00 2001 From: Dennis Doomen Date: Sat, 1 Apr 2023 20:52:35 +0200 Subject: [PATCH 79/98] Some minor internal naming changes that I found while using the code in a workshop (#2164) --- .../Equivalency/EquivalencyValidationContext.cs | 4 ++-- .../Equivalency/EquivalencyValidator.cs | 15 +++++++-------- .../Execution/CyclicReferenceDetector.cs | 2 +- .../Equivalency/Execution/ObjectReference.cs | 8 ++++---- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Src/FluentAssertions/Equivalency/EquivalencyValidationContext.cs b/Src/FluentAssertions/Equivalency/EquivalencyValidationContext.cs index 9cc7fa28f7..5ebbe576b1 100644 --- a/Src/FluentAssertions/Equivalency/EquivalencyValidationContext.cs +++ b/Src/FluentAssertions/Equivalency/EquivalencyValidationContext.cs @@ -71,10 +71,10 @@ public IEquivalencyValidationContext Clone() public bool IsCyclicReference(object expectation) { - bool isComplexType = expectation is not null && Options.GetEqualityStrategy(expectation.GetType()) + bool compareByMembers = expectation is not null && Options.GetEqualityStrategy(expectation.GetType()) is EqualityStrategy.Members or EqualityStrategy.ForceMembers; - var reference = new ObjectReference(expectation, CurrentNode.PathAndName, isComplexType); + var reference = new ObjectReference(expectation, CurrentNode.PathAndName, compareByMembers); return CyclicReferenceDetector.IsCyclicReference(reference, Options.CyclicReferenceHandling, Reason); } diff --git a/Src/FluentAssertions/Equivalency/EquivalencyValidator.cs b/Src/FluentAssertions/Equivalency/EquivalencyValidator.cs index 57ee7958bd..332c2a185f 100644 --- a/Src/FluentAssertions/Equivalency/EquivalencyValidator.cs +++ b/Src/FluentAssertions/Equivalency/EquivalencyValidator.cs @@ -31,38 +31,38 @@ public void RecursivelyAssertEquality(Comparands comparands, IEquivalencyValidat { var scope = AssertionScope.Current; - if (ShouldCompareNodesThisDeep(context.CurrentNode, context.Options, scope)) + if (ShouldContinueThisDeep(context.CurrentNode, context.Options, scope)) { - UpdateScopeWithReportableContext(scope, comparands, context.CurrentNode); + TrackWhatIsNeededToProvideContextToFailures(scope, comparands, context.CurrentNode); if (!context.IsCyclicReference(comparands.Expectation)) { - RunStepsUntilEquivalencyIsProven(comparands, context); + TryToProveNodesAreEquivalent(comparands, context); } } } - private static bool ShouldCompareNodesThisDeep(INode currentNode, IEquivalencyAssertionOptions options, + private static bool ShouldContinueThisDeep(INode currentNode, IEquivalencyAssertionOptions options, AssertionScope assertionScope) { bool shouldRecurse = options.AllowInfiniteRecursion || currentNode.Depth <= MaxDepth; - if (!shouldRecurse) { + // This will throw, unless we're inside an AssertionScope assertionScope.FailWith($"The maximum recursion depth of {MaxDepth} was reached. "); } return shouldRecurse; } - private static void UpdateScopeWithReportableContext(AssertionScope scope, Comparands comparands, INode currentNode) + private static void TrackWhatIsNeededToProvideContextToFailures(AssertionScope scope, Comparands comparands, INode currentNode) { scope.Context = new Lazy(() => currentNode.Description); scope.TrackComparands(comparands.Subject, comparands.Expectation); } - private void RunStepsUntilEquivalencyIsProven(Comparands comparands, IEquivalencyValidationContext context) + private void TryToProveNodesAreEquivalent(Comparands comparands, IEquivalencyValidationContext context) { using var _ = context.Tracer.WriteBlock(node => node.Description); @@ -71,7 +71,6 @@ private void RunStepsUntilEquivalencyIsProven(Comparands comparands, IEquivalenc foreach (IEquivalencyStep step in AssertionOptions.EquivalencyPlan) { var result = step.Handle(comparands, context, this); - if (result == EquivalencyResult.AssertionCompleted) { context.Tracer.WriteLine(getMessage(step)); diff --git a/Src/FluentAssertions/Equivalency/Execution/CyclicReferenceDetector.cs b/Src/FluentAssertions/Equivalency/Execution/CyclicReferenceDetector.cs index 736ba716bd..626e0367c5 100644 --- a/Src/FluentAssertions/Equivalency/Execution/CyclicReferenceDetector.cs +++ b/Src/FluentAssertions/Equivalency/Execution/CyclicReferenceDetector.cs @@ -26,7 +26,7 @@ public bool IsCyclicReference(ObjectReference reference, CyclicReferenceHandling { bool isCyclic = false; - if (reference.IsComplexType) + if (reference.CompareByMembers) { isCyclic = !observedReferences.Add(reference); diff --git a/Src/FluentAssertions/Equivalency/Execution/ObjectReference.cs b/Src/FluentAssertions/Equivalency/Execution/ObjectReference.cs index 0e5b9925cf..b2f92fc3b1 100644 --- a/Src/FluentAssertions/Equivalency/Execution/ObjectReference.cs +++ b/Src/FluentAssertions/Equivalency/Execution/ObjectReference.cs @@ -13,14 +13,14 @@ internal class ObjectReference { private readonly object @object; private readonly string path; - private readonly bool? isComplexType; + private readonly bool? compareByMembers; private string[] pathElements; - public ObjectReference(object @object, string path, bool? isComplexType = null) + public ObjectReference(object @object, string path, bool? compareByMembers = null) { this.@object = @object; this.path = path; - this.isComplexType = isComplexType; + this.compareByMembers = compareByMembers; } /// [AttributeUsage(AttributeTargets.Method)] +#pragma warning disable CA1813 // Avoid unsealed attributes. This type has shipped. public class ValueFormatterAttribute : Attribute { } diff --git a/Src/FluentAssertions/ObjectAssertionsExtensions.cs b/Src/FluentAssertions/ObjectAssertionsExtensions.cs index eddacfe79b..8bc788805c 100644 --- a/Src/FluentAssertions/ObjectAssertionsExtensions.cs +++ b/Src/FluentAssertions/ObjectAssertionsExtensions.cs @@ -151,11 +151,11 @@ private static object CreateCloneUsingBinarySerializer(object subject) Binder = new SimpleBinder(subject.GetType()) }; -#pragma warning disable SYSLIB0011 // BinaryFormatter is obsoleted, GH-issue 1779 tracks the upcoming removal in .NET 8.0 +#pragma warning disable SYSLIB0011, CA2300 // BinaryFormatter is obsoleted, GH-issue 1779 tracks the upcoming removal in .NET 8.0 binaryFormatter.Serialize(stream, subject); stream.Position = 0; return binaryFormatter.Deserialize(stream); -#pragma warning restore SYSLIB0011 +#pragma warning restore SYSLIB0011, CA2300 } private sealed class SimpleBinder : SerializationBinder diff --git a/Src/FluentAssertions/Primitives/ReferenceTypeAssertions.cs b/Src/FluentAssertions/Primitives/ReferenceTypeAssertions.cs index 71509fde21..4d16b601ed 100644 --- a/Src/FluentAssertions/Primitives/ReferenceTypeAssertions.cs +++ b/Src/FluentAssertions/Primitives/ReferenceTypeAssertions.cs @@ -6,7 +6,7 @@ namespace FluentAssertions.Primitives; -#pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals /// @@ -69,5 +69,5 @@ public override string ToString() return Invariant($"{{\"{path}\", {@object}}}"); } - public bool IsComplexType => isComplexType ?? (@object?.GetType().OverridesEquals() == false); + public bool CompareByMembers => compareByMembers ?? (@object?.GetType().OverridesEquals() == false); } From 649e9fd0054627927427959e618a9a56f9cee251 Mon Sep 17 00:00:00 2001 From: Dennis Doomen Date: Sat, 1 Apr 2023 21:00:08 +0200 Subject: [PATCH 80/98] Extracts the type reflection logic into a dedicated class (#2165) --- Src/FluentAssertions/Common/TypeExtensions.cs | 155 ++--------------- .../Common/TypeMemberReflector.cs | 156 ++++++++++++++++++ .../Formatting/DefaultValueFormatter.cs | 2 +- 3 files changed, 173 insertions(+), 140 deletions(-) create mode 100644 Src/FluentAssertions/Common/TypeMemberReflector.cs diff --git a/Src/FluentAssertions/Common/TypeExtensions.cs b/Src/FluentAssertions/Common/TypeExtensions.cs index f8882a66fc..68f9831ba7 100644 --- a/Src/FluentAssertions/Common/TypeExtensions.cs +++ b/Src/FluentAssertions/Common/TypeExtensions.cs @@ -24,11 +24,8 @@ internal static class TypeExtensions private static readonly ConcurrentDictionary HasValueSemanticsCache = new(); private static readonly ConcurrentDictionary TypeIsRecordCache = new(); - private static readonly ConcurrentDictionary<(Type Type, MemberVisibility Visibility), IEnumerable> - NonPrivatePropertiesCache = new(); - - private static readonly ConcurrentDictionary<(Type Type, MemberVisibility Visibility), IEnumerable> - NonPrivateFieldsCache = new(); + private static readonly ConcurrentDictionary<(Type Type, MemberVisibility Visibility), TypeMemberReflector> + TypeMemberReflectorsCache = new(); public static bool IsDecoratedWith(this Type type) where TAttribute : Attribute @@ -219,145 +216,25 @@ public static FieldInfo FindField(this Type type, string fieldName) return null; } - public static IEnumerable GetNonPrivateMembers(this Type typeToReflect, MemberVisibility visibility) - { - return - GetNonPrivateProperties(typeToReflect, visibility) - .Concat(GetNonPrivateFields(typeToReflect, visibility)) - .ToArray(); - } - - public static IEnumerable GetNonPrivateProperties(this Type typeToReflect, MemberVisibility visibility) + public static MemberInfo[] GetNonPrivateMembers(this Type typeToReflect, MemberVisibility visibility) { - return NonPrivatePropertiesCache.GetOrAdd((typeToReflect, visibility), static key => - { - IEnumerable query = - from propertyInfo in GetPropertiesFromHierarchy(key.Type, key.Visibility) - where HasNonPrivateGetter(propertyInfo) - where !propertyInfo.IsIndexer() - select propertyInfo; - - return query.ToArray(); - }); - } - - private static IEnumerable GetPropertiesFromHierarchy(Type typeToReflect, MemberVisibility memberVisibility) - { - bool includeInternals = memberVisibility.HasFlag(MemberVisibility.Internal); - - return GetMembersFromHierarchy(typeToReflect, type => - { - return type - .GetProperties(AllInstanceMembersFlag | BindingFlags.DeclaredOnly) - .Where(property => property.GetMethod?.IsPrivate == false) - .Where(property => includeInternals || property.GetMethod is { IsAssembly: false, IsFamilyOrAssembly: false }) - .ToArray(); - }); - } - - public static IEnumerable GetNonPrivateFields(this Type typeToReflect, MemberVisibility visibility) - { - return NonPrivateFieldsCache.GetOrAdd((typeToReflect, visibility), static key => - { - IEnumerable query = - from fieldInfo in GetFieldsFromHierarchy(key.Type, key.Visibility) - where !fieldInfo.IsPrivate - where !fieldInfo.IsFamily - select fieldInfo; - - return query.ToArray(); - }); - } - - private static IEnumerable GetFieldsFromHierarchy(Type typeToReflect, MemberVisibility memberVisibility) - { - bool includeInternals = memberVisibility.HasFlag(MemberVisibility.Internal); - - return GetMembersFromHierarchy(typeToReflect, type => - { - return type - .GetFields(AllInstanceMembersFlag) - .Where(field => !field.IsPrivate) - .Where(field => includeInternals || (!field.IsAssembly && !field.IsFamilyOrAssembly)) - .ToArray(); - }); - } - - private static IEnumerable GetMembersFromHierarchy( - Type typeToReflect, - Func> getMembers) - where TMemberInfo : MemberInfo - { - if (typeToReflect.IsInterface) - { - return GetInterfaceMembers(typeToReflect, getMembers); - } - - return GetClassMembers(typeToReflect, getMembers); + return GetTypeReflectorFor(typeToReflect, visibility).NonPrivateMembers; } - private static List GetInterfaceMembers(Type typeToReflect, - Func> getMembers) - where TMemberInfo : MemberInfo + public static PropertyInfo[] GetNonPrivateProperties(this Type typeToReflect, MemberVisibility visibility) { - List members = new(); - - var considered = new List(); - var queue = new Queue(); - considered.Add(typeToReflect); - queue.Enqueue(typeToReflect); - - while (queue.Count > 0) - { - Type subType = queue.Dequeue(); - - foreach (Type subInterface in subType.GetInterfaces()) - { - if (considered.Contains(subInterface)) - { - continue; - } - - considered.Add(subInterface); - queue.Enqueue(subInterface); - } - - IEnumerable typeMembers = getMembers(subType); - - IEnumerable newPropertyInfos = typeMembers.Where(x => !members.Contains(x)); - - members.InsertRange(0, newPropertyInfos); - } - - return members; + return GetTypeReflectorFor(typeToReflect, visibility).NonPrivateProperties; } - private static List GetClassMembers(Type typeToReflect, - Func> getMembers) - where TMemberInfo : MemberInfo + public static FieldInfo[] GetNonPrivateFields(this Type typeToReflect, MemberVisibility visibility) { - List members = new(); - - while (typeToReflect != null) - { - foreach (var memberInfo in getMembers(typeToReflect)) - { - if (members.All(mi => mi.Name != memberInfo.Name)) - { - members.Add(memberInfo); - } - } - - typeToReflect = typeToReflect.BaseType; - } - - return members; + return GetTypeReflectorFor(typeToReflect, visibility).NonPrivateFields; } - private static bool HasNonPrivateGetter(PropertyInfo propertyInfo) + private static TypeMemberReflector GetTypeReflectorFor(Type typeToReflect, MemberVisibility visibility) { - MethodInfo getMethod = propertyInfo.GetGetMethod(nonPublic: true); - return getMethod is { IsPrivate: false, IsFamily: false }; + return TypeMemberReflectorsCache.GetOrAdd((typeToReflect, visibility), + static key => new TypeMemberReflector(key.Type, key.Visibility)); } /// [AttributeUsage(AttributeTargets.Method)] +#pragma warning disable CA1813 // Avoid unsealed attributes. This type has shipped. public class CustomAssertionAttribute : Attribute { } diff --git a/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs b/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs index 5e4b6dd0af..5568dbacb9 100644 --- a/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs +++ b/Src/FluentAssertions/Equivalency/SelfReferenceEquivalencyAssertionOptions.cs @@ -17,6 +17,8 @@ namespace FluentAssertions.Equivalency; +#pragma warning disable CA1033 //An unsealed externally visible type provides an explicit method implementation of a public interface and does not provide an alternative externally visible method that has the same name. + /// diff --git a/Src/FluentAssertions/Execution/LateBoundTestFramework.cs b/Src/FluentAssertions/Execution/LateBoundTestFramework.cs index d242455a38..41c214509d 100644 --- a/Src/FluentAssertions/Execution/LateBoundTestFramework.cs +++ b/Src/FluentAssertions/Execution/LateBoundTestFramework.cs @@ -16,7 +16,7 @@ public void Throw(string message) if (exceptionType is null) { - throw new Exception( + throw new NotSupportedException( $"Failed to create the assertion exception for the current test framework: \"{ExceptionFullName}, {assembly.FullName}\""); } diff --git a/Src/FluentAssertions/Execution/NSpecFramework.cs b/Src/FluentAssertions/Execution/NSpecFramework.cs index a22b9ad308..e1cb34c89e 100644 --- a/Src/FluentAssertions/Execution/NSpecFramework.cs +++ b/Src/FluentAssertions/Execution/NSpecFramework.cs @@ -30,12 +30,8 @@ public bool IsAvailable [DoesNotReturn] public void Throw(string message) { - Type exceptionType = assembly.GetType("NSpec.Domain.AssertionException"); - - if (exceptionType is null) - { - throw new Exception("Failed to create the NSpec assertion type"); - } + Type exceptionType = assembly.GetType("NSpec.Domain.AssertionException") + ?? throw new NotSupportedException("Failed to create the NSpec assertion type"); throw (Exception)Activator.CreateInstance(exceptionType, message); } diff --git a/Src/FluentAssertions/Execution/XUnit2TestFramework.cs b/Src/FluentAssertions/Execution/XUnit2TestFramework.cs index a9c993a2b0..5dc2b38012 100644 --- a/Src/FluentAssertions/Execution/XUnit2TestFramework.cs +++ b/Src/FluentAssertions/Execution/XUnit2TestFramework.cs @@ -32,12 +32,8 @@ public bool IsAvailable [DoesNotReturn] public void Throw(string message) { - Type exceptionType = assembly.GetType("Xunit.Sdk.XunitException"); - - if (exceptionType is null) - { - throw new Exception("Failed to create the XUnit assertion type"); - } + Type exceptionType = assembly.GetType("Xunit.Sdk.XunitException") + ?? throw new NotSupportedException("Failed to create the XUnit assertion type"); throw (Exception)Activator.CreateInstance(exceptionType, message); } diff --git a/Src/FluentAssertions/FluentAssertions.csproj b/Src/FluentAssertions/FluentAssertions.csproj index e3f47fe0fd..97b75a3288 100644 --- a/Src/FluentAssertions/FluentAssertions.csproj +++ b/Src/FluentAssertions/FluentAssertions.csproj @@ -7,7 +7,6 @@ - @@ -30,11 +29,6 @@ - - diff --git a/Src/FluentAssertions/Formatting/ValueFormatterAttribute.cs b/Src/FluentAssertions/Formatting/ValueFormatterAttribute.cs index 73c924daf4..bac15f0878 100644 --- a/Src/FluentAssertions/Formatting/ValueFormatterAttribute.cs +++ b/Src/FluentAssertions/Formatting/ValueFormatterAttribute.cs @@ -6,6 +6,7 @@ namespace FluentAssertions.Formatting; /// Marks a static method as a kind of @@ -404,11 +281,6 @@ public static MethodInfo GetParameterlessMethod(this Type type, string methodNam return type.GetMethod(methodName, Enumerable.Empty()); } - public static bool HasParameterlessMethod(this Type type, string methodName) - { - return type.GetParameterlessMethod(methodName) is not null; - } - public static PropertyInfo FindPropertyByName(this Type type, string propertyName) { return type.GetProperty(propertyName, AllStaticAndInstanceMembersFlag); @@ -426,6 +298,11 @@ public static bool HasExplicitlyImplementedProperty(this Type type, Type interfa return hasGetter || hasSetter; } + private static bool HasParameterlessMethod(this Type type, string methodName) + { + return type.GetParameterlessMethod(methodName) is not null; + } + public static PropertyInfo GetIndexerByParameterTypes(this Type type, IEnumerable parameterTypes) { return type.GetProperties(AllStaticAndInstanceMembersFlag) diff --git a/Src/FluentAssertions/Common/TypeMemberReflector.cs b/Src/FluentAssertions/Common/TypeMemberReflector.cs new file mode 100644 index 0000000000..2757cdafb4 --- /dev/null +++ b/Src/FluentAssertions/Common/TypeMemberReflector.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using FluentAssertions.Equivalency; + +namespace FluentAssertions.Common; + +/// +internal sealed class TypeMemberReflector +{ + private const BindingFlags AllInstanceMembersFlag = + BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; + + public TypeMemberReflector(Type typeToReflect, MemberVisibility visibility) + { + NonPrivateProperties = LoadNonPrivateProperties(typeToReflect, visibility); + NonPrivateFields = LoadNonPrivateFields(typeToReflect, visibility); + NonPrivateMembers = NonPrivateProperties.Concat +/// Helper class to get all the public and internal fields and properties from a type. +/// (NonPrivateFields).ToArray(); + } + + public MemberInfo[] NonPrivateMembers { get; } + + public PropertyInfo[] NonPrivateProperties { get; } + + public FieldInfo[] NonPrivateFields { get; } + + private static PropertyInfo[] LoadNonPrivateProperties(Type typeToReflect, MemberVisibility visibility) + { + IEnumerable query = + from propertyInfo in GetPropertiesFromHierarchy(typeToReflect, visibility) + where HasNonPrivateGetter(propertyInfo) + where !propertyInfo.IsIndexer() + select propertyInfo; + + return query.ToArray(); + } + + private static IEnumerable GetPropertiesFromHierarchy(Type typeToReflect, MemberVisibility memberVisibility) + { + bool includeInternals = memberVisibility.HasFlag(MemberVisibility.Internal); + + return GetMembersFromHierarchy(typeToReflect, type => + { + return type + .GetProperties(AllInstanceMembersFlag | BindingFlags.DeclaredOnly) + .Where(property => property.GetMethod?.IsPrivate == false) + .Where(property => includeInternals || property.GetMethod is { IsAssembly: false, IsFamilyOrAssembly: false }) + .ToArray(); + }); + } + + private static FieldInfo[] LoadNonPrivateFields(Type typeToReflect, MemberVisibility visibility) + { + IEnumerable query = + from fieldInfo in GetFieldsFromHierarchy(typeToReflect, visibility) + where !fieldInfo.IsPrivate + where !fieldInfo.IsFamily + select fieldInfo; + + return query.ToArray(); + } + + private static IEnumerable GetFieldsFromHierarchy(Type typeToReflect, MemberVisibility memberVisibility) + { + bool includeInternals = memberVisibility.HasFlag(MemberVisibility.Internal); + + return GetMembersFromHierarchy(typeToReflect, type => + { + return type + .GetFields(AllInstanceMembersFlag) + .Where(field => !field.IsPrivate) + .Where(field => includeInternals || (!field.IsAssembly && !field.IsFamilyOrAssembly)) + .ToArray(); + }); + } + + private static IEnumerable GetMembersFromHierarchy( + Type typeToReflect, + Func> getMembers) + where TMemberInfo : MemberInfo + { + if (typeToReflect.IsInterface) + { + return GetInterfaceMembers(typeToReflect, getMembers); + } + + return GetClassMembers(typeToReflect, getMembers); + } + + private static List GetInterfaceMembers(Type typeToReflect, + Func> getMembers) + where TMemberInfo : MemberInfo + { + List members = new(); + + var considered = new List(); + var queue = new Queue(); + considered.Add(typeToReflect); + queue.Enqueue(typeToReflect); + + while (queue.Count > 0) + { + Type subType = queue.Dequeue(); + + foreach (Type subInterface in subType.GetInterfaces()) + { + if (considered.Contains(subInterface)) + { + continue; + } + + considered.Add(subInterface); + queue.Enqueue(subInterface); + } + + IEnumerable typeMembers = getMembers(subType); + + IEnumerable newPropertyInfos = typeMembers.Where(x => !members.Contains(x)); + + members.InsertRange(0, newPropertyInfos); + } + + return members; + } + + private static List GetClassMembers(Type typeToReflect, + Func> getMembers) + where TMemberInfo : MemberInfo + { + List members = new(); + + while (typeToReflect != null) + { + foreach (var memberInfo in getMembers(typeToReflect)) + { + if (members.All(mi => mi.Name != memberInfo.Name)) + { + members.Add(memberInfo); + } + } + + typeToReflect = typeToReflect.BaseType; + } + + return members; + } + + private static bool HasNonPrivateGetter(PropertyInfo propertyInfo) + { + MethodInfo getMethod = propertyInfo.GetGetMethod(nonPublic: true); + return getMethod is { IsPrivate: false, IsFamily: false }; + } +} diff --git a/Src/FluentAssertions/Formatting/DefaultValueFormatter.cs b/Src/FluentAssertions/Formatting/DefaultValueFormatter.cs index a65ab4cc2b..30f49377ae 100644 --- a/Src/FluentAssertions/Formatting/DefaultValueFormatter.cs +++ b/Src/FluentAssertions/Formatting/DefaultValueFormatter.cs @@ -56,7 +56,7 @@ public void Format(object value, FormattedObjectGraph formattedGraph, Formatting /// protected virtual MemberInfo[] GetMembers(Type type) { - return type.GetNonPrivateMembers(MemberVisibility.Public).ToArray(); + return type.GetNonPrivateMembers(MemberVisibility.Public); } private static bool HasDefaultToStringImplementation(object value) From bc23a499eb749d050dd8f36e733eccc66b74dbcd Mon Sep 17 00:00:00 2001 From: Jonas Nyrup The default is all non-private members. Date: Sat, 1 Apr 2023 22:37:59 +0200 Subject: [PATCH 81/98] Use C# 11 --- Directory.Build.props | 2 +- FluentAssertions.sln | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 9001ea1d2f..0e93053edf 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ diff --git a/FluentAssertions.sln b/FluentAssertions.sln index b17acfccb2..404f5fb173 100644 --- a/FluentAssertions.sln +++ b/FluentAssertions.sln @@ -16,6 +16,9 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "_build", "Build\_build.csproj", "{364DD16C-D759-49DC-A04A-64D40205295B}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Specs", "Specs", "{963262D0-9FD5-4741-8C0E-E2F34F110EF3}" + ProjectSection(SolutionItems) = preProject + Tests\.editorconfig = Tests\.editorconfig + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssemblyA", "Tests\AssemblyA\AssemblyA.csproj", "{7144BD9D-2A5F-45B6-AC5B-E35578D03350}" EndProject diff --git a/Rules.ruleset b/Rules.ruleset deleted file mode 100644 index f0ac4bc983..0000000000 --- a/Rules.ruleset +++ /dev/null @@ -1,63 +0,0 @@ - - \ No newline at end of file diff --git a/Src/FluentAssertions/CustomAssertionAttribute.cs b/Src/FluentAssertions/CustomAssertionAttribute.cs index 028e151bcb..3dcde4a46c 100644 --- a/Src/FluentAssertions/CustomAssertionAttribute.cs +++ b/Src/FluentAssertions/CustomAssertionAttribute.cs @@ -7,6 +7,7 @@ namespace FluentAssertions; /// internally, or directly uses the . /// diff --git a/FluentAssertions.sln b/FluentAssertions.sln index 27b4dfdc64..b17acfccb2 100644 --- a/FluentAssertions.sln +++ b/FluentAssertions.sln @@ -7,6 +7,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig Tests\Default.testsettings = Tests\Default.testsettings + Directory.Build.props = Directory.Build.props Src\JetBrainsAnnotations.cs = Src\JetBrainsAnnotations.cs nuget.config = nuget.config README.md = README.md From 24be75310201344d1ce806b97152c4859ce63892 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup - + 10.011.0falsetrue Date: Sat, 1 Apr 2023 22:38:08 +0200 Subject: [PATCH 82/98] Use list patterns --- .../MultiLineCommentParsingStrategy.cs | 7 +++---- .../QuotesParsingStrategy.cs | 6 ++++-- .../SingleLineCommentParsingStrategy.cs | 4 +++- .../Common/ExpressionExtensions.cs | 17 +++++++++-------- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Src/FluentAssertions/CallerIdentification/MultiLineCommentParsingStrategy.cs b/Src/FluentAssertions/CallerIdentification/MultiLineCommentParsingStrategy.cs index a614631307..4f49397f14 100644 --- a/Src/FluentAssertions/CallerIdentification/MultiLineCommentParsingStrategy.cs +++ b/Src/FluentAssertions/CallerIdentification/MultiLineCommentParsingStrategy.cs @@ -26,10 +26,9 @@ public ParsingState Parse(char symbol, StringBuilder statement) return ParsingState.GoToNextSymbol; } - var isStartOfMultilineComment = - symbol is '*' - && statement.Length > 0 - && statement[^1] is '/'; +#pragma warning disable SA1010 // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/pull/3507 + var isStartOfMultilineComment = symbol is '*' && statement is [.., '/']; +#pragma warning restore SA1010 if (isStartOfMultilineComment) { diff --git a/Src/FluentAssertions/CallerIdentification/QuotesParsingStrategy.cs b/Src/FluentAssertions/CallerIdentification/QuotesParsingStrategy.cs index a988bb4c79..ce43cda82a 100644 --- a/Src/FluentAssertions/CallerIdentification/QuotesParsingStrategy.cs +++ b/Src/FluentAssertions/CallerIdentification/QuotesParsingStrategy.cs @@ -54,7 +54,9 @@ public void NotifyEndOfLineReached() private bool IsVerbatim(StringBuilder statement) { - return (previousChar is '@' && statement.Length >= 2 && statement[^2] is '$' && statement[^1] is '@') - || (previousChar is '$' && statement.Length >= 2 && statement[^2] is '@' && statement[^1] is '$'); +#pragma warning disable SA1010 // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/pull/3507 + return (previousChar is '@' && statement is [.., '$', '@']) + || (previousChar is '$' && statement is [.., '@', '$']); +#pragma warning restore SA1010 } } diff --git a/Src/FluentAssertions/CallerIdentification/SingleLineCommentParsingStrategy.cs b/Src/FluentAssertions/CallerIdentification/SingleLineCommentParsingStrategy.cs index 9c8e86196f..847cf0f958 100644 --- a/Src/FluentAssertions/CallerIdentification/SingleLineCommentParsingStrategy.cs +++ b/Src/FluentAssertions/CallerIdentification/SingleLineCommentParsingStrategy.cs @@ -13,7 +13,9 @@ public ParsingState Parse(char symbol, StringBuilder statement) return ParsingState.GoToNextSymbol; } - var doesSymbolStartComment = symbol is '/' && statement.Length > 0 && statement[^1] is '/'; +#pragma warning disable SA1010 // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/pull/3507 + var doesSymbolStartComment = symbol is '/' && statement is [.., '/']; +#pragma warning restore SA1010 if (!doesSymbolStartComment) { diff --git a/Src/FluentAssertions/Common/ExpressionExtensions.cs b/Src/FluentAssertions/Common/ExpressionExtensions.cs index 40884bc7e9..7d7f098ce3 100644 --- a/Src/FluentAssertions/Common/ExpressionExtensions.cs +++ b/Src/FluentAssertions/Common/ExpressionExtensions.cs @@ -74,10 +74,10 @@ public static MemberPath GetMemberPath( case ExpressionType.ArrayIndex: var binaryExpression = (BinaryExpression)node; - var constantExpression = (ConstantExpression)binaryExpression.Right; + var indexExpression = (ConstantExpression)binaryExpression.Right; node = binaryExpression.Left; - segments.Add("[" + constantExpression.Value + "]"); + segments.Add("[" + indexExpression.Value + "]"); break; case ExpressionType.Parameter: @@ -87,15 +87,15 @@ public static MemberPath GetMemberPath( case ExpressionType.Call: var methodCallExpression = (MethodCallExpression)node; - if (methodCallExpression.Method.Name != "get_Item" || methodCallExpression.Arguments.Count != 1 || - methodCallExpression.Arguments[0] is not ConstantExpression) +#pragma warning disable SA1010 // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/pull/3507 + if (methodCallExpression is not { Method.Name: "get_Item", Arguments: [ConstantExpression argumentExpression] }) { throw new ArgumentException(GetUnsupportedExpressionMessage(expression.Body), nameof(expression)); } +#pragma warning restore SA1010 - constantExpression = (ConstantExpression)methodCallExpression.Arguments[0]; node = methodCallExpression.Object; - segments.Add("[" + constantExpression.Value + "]"); + segments.Add("[" + argumentExpression.Value + "]"); break; default: @@ -158,11 +158,12 @@ public static void ValidateMemberPath( case ExpressionType.Call: var methodCallExpression = (MethodCallExpression)node; - if (methodCallExpression.Method.Name != "get_Item" || methodCallExpression.Arguments.Count != 1 || - methodCallExpression.Arguments[0] is not ConstantExpression) +#pragma warning disable SA1010 // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/pull/3507 + if (methodCallExpression is not { Method.Name: "get_Item", Arguments: [ConstantExpression] }) { throw new ArgumentException(GetUnsupportedExpressionMessage(expression.Body), nameof(expression)); } +#pragma warning restore SA1010 node = methodCallExpression.Object; break; From 24a856dbd5e3d69d7ba4330c93e4bc3536b75fdc Mon Sep 17 00:00:00 2001 From: sdelarosbil Date: Thu, 30 Mar 2023 15:13:11 -0400 Subject: [PATCH 83/98] Improve the DataRowCollectionEquivalency code coverage --- .../DataTableSpecs.cs | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/Tests/FluentAssertions.Equivalency.Specs/DataTableSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/DataTableSpecs.cs index 3406bbed26..285c4ec402 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/DataTableSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/DataTableSpecs.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Data; using System.Globalization; using System.Linq; @@ -32,6 +33,125 @@ public void When_data_tables_are_both_null_equivalence_test_should_succeed() ((DataTable)null).Should().BeEquivalentTo(null); } + [Fact] + public void When_row_match_mode_is_invalid_it_should_fail() + { + // Arrange + var typedDataSet = CreateDummyDataSet(); + + var subject = typedDataSet.ToUntypedDataSet().Tables["TypedDataTable1"]; + var expectation = typedDataSet.ToUntypedDataSet().Tables["TypedDataTable1"]; + + // Act + Action action = () => subject.Should().BeEquivalentTo(expectation, options => options.UsingRowMatchMode((RowMatchMode)2)); + + // Assert + action.Should().Throw().WithMessage( + "Unknown RowMatchMode *when trying to compare *"); + } + + [Theory] + [MemberData(nameof(EmptyPrimaryKeys))] + public void When_row_match_mode_is_primary_key_without_primary_key_it_should_fail(DataColumn[] emptyPrimaryKey) + { + // Arrange + var typedDataSet = CreateDummyDataSet(includeRelation: false); + + var subject = typedDataSet.ToUntypedDataSet().Tables["TypedDataTable1"]; + var expectation = typedDataSet.ToUntypedDataSet().Tables["TypedDataTable1"]; + + subject.PrimaryKey = emptyPrimaryKey; + + // Act + Action action = () => + subject.Should().BeEquivalentTo(expectation, options => options.UsingRowMatchMode(RowMatchMode.PrimaryKey)); + + // Assert + action.Should().Throw().WithMessage( + "*Table *containing *does not have a primary key. RowMatchMode.PrimaryKey cannot be applied.*"); + } + + public static TheoryData EmptyPrimaryKeys => new() + { + null, + new DataColumn[] { } + }; + + [Fact] + public void When_primary_key_types_do_not_match_it_should_throw() + { + // Arrange + var typedDataSetSubject = CreateDummyDataSet(includeDummyData: false, includeRelation: false); + var typedDataSetExpectation = new TypedDataSetSubclass(typedDataSetSubject); + + var subject = typedDataSetSubject.ToUntypedDataSet().Tables["TypedDataTable1"]; + var expectation = typedDataSetExpectation.ToUntypedDataSet().Tables["TypedDataTable1"]; + + subject.PrimaryKey[0].DataType = typeof(long); + subject.Rows.Add(1L); + subject.AcceptChanges(); + expectation.Rows.Add(1); + expectation.AcceptChanges(); + + // Act + Action action = () => + subject.Should().BeEquivalentTo(expectation, options => options.UsingRowMatchMode(RowMatchMode.PrimaryKey)); + + // Assert + action.Should().Throw().WithMessage( + "*Subject and expectation primary keys of table containing *do not have the same schema and cannot be compared. " + + "RowMatchMode.PrimaryKey cannot be applied.*"); + } + + [Fact] + public void When_primary_key_of_one_rows_differ_it_should_fail() + { + // Arrange + var typedDataSetSubject = CreateDummyDataSet(); + var typedDataSetExpectation = new TypedDataSetSubclass(typedDataSetSubject); + + var subject = typedDataSetSubject.ToUntypedDataSet().Tables["TypedDataTable1"]; + var expectation = typedDataSetExpectation.ToUntypedDataSet().Tables["TypedDataTable1"]; + + expectation.Rows[0].SetField(expectation.PrimaryKey[0], 0); + + expectation.AcceptChanges(); + + // Act + Action action = () => + subject.Should().BeEquivalentTo(expectation, options => options.UsingRowMatchMode(RowMatchMode.PrimaryKey)); + + // Assert + action.Should().Throw().WithMessage( + "Found unexpected row in *with key *Expected to find a row with key *in *, but no such row was found*"); + } + + [Fact] + public void When_primary_key_of_multiple_rows_differ_it_should_fail() + { + // Arrange + var typedDataSetSubject = CreateDummyDataSet(); + var typedDataSetExpectation = new TypedDataSetSubclass(typedDataSetSubject); + + var subject = typedDataSetSubject.ToUntypedDataSet().Tables["TypedDataTable1"]; + var expectation = typedDataSetExpectation.ToUntypedDataSet().Tables["TypedDataTable1"]; + + for (int i = 0; i < 3; i++) + { + expectation.Rows[i].SetField(expectation.PrimaryKey[0], i); + } + + expectation.AcceptChanges(); + + // Act + Action action = () => + subject.Should().BeEquivalentTo(expectation, options => options.UsingRowMatchMode(RowMatchMode.PrimaryKey)); + + // Assert + action.Should().Throw().WithMessage( + "Found unexpected row in *with key * rows were expected in *and not found*"); + } + [Fact] public void When_data_table_is_null_and_isnt_expected_to_be_equivalence_test_should_fail() { From 293aec1dd0cdc3010116d263bc56fa6ed7a6d234 Mon Sep 17 00:00:00 2001 From: Samuel Delarosbil <126594693+sdelarosbil@users.noreply.github.com> Date: Tue, 4 Apr 2023 10:17:44 -0400 Subject: [PATCH 84/98] Improve the ExpressionExtensions coverage (#2168) --- ...ectionAssertionSpecs.BeInAscendingOrder.cs | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeInAscendingOrder.cs b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeInAscendingOrder.cs index 92d4b176be..faf106ce2b 100644 --- a/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeInAscendingOrder.cs +++ b/Tests/FluentAssertions.Specs/Collections/CollectionAssertionSpecs.BeInAscendingOrder.cs @@ -153,6 +153,62 @@ public void When_asserting_single_element_collection_by_property_expression_orde act.Should().NotThrow(); } + [Fact] + public void Can_use_a_cast_expression_in_the_ordering_expression() + { + // Arrange + var collection = new SomeClass[] + { + new() { Text = "a", Number = 1 } + }; + + // Act & Assert + collection.Should().BeInAscendingOrder(o => (float)o.Number); + } + + [Fact] + public void Can_use_an_index_into_a_list_in_the_ordering_expression() + { + // Arrange + var collection = new[] + { + new List { new() { Text = "a", Number = 1 } } + }; + + // Act & Assert + collection.Should().BeInAscendingOrder(o => o[0].Number); + } + + [Fact] + public void Can_use_an_index_into_an_array_in_the_ordering_expression() + { + // Arrange + var collection = new[] + { + new[] { new SomeClass { Text = "a", Number = 1 } } + }; + + // Act & Assert + collection.Should().BeInAscendingOrder(o => o[0].Number); + } + + [Fact] + public void Unsupported_ordering_expressions_are_invalid() + { + // Arrange + var collection = new SomeClass[] + { + new() { Text = "a", Number = 1 } + }; + + // Act + Action act = () => collection.Should().BeInAscendingOrder(o => o.Number > 1); + + // Assert + act.Should().Throw() + .WithMessage("*Expression <*> cannot be used to select a member.*"); + } + [Fact] public void When_asserting_the_items_in_an_unordered_collection_are_ordered_ascending_using_the_specified_property_it_should_throw() From b1f594507c0ce2ebc94b96e98f810e11375bed36 Mon Sep 17 00:00:00 2001 From: Samuel Delarosbil <126594693+sdelarosbil@users.noreply.github.com> Date: Tue, 4 Apr 2023 11:58:34 -0400 Subject: [PATCH 85/98] Improve the DateOnly and TimeOnly code coverage (#2167) --- .../Primitives/DateOnlyAssertionSpecs.cs | 69 +++++++++++++++++++ .../Primitives/TimeOnlyAssertionSpecs.cs | 69 +++++++++++++++++++ 2 files changed, 138 insertions(+) diff --git a/Tests/FluentAssertions.Specs/Primitives/DateOnlyAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Primitives/DateOnlyAssertionSpecs.cs index edbd61a548..962f38023a 100644 --- a/Tests/FluentAssertions.Specs/Primitives/DateOnlyAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Primitives/DateOnlyAssertionSpecs.cs @@ -27,6 +27,16 @@ public void Should_succeed_when_asserting_nullable_dateonly_value_with_value_to_ dateOnly.Should().NotBeNull(); } + [Fact] + public void Should_succeed_when_asserting_nullable_dateonly_value_with_null_to_be_null() + { + // Arrange + DateOnly? dateOnly = null; + + // Act/Assert + dateOnly.Should().BeNull(); + } + public class Be { [Fact] @@ -602,6 +612,65 @@ public void When_asserting_subject_null_dateonly_should_not_have_month_should_th } } + public class NotBe + { + [Fact] + public void Different_dateonly_values_are_valid() + { + // Arrange + DateOnly date = new(2020, 06, 04); + DateOnly otherDate = new(2020, 06, 05); + + // Act & Assert + date.Should().NotBe(otherDate); + } + + [Fact] + public void Different_dateonly_values_with_different_nullability_are_valid() + { + // Arrange + DateOnly date = new(2020, 06, 04); + DateOnly? otherDate = new(2020, 07, 05); + + // Act & Assert + date.Should().NotBe(otherDate); + } + + [Fact] + public void Same_dateonly_values_are_invalid() + { + // Arrange + DateOnly date = new(2020, 06, 04); + DateOnly sameDate = new(2020, 06, 04); + + // Act + Action act = + () => date.Should().NotBe(sameDate, "because we want to test the failure {0}", "message"); + + // Assert + act.Should().Throw() + .WithMessage( + "Expected date not to be <2020-06-04> because we want to test the failure message, but it is."); + } + + [Fact] + public void Same_dateonly_values_with_different_nullability_are_invalid() + { + // Arrange + DateOnly date = new(2020, 06, 04); + DateOnly? sameDate = new(2020, 06, 04); + + // Act + Action act = + () => date.Should().NotBe(sameDate, "because we want to test the failure {0}", "message"); + + // Assert + act.Should().Throw() + .WithMessage( + "Expected date not to be <2020-06-04> because we want to test the failure message, but it is."); + } + } + public class HaveDay { [Fact] diff --git a/Tests/FluentAssertions.Specs/Primitives/TimeOnlyAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Primitives/TimeOnlyAssertionSpecs.cs index 5e66cb8b7c..6f98e99856 100644 --- a/Tests/FluentAssertions.Specs/Primitives/TimeOnlyAssertionSpecs.cs +++ b/Tests/FluentAssertions.Specs/Primitives/TimeOnlyAssertionSpecs.cs @@ -29,6 +29,16 @@ public void Should_succeed_when_asserting_nullable_timeonly_value_with_value_to_ timeOnly.Should().NotBeNull(); } + [Fact] + public void Should_succeed_when_asserting_nullable_timeonly_value_with_null_to_be_null() + { + // Arrange + TimeOnly? timeOnly = null; + + // Act/Assert + timeOnly.Should().BeNull(); + } + public class Be { [Fact] @@ -1291,6 +1301,65 @@ public void When_a_value_is_one_of_the_specified_values_it_should_succeed_when_t } } + public class NotBe + { + [Fact] + public void Different_timeonly_values_are_valid() + { + // Arrange + TimeOnly time = new(19, 06, 04); + TimeOnly otherTime = new(20, 06, 05); + + // Act & Assert + time.Should().NotBe(otherTime); + } + + [Fact] + public void Different_timeonly_values_with_different_nullability_are_valid() + { + // Arrange + TimeOnly time = new(19, 06, 04); + TimeOnly? otherTime = new(19, 07, 05); + + // Act & Assert + time.Should().NotBe(otherTime); + } + + [Fact] + public void Same_timeonly_values_are_invalid() + { + // Arrange + TimeOnly time = new(19, 06, 04); + TimeOnly sameTime = new(19, 06, 04); + + // Act + Action act = + () => time.Should().NotBe(sameTime, "because we want to test the failure {0}", "message"); + + // Assert + act.Should().Throw() + .WithMessage( + "Expected time not to be <19:06:04.000> because we want to test the failure message, but it is."); + } + + [Fact] + public void Same_timeonly_values_with_different_nullability_are_invalid() + { + // Arrange + TimeOnly time = new(19, 06, 04); + TimeOnly? sameTime = new(19, 06, 04); + + // Act + Action act = + () => time.Should().NotBe(sameTime, "because we want to test the failure {0}", "message"); + + // Assert + act.Should().Throw() + .WithMessage( + "Expected time not to be <19:06:04.000> because we want to test the failure message, but it is."); + } + } + public class AndChaining { [Fact] From dfc11c00dd8963ed1b90b171e1db720b71019b77 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Wed, 5 Apr 2023 14:58:53 +0200 Subject: [PATCH 86/98] fix link to PR in release notes --- docs/_pages/releases.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_pages/releases.md b/docs/_pages/releases.md index 1947bb1e99..962a4414cd 100644 --- a/docs/_pages/releases.md +++ b/docs/_pages/releases.md @@ -440,7 +440,7 @@ Kudos to [conklinb](https://github.com/conklinb) and [Amaury Levé](https://gith * `BeOfType` does not attach to the `AssertionScope` correctly - [#1002](https://github.com/fluentassertions/fluentassertions/pull/1002) * Event monitoring did not detect events on interfaces - [#821](https://github.com/fluentassertions/fluentassertions/pull/821) * Fix continuation on `NotThrow(After)` in chained `AssertionScope` invocations - [#1031](https://github.com/fluentassertions/fluentassertions/pull/1031) -* Allow nesting equivalency checks in custom assertion rules when using `BeEquivalentTo` - [#1031](https://github.com/fluentassertions/fluentassertions/pull/1031) +* Allow nesting equivalency checks in custom assertion rules when using `BeEquivalentTo` - [#1033](https://github.com/fluentassertions/fluentassertions/pull/1033) * Removed redundant use of the thread pool in async assertions - [#1020](https://github.com/fluentassertions/fluentassertions/pull/1020) * Improved formatting of multidimensional arrays - [#1044](https://github.com/fluentassertions/fluentassertions/pull/1044) * Better handling of exceptions wrapped in `AggregateException`s - [#1041](https://github.com/fluentassertions/fluentassertions/pull/1041) From 3a2c331983dad6b3b73f1f83ba24b00f3c234241 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Thu, 6 Apr 2023 14:08:24 +0200 Subject: [PATCH 87/98] Update ReportGenerator 5.1.17 -> 5.1.19 --- Build/_build.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Build/_build.csproj b/Build/_build.csproj index 0b15c7a026..520e5c2544 100644 --- a/Build/_build.csproj +++ b/Build/_build.csproj @@ -19,7 +19,7 @@ - + From d4c4eb5b1df000f44fe14facc07d54c32457e57f Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Thu, 6 Apr 2023 14:08:47 +0200 Subject: [PATCH 88/98] Update coveralls 1.1.3 -> v2 This switches the underlying coveralls reporter from https://github.com/nickmerwin/node-coveralls to https://github.com/coverallsapp/coverage-reporter which fixes two problems. 1) A deprecation notice in the github action output: > Warning: The `set-output` command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/ 2) Files containing multiple types did not have coverage information on coveralls.io. 9625e1f23773ad58d54e4b7ec4ad7bbfaed5229c partly fixed this by separating most types to separate files. Left are files with multiple generic variants which we want to keep in the same file. --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7582c7e20e..08caf2633d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,11 +36,11 @@ jobs: files: "TestResults/reports/lcov.info" - name: coveralls - uses: coverallsapp/github-action@1.1.3 + uses: coverallsapp/github-action@v2 if: steps.check_files.outputs.files_exists == 'true' with: github-token: ${{ secrets.GITHUB_TOKEN }} - path-to-lcov: TestResults/reports/lcov.info + file: TestResults/reports/lcov.info - name: Upload artifacts uses: actions/upload-artifact@v3 From 2a95ebd5371d5d9b1df5e2bcf9a7a819bc58f994 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Thu, 6 Apr 2023 18:06:01 +0200 Subject: [PATCH 89/98] Use StartsWith(char value) for modern TFM --- Src/FluentAssertions/CallerIdentifier.cs | 2 +- Src/FluentAssertions/Common/StringExtensions.cs | 2 +- Src/FluentAssertions/SystemExtensions.cs | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Src/FluentAssertions/CallerIdentifier.cs b/Src/FluentAssertions/CallerIdentifier.cs index a3452fb59b..ff9c66f547 100644 --- a/Src/FluentAssertions/CallerIdentifier.cs +++ b/Src/FluentAssertions/CallerIdentifier.cs @@ -243,7 +243,7 @@ private static bool StartsWithNewKeyword(string candidate) private static bool IsStringLiteral(string candidate) { - return candidate.StartsWith("\"", StringComparison.Ordinal); + return candidate.StartsWith('\"'); } private static bool IsNumeric(string candidate) diff --git a/Src/FluentAssertions/Common/StringExtensions.cs b/Src/FluentAssertions/Common/StringExtensions.cs index 73abf90857..7f38809cee 100644 --- a/Src/FluentAssertions/Common/StringExtensions.cs +++ b/Src/FluentAssertions/Common/StringExtensions.cs @@ -88,7 +88,7 @@ public static string Combine(this string @this, string other, string separator = return @this; } - if (other.StartsWith("[", StringComparison.Ordinal)) + if (other.StartsWith('[')) { separator = string.Empty; } diff --git a/Src/FluentAssertions/SystemExtensions.cs b/Src/FluentAssertions/SystemExtensions.cs index 8204372271..9594e97654 100644 --- a/Src/FluentAssertions/SystemExtensions.cs +++ b/Src/FluentAssertions/SystemExtensions.cs @@ -16,4 +16,8 @@ public static bool Contains(this string str, string value, StringComparison comp public static bool Contains(this string str, char value, StringComparison comparison) => str.IndexOf(value, comparison) != -1; + + // https://source.dot.net/#System.Private.CoreLib/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs,1014 + public static bool StartsWith(this string str, char value) => + str.Length != 0 && str[0] == value; } From aad6f1e0bb0677c0148e09ce9f064c2a6443fd0d Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Thu, 6 Apr 2023 18:09:50 +0200 Subject: [PATCH 90/98] Migrate from FxCop to .NET Analyzers https://learn.microsoft.com/en-gb/visualstudio/code-quality/migrate-from-fxcop-analyzers-to-net-analyzers?view=vs-2019 --- .editorconfig | 24 +++++++ Build/.editorconfig | 12 +++- Build/Build.cs | 4 ++ Build/Configuration.cs | 8 ++- Directory.Build.props | 35 +++++++++++ FluentAssertions.sln | 3 + Rules.ruleset | 63 ------------------- .../CustomAssertionAttribute.cs | 1 + ...elfReferenceEquivalencyAssertionOptions.cs | 2 + .../Execution/LateBoundTestFramework.cs | 2 +- .../Execution/NSpecFramework.cs | 8 +-- .../Execution/XUnit2TestFramework.cs | 8 +-- Src/FluentAssertions/FluentAssertions.csproj | 32 ---------- .../Formatting/ValueFormatterAttribute.cs | 1 + .../ObjectAssertionsExtensions.cs | 4 +- .../Primitives/ReferenceTypeAssertions.cs | 2 +- .../Primitives/SimpleTimeSpanAssertions.cs | 2 +- .../Primitives/TimeOnlyAssertions.cs | 2 +- .../Specialized/ExecutionTimeAssertions.cs | 2 +- .../GenericAsyncFunctionAssertions.cs | 2 + .../TaskCompletionSourceAssertions.cs | 4 +- .../TaskCompletionSourceAssertionsBase.cs | 2 +- .../Types/MethodInfoSelectorAssertions.cs | 2 +- .../Types/PropertyInfoSelectorAssertions.cs | 2 +- .../Types/TypeSelectorAssertions.cs | 2 +- TestRules.ruleset | 25 -------- Tests/.editorconfig | 60 +++++++++++++++++- Tests/Approval.Tests/.editorconfig | 7 +++ Tests/AssemblyA/AssemblyA.csproj | 1 - Tests/AssemblyB/AssemblyB.csproj | 1 - .../CollectionSpecs.cs | 2 + .../DataSpecs.cs | 18 +++--- .../DataTableSpecs.cs | 1 - .../FluentAssertions.Equivalency.Specs.csproj | 31 --------- .../Execution/CallerIdentifierSpecs.cs | 4 +- .../FluentAssertions.Specs.csproj | 31 --------- .../Types/MethodInfoSelectorSpecs.cs | 4 +- .../Types/TypeSelectorSpecs.cs | 4 +- .../MSTestV2.Specs/MSTestV2.Specs.csproj | 1 - .../TestFrameworks/MSpec.Specs/.editorconfig | 24 +++++++ .../MSpec.Specs/MSpec.Specs.csproj | 1 - .../TestFrameworks/MSpec.Specs/Rules.ruleset | 16 ----- .../NSpec3.Net47.Specs.csproj | 1 - .../NUnit3.Specs/NUnit3.Specs.csproj | 1 - .../XUnit2.Specs/XUnit2.Specs.csproj | 1 - 45 files changed, 213 insertions(+), 250 deletions(-) delete mode 100644 Rules.ruleset delete mode 100644 TestRules.ruleset create mode 100644 Tests/Approval.Tests/.editorconfig delete mode 100644 Tests/TestFrameworks/MSpec.Specs/Rules.ruleset diff --git a/.editorconfig b/.editorconfig index f0f44a4cee..ee0cd80a17 100644 --- a/.editorconfig +++ b/.editorconfig @@ -134,11 +134,31 @@ dotnet_diagnostic.CA1062.severity = suggestion dotnet_code_quality.CA1062.exclude_extension_method_this_parameter = true dotnet_code_quality.exclude_extension_method_this_parameter = true dotnet_code_quality.null_check_validation_methods = ThrowIfArgumentIsNull +# CA1031: Do not catch general exception types +dotnet_diagnostic.CA1031.severity = none +# CA1303: Do not pass literals as localized parameters +dotnet_diagnostic.CA1303.severity = none +# CA1304: Specify CultureInfo dotnet_diagnostic.CA1304.severity = error +# CA1307: Specify StringComparison for clarity dotnet_diagnostic.CA1307.severity = error +# CA1308: Normalize strings to uppercase dotnet_diagnostic.CA1308.severity = error +# CA1309: Use ordinal StringComparison dotnet_diagnostic.CA1309.severity = error +# CA1724: Type names should not match namespaces +dotnet_diagnostic.CA1724.severity = none +# CA1819: Properties should not return arrays +dotnet_diagnostic.CA1819.severity = none +# CA1851: Possible multiple enumerations of IEnumerable collection. Related to GH-issue #2000 +dotnet_diagnostic.CA1851.severity = suggestion +# CA2007: Do not directly await a Task +dotnet_diagnostic.CA2007.severity = none +# CA2225: Operator overloads have named alternates +dotnet_diagnostic.CA2225.severity = none +# CA3075: Insecure DTD Processing dotnet_diagnostic.CA3075.severity = none +# CA5369: Use XmlReader for Deserialize dotnet_diagnostic.CA5369.severity = none # Banned API Analyzers @@ -317,6 +337,10 @@ dotnet_diagnostic.RCS1124.severity = suggestion # Add exception to documentation comment. Nice suggestion, but we don't want to document exceptions for internal code. dotnet_diagnostic.RCS1140.severity = suggestion +# Missing documentation +dotnet_diagnostic.RCS1141.severity = suggestion +dotnet_diagnostic.RCS1142.severity = suggestion + # Use conditional access. Suggestion because it doesn't always improve readability dotnet_diagnostic.RCS1146.severity = suggestion diff --git a/Build/.editorconfig b/Build/.editorconfig index 5641e0f6df..44c3d20be0 100644 --- a/Build/.editorconfig +++ b/Build/.editorconfig @@ -9,8 +9,16 @@ csharp_style_expression_bodied_properties = true:warning csharp_style_expression_bodied_indexers = true:warning csharp_style_expression_bodied_accessors = true:warning -dotnet_diagnostic.ide0044.severity = none -dotnet_diagnostic.ide0051.severity = none +dotnet_diagnostic.IDE0044.severity = none +dotnet_diagnostic.IDE0051.severity = none +dotnet_diagnostic.RCS1110.severity = none +dotnet_diagnostic.RCS1169.severity = none +dotnet_diagnostic.S2365.severity = none +dotnet_diagnostic.S3903.severity = none +dotnet_diagnostic.SA1009.severity = none +dotnet_diagnostic.SA1111.severity = none +dotnet_diagnostic.SA1306.severity = none +dotnet_diagnostic.SA1400.severity = none # ReSharper properties resharper_place_field_attribute_on_same_line = false diff --git a/Build/Build.cs b/Build/Build.cs index e5c8a6a88e..2c4dff40ef 100644 --- a/Build/Build.cs +++ b/Build/Build.cs @@ -38,7 +38,9 @@ class Build : NukeBuild GitHubActions GitHubActions => GitHubActions.Instance; string BranchSpec => GitHubActions?.Ref; + string BuildNumber => GitHubActions?.RunNumber.ToString(); + string PullRequestBase => GitHubActions?.BaseRef; [Parameter("Use this parameter if you encounter build problems in any way, " + @@ -375,7 +377,9 @@ static bool IsDocumentation(string x) => .ToArray(); Repository Repository => new(GitRepository.LocalDirectory); + Tree TargetBranch => Repository.Branches[PullRequestBase].Tip.Tree; + Tree SourceBranch => Repository.Branches[Repository.Head.FriendlyName].Tip.Tree; bool RunAllTargets => string.IsNullOrWhiteSpace(PullRequestBase) || Changes.Any(x => x.StartsWith("Build")); diff --git a/Build/Configuration.cs b/Build/Configuration.cs index 28711f53d9..63b8965fad 100644 --- a/Build/Configuration.cs +++ b/Build/Configuration.cs @@ -4,9 +4,11 @@ [TypeConverter(typeof(TypeConverter))] public class Configuration : Enumeration { - public static Configuration Debug = new() { Value = nameof(Debug) }; - public static Configuration Release = new() { Value = nameof(Release) }; - public static Configuration CI = new() { Value = nameof(CI) }; + public static Configuration Debug { get; } = new() { Value = nameof(Debug) }; + + public static Configuration Release { get; } = new() { Value = nameof(Release) }; + + public static Configuration CI { get; } = new() { Value = nameof(CI) }; public static implicit operator string(Configuration configuration) { diff --git a/Directory.Build.props b/Directory.Build.props index 0e93053edf..d53bbb8033 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -4,4 +4,39 @@ + + + + + falsetrue + + + + falsefalsefalse + + + + + truelatestAlltrue + + + + + + + + + allruntime; build; native; contentfiles; analyzers; buildtransitive + + + allruntime; build; native; contentfiles; analyzers; buildtransitive + + + allruntime; build; native; contentfiles; analyzers; buildtransitive + + + allruntime; build; native; contentfiles; analyzers; buildtransitive + + + allruntime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Execute.Assertion /// Represents the run-time behavior of a structural equivalency assertion. /// true1591;1573False..\..\Rules.ruleset$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdbtruetrueSee https://fluentassertions.com/releases/Copyright Dennis Doomen 2010-$([System.DateTime]::Now.ToString(yyyy)) - - - - falsefalsefalse <_Parameter1>FluentAssertions.Specs, PublicKey=00240000048000009400000006020000002400005253413100040000010001002d25ff515c85b13ba08f61d466cff5d80a7f28ba197bbf8796085213e7a3406f970d2a4874932fed35db546e89af2da88c194bf1b7f7ac70de7988c78406f7629c547283061282a825616eb7eb48a9514a7570942936020a9bb37dca9ff60b778309900851575614491c6d25018fadb75828f4c7a17bf2d7dc86e7b6eafc5d8f @@ -100,30 +94,4 @@ - - - - - - - - - - allruntime; build; native; contentfiles; analyzers; buildtransitive - - - allruntime; build; native; contentfiles; analyzers; buildtransitive - - - allruntime; build; native; contentfiles; analyzers; buildtransitive - - - allruntime; build; native; contentfiles; analyzers; buildtransitive - - - allruntime; build; native; contentfiles; analyzers; buildtransitive - - - allruntime; build; native; contentfiles; analyzers; buildtransitive for a particular type. /// /// Contains a number of methods to assert that a reference type object is in the expected state. diff --git a/Src/FluentAssertions/Primitives/SimpleTimeSpanAssertions.cs b/Src/FluentAssertions/Primitives/SimpleTimeSpanAssertions.cs index 1493f10a06..9612a6e23b 100644 --- a/Src/FluentAssertions/Primitives/SimpleTimeSpanAssertions.cs +++ b/Src/FluentAssertions/Primitives/SimpleTimeSpanAssertions.cs @@ -18,7 +18,7 @@ public SimpleTimeSpanAssertions(TimeSpan? value) } } -#pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals /// /// Contains a number of methods to assert that a nullable is in the expected state. diff --git a/Src/FluentAssertions/Primitives/TimeOnlyAssertions.cs b/Src/FluentAssertions/Primitives/TimeOnlyAssertions.cs index 557d089c07..b604aa0d28 100644 --- a/Src/FluentAssertions/Primitives/TimeOnlyAssertions.cs +++ b/Src/FluentAssertions/Primitives/TimeOnlyAssertions.cs @@ -20,7 +20,7 @@ public TimeOnlyAssertions(TimeOnly? value) } } -#pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals /// /// Contains a number of methods to assert that a is in the expected state. diff --git a/Src/FluentAssertions/Specialized/ExecutionTimeAssertions.cs b/Src/FluentAssertions/Specialized/ExecutionTimeAssertions.cs index 13e848fc99..35bd6a3c4a 100644 --- a/Src/FluentAssertions/Specialized/ExecutionTimeAssertions.cs +++ b/Src/FluentAssertions/Specialized/ExecutionTimeAssertions.cs @@ -5,7 +5,7 @@ namespace FluentAssertions.Specialized; -#pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals /// /// Provides methods for asserting that the execution time of an satisfies certain conditions. diff --git a/Src/FluentAssertions/Specialized/GenericAsyncFunctionAssertions.cs b/Src/FluentAssertions/Specialized/GenericAsyncFunctionAssertions.cs index 386f497daa..d389955d0e 100644 --- a/Src/FluentAssertions/Specialized/GenericAsyncFunctionAssertions.cs +++ b/Src/FluentAssertions/Specialized/GenericAsyncFunctionAssertions.cs @@ -59,7 +59,9 @@ public GenericAsyncFunctionAssertions(Func> subject, IExtractExcep .FailWith("Expected {context:task} to complete within {0}{reason}.", timeSpan); } +#pragma warning disable CA1849 // Call async methods when in an async method TResult result = success ? task.Result : default; +#pragma warning restore CA1849 // Call async methods when in an async method return new AndWhichConstraint, TResult>(this, result); } diff --git a/Src/FluentAssertions/Specialized/TaskCompletionSourceAssertions.cs b/Src/FluentAssertions/Specialized/TaskCompletionSourceAssertions.cs index 993e6e3ffd..1ad25bb5a9 100644 --- a/Src/FluentAssertions/Specialized/TaskCompletionSourceAssertions.cs +++ b/Src/FluentAssertions/Specialized/TaskCompletionSourceAssertions.cs @@ -5,7 +5,7 @@ namespace FluentAssertions.Specialized; -#pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals #if NET6_0_OR_GREATER @@ -131,7 +131,9 @@ public async Task, T>> Comp .BecauseOf(because, becauseArgs) .FailWith("Expected {context:task} to complete within {0}{reason}.", timeSpan); +#pragma warning disable CA1849 // Call async methods when in an async method T result = subject.Task.IsCompleted ? subject.Task.Result : default; +#pragma warning restore CA1849 // Call async methods when in an async method return new AndWhichConstraint, T>(this, result); } diff --git a/Src/FluentAssertions/Specialized/TaskCompletionSourceAssertionsBase.cs b/Src/FluentAssertions/Specialized/TaskCompletionSourceAssertionsBase.cs index 74393482c7..7cb21a8c39 100644 --- a/Src/FluentAssertions/Specialized/TaskCompletionSourceAssertionsBase.cs +++ b/Src/FluentAssertions/Specialized/TaskCompletionSourceAssertionsBase.cs @@ -6,7 +6,7 @@ namespace FluentAssertions.Specialized; -#pragma warning disable CS0659 +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() /// diff --git a/Src/FluentAssertions/Types/MethodInfoSelectorAssertions.cs b/Src/FluentAssertions/Types/MethodInfoSelectorAssertions.cs index ee88f04078..36cdcc7f0b 100644 --- a/Src/FluentAssertions/Types/MethodInfoSelectorAssertions.cs +++ b/Src/FluentAssertions/Types/MethodInfoSelectorAssertions.cs @@ -9,7 +9,7 @@ namespace FluentAssertions.Types; -#pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals /// /// Implements base functionality for assertions on TaskCompletionSource. /// /// Contains assertions for the objects returned by the parent . diff --git a/Src/FluentAssertions/Types/PropertyInfoSelectorAssertions.cs b/Src/FluentAssertions/Types/PropertyInfoSelectorAssertions.cs index ba243a93fc..2b958aa08a 100644 --- a/Src/FluentAssertions/Types/PropertyInfoSelectorAssertions.cs +++ b/Src/FluentAssertions/Types/PropertyInfoSelectorAssertions.cs @@ -8,7 +8,7 @@ namespace FluentAssertions.Types; -#pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals /// /// Contains assertions for the objects returned by the parent . diff --git a/Src/FluentAssertions/Types/TypeSelectorAssertions.cs b/Src/FluentAssertions/Types/TypeSelectorAssertions.cs index 7ed6307706..e8bfbc1811 100644 --- a/Src/FluentAssertions/Types/TypeSelectorAssertions.cs +++ b/Src/FluentAssertions/Types/TypeSelectorAssertions.cs @@ -8,7 +8,7 @@ namespace FluentAssertions.Types; -#pragma warning disable CS0659 // Ignore not overriding Object.GetHashCode() +#pragma warning disable CS0659, S1206 // Ignore not overriding Object.GetHashCode() #pragma warning disable CA1065 // Ignore throwing NotSupportedException from Equals /// private static Expression ReduceConstantSubExpressions(Expression expression) { - return new ConstantSubExpressionReductionVisitor().Visit(expression); + try + { + return new ConstantSubExpressionReductionVisitor().Visit(expression); + } + catch (InvalidOperationException) + { + // Fallback if we make an invalid rewrite of the expression. + return expression; + } } /// - private static IEnumerable /// Contains a number of methods to assert that all s in a diff --git a/TestRules.ruleset b/TestRules.ruleset deleted file mode 100644 index 11eacf3170..0000000000 --- a/TestRules.ruleset +++ /dev/null @@ -1,25 +0,0 @@ - - \ No newline at end of file diff --git a/Tests/.editorconfig b/Tests/.editorconfig index 18c30fb84d..caeb650817 100644 --- a/Tests/.editorconfig +++ b/Tests/.editorconfig @@ -49,14 +49,20 @@ dotnet_diagnostic.CA1711.severity = none dotnet_diagnostic.CA1714.severity = none # CA1716: Identifiers should not match keywords dotnet_diagnostic.CA1716.severity = none +# CA1720: Identifiers should not contain type names +dotnet_diagnostic.CA1720.severity = none +# CA1812: Type is an internal class that is apparently never instantiated. +dotnet_diagnostic.CA1812.severity = none # CA1813 Avoid unsealed attributes dotnet_diagnostic.CA1813.severity = none # CA1814: Prefer jagged arrays over multidimensional dotnet_diagnostic.CA1814.severity = none -# CA1818: Type is an internal class that is apparently never instantiated. -dotnet_diagnostic.CA1812.severity = none # CA1822: Member does not access instance data and can be marked as static dotnet_diagnostic.CA1822.severity = none +# CA1825: Avoid unnecessary zero-length array allocations. Use Array.Empty - - - - - - - - - - - - - - - - - - - - - - - () instead +dotnet_diagnostic.CA1825.severity = none +# CA1852: A type that's not accessible outside its assembly and has no subtypes within its containing assembly is not marked sealed +dotnet_diagnostic.CA1852.severity = none # CA2000: Dispose objects before losing scope dotnet_diagnostic.CA2000.severity = none # CA2201: Exception type System.Exception is not sufficiently specific @@ -151,9 +157,27 @@ resharper_expression_is_always_null_highlighting = none # ReSharper properties resharper_keep_user_linebreaks = true +# Make class static +dotnet_diagnostic.RCS1102.severity = none + +# Mark local variable as const. +dotnet_diagnostic.RCS1118.severity = none + # Use EventHandler. We have some special cases for testing. dotnet_diagnostic.RCS1159.severity = error +# Unused parameter +dotnet_diagnostic.RCS1163.severity = none + +# Use read-only auto-implemented property +dotnet_diagnostic.RCS1170.severity = none + +# Implement exception constructors +dotnet_diagnostic.RCS1194.severity = none + +# Removed unused method declaration +dotnet_diagnostic.RCS1213.severity = none + # Implement IComparable when implementing IComparable. Disabled since we don't want to be so strict in tests. dotnet_diagnostic.RCS1241.severity = none @@ -163,6 +187,9 @@ dotnet_diagnostic.MA0005.severity = none # 'System.BadImageFormatException' is a reserved exception type. Don't care. dotnet_diagnostic.MA0012.severity = none +# Use an overload of System.ArgumentException with the parameter name. Don't care. +dotnet_diagnostic.MA0013.severity = none + # Do not raise System.ApplicationException type dotnet_diagnostic.MA0014.severity = none @@ -185,4 +212,31 @@ dotnet_diagnostic.MA0051.severity = none dotnet_diagnostic.MA0096.severity = none # A class that implements IComparable or IComparable should override comparison operators. Don't care about this. -dotnet_diagnostic.MA0097.severity = none \ No newline at end of file +dotnet_diagnostic.MA0097.severity = none + +# Rename class to match pascal case naming rules +dotnet_diagnostic.S101.severity = none + +# Remove the unused private method +dotnet_diagnostic.S1144.severity = none + +# Remove this empty class, write its code or make it an "interface" +dotnet_diagnostic.S2094.severity = none + +# Add a nested comment explaining why this method is empty +dotnet_diagnostic.S1186.severity = none + +# Rename this enumeration to remove the 'Enum' suffix +dotnet_diagnostic.S2344.severity = none + +# Provide a getter for 'Property' or replace the property witha 'SetProperty' method +dotnet_diagnostic.S2376.severity = none + +# Use the 'value' parameter in this property set accessor declaration +dotnet_diagnostic.S3237.severity = none + +# Use a constructor overloads that allows a more meaningful exception message to be provided +dotnet_diagnostic.S3928.severity = none + +# Remove this unread private field 'field' or refactor the code to use its value +dotnet_diagnostic.S4487.severity = none \ No newline at end of file diff --git a/Tests/Approval.Tests/.editorconfig b/Tests/Approval.Tests/.editorconfig new file mode 100644 index 0000000000..2ff539ef79 --- /dev/null +++ b/Tests/Approval.Tests/.editorconfig @@ -0,0 +1,7 @@ +[*.cs] + +# SonarLint +# S1144: SonarLint cannot see the private ctor is used in [ClassData] +dotnet_diagnostic.S1144.severity = none +# S3885: "Assembly.Load" should be used +dotnet_diagnostic.S3885.severity = none \ No newline at end of file diff --git a/Tests/AssemblyA/AssemblyA.csproj b/Tests/AssemblyA/AssemblyA.csproj index 78a9f3a0e2..89993ba456 100644 --- a/Tests/AssemblyA/AssemblyA.csproj +++ b/Tests/AssemblyA/AssemblyA.csproj @@ -3,7 +3,6 @@ - netstandard2.0True..\..\Src\FluentAssertions\FluentAssertions.snk..\..\Rules.ruleset diff --git a/Tests/AssemblyB/AssemblyB.csproj b/Tests/AssemblyB/AssemblyB.csproj index 8567f08529..ee88670b77 100644 --- a/Tests/AssemblyB/AssemblyB.csproj +++ b/Tests/AssemblyB/AssemblyB.csproj @@ -3,6 +3,5 @@ - \ No newline at end of file diff --git a/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs index 6fa68a230a..128514b678 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/CollectionSpecs.cs @@ -2072,6 +2072,7 @@ public void When_the_length_of_the_first_dimension_differs_between_the_arrays_it public void When_the_number_of_dimensions_of_the_arrays_are_not_the_same_it_should_throw() { // Arrange +#pragma warning disable format // VS and Rider disagree on how to format a multidimensional array initializer var actual = new[,,] { { @@ -2085,6 +2086,7 @@ public void When_the_number_of_dimensions_of_the_arrays_are_not_the_same_it_shou { 6 } } }; +#pragma warning restore format var expectation = new[,] { diff --git a/Tests/FluentAssertions.Equivalency.Specs/DataSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/DataSpecs.cs index f9a4e64a73..a2d6b77e35 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/DataSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/DataSpecs.cs @@ -414,7 +414,7 @@ private void CopyTablenetstandard2.0True..\..\Src\FluentAssertions\FluentAssertions.snk..\..\Rules.ruleset(TDataTable from, TDataTable to, boo { if (randomizeRowOrder) { - foreach (var row in from.OrderBy(row => Guid.NewGuid())) + foreach (var row in from.OrderBy(_ => Guid.NewGuid())) { to.ImportRow(row); } @@ -591,12 +591,16 @@ public enum ChangeType public static IEnumerable AllChangeTypes => Enum.GetValues(typeof(ChangeType)).Cast().Select(t => new object[] { t }); - public static IEnumerable AllChangeTypesWithAcceptChangesValues => - Enum.GetValues(typeof(ChangeType)).Cast().Join( - new[] { true, false }, - changeType => true, - acceptChanges => true, - (changeType, acceptChanges) => new object[] { changeType, acceptChanges }); + public static IEnumerable AllChangeTypesWithAcceptChangesValues + { + get + { + return + from changeType in Enum.GetValues(typeof(ChangeType)).Cast() + from acceptChanges in new[] { true, false } + select new object[] { changeType, acceptChanges }; + } + } [SuppressMessage("Style", "IDE0010:Add missing cases", Justification = "Every enum value is covered")] protected static void ApplyChange(DataColumnCollection columns, ChangeType changeType) diff --git a/Tests/FluentAssertions.Equivalency.Specs/DataTableSpecs.cs b/Tests/FluentAssertions.Equivalency.Specs/DataTableSpecs.cs index 285c4ec402..419831f2d7 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/DataTableSpecs.cs +++ b/Tests/FluentAssertions.Equivalency.Specs/DataTableSpecs.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Data; using System.Globalization; using System.Linq; diff --git a/Tests/FluentAssertions.Equivalency.Specs/FluentAssertions.Equivalency.Specs.csproj b/Tests/FluentAssertions.Equivalency.Specs/FluentAssertions.Equivalency.Specs.csproj index 6783db4a69..1b8489cd52 100644 --- a/Tests/FluentAssertions.Equivalency.Specs/FluentAssertions.Equivalency.Specs.csproj +++ b/Tests/FluentAssertions.Equivalency.Specs/FluentAssertions.Equivalency.Specs.csproj @@ -1,22 +1,14 @@  - - - - - - net47;net6.0;netcoreapp2.0;netcoreapp2.1;netcoreapp3.1True..\..\Src\FluentAssertions\FluentAssertions.snkfalse..\..\TestRules.ruleset$(NoWarn),IDE0052,1573,1591,1712full - - - - falsefalsefalse - - @@ -69,29 +61,6 @@ - net47;net6.0;netcoreapp2.0;netcoreapp2.1;netcoreapp3.1True..\..\Src\FluentAssertions\FluentAssertions.snkfalse..\..\TestRules.ruleset$(NoWarn),IDE0052,1573,1591,1712full - - - - falsefalsefalse - - - - - - - - - allruntime; build; native; contentfiles; analyzers; buildtransitive - - - allruntime; build; native; contentfiles; analyzers; buildtransitive - - - allruntime; build; native; contentfiles; analyzers; buildtransitive - - - allruntime; build; native; contentfiles; analyzers; buildtransitive - - - allruntime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs b/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs index cbe47fb470..358b6f51c2 100644 --- a/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs +++ b/Tests/FluentAssertions.Specs/Types/MethodInfoSelectorSpecs.cs @@ -445,9 +445,9 @@ public void When_accidentally_using_equals_it_should_throw_a_helpful_error() internal class TestClassForMethodSelector { -#pragma warning disable 67 // "event is never used" +#pragma warning disable 67, S3264 // "event is never used" public event EventHandler SomethingChanged = (_, _) => { }; -#pragma warning restore 67 +#pragma warning restore 67, S3264 public virtual void PublicVirtualVoidMethod() { diff --git a/Tests/FluentAssertions.Specs/Types/TypeSelectorSpecs.cs b/Tests/FluentAssertions.Specs/Types/TypeSelectorSpecs.cs index ff2687f66c..8a09e8bb75 100644 --- a/Tests/FluentAssertions.Specs/Types/TypeSelectorSpecs.cs +++ b/Tests/FluentAssertions.Specs/Types/TypeSelectorSpecs.cs @@ -945,10 +945,10 @@ internal interface InternalInterfaceNotValueType } } -#pragma warning disable RCS1110 // Declare type inside namespace. +#pragma warning disable RCS1110, S3903 // Declare type inside namespace. internal class ClassInGlobalNamespace { } -#pragma warning restore RCS1110 +#pragma warning restore RCS1110, S3903 #endregion diff --git a/Tests/TestFrameworks/MSTestV2.Specs/MSTestV2.Specs.csproj b/Tests/TestFrameworks/MSTestV2.Specs/MSTestV2.Specs.csproj index 756fd1136c..fa1cc88527 100644 --- a/Tests/TestFrameworks/MSTestV2.Specs/MSTestV2.Specs.csproj +++ b/Tests/TestFrameworks/MSTestV2.Specs/MSTestV2.Specs.csproj @@ -3,7 +3,6 @@ - net6.0MSTestV2.SpecsMSTestV2.Specs..\..\..\TestRules.ruleset diff --git a/Tests/TestFrameworks/MSpec.Specs/.editorconfig b/Tests/TestFrameworks/MSpec.Specs/.editorconfig index 94d55ff3e6..771fbd2830 100644 --- a/Tests/TestFrameworks/MSpec.Specs/.editorconfig +++ b/Tests/TestFrameworks/MSpec.Specs/.editorconfig @@ -8,3 +8,27 @@ dotnet_style_readonly_field = true:none # IDE0040: Add accessibility modifiers dotnet_style_require_accessibility_modifiers = for_non_interface_members:none + +# StyleCop +# SA1306: The name of a field in C# does not begin with a lower-case letter. +dotnet_diagnostic.SA1306.severity = none +# SA1310: A field name in C# contains an underscore. +dotnet_diagnostic.SA1310.severity = none +# SA1400: The access modifier for a C# element has not been explicitly defined. +dotnet_diagnostic.SA1400.severity = none +# SA1649: The file name of a C# code file does not match the first type declared in the file. +dotnet_diagnostic.SA1649.severity = none + +# Roslynator +# RCS1169: Make field read-only +dotnet_diagnostic.RCS1169.severity = none +# RCS1213: Remove unused member declaration +dotnet_diagnostic.RCS1213.severity = none + +# SonarLint +# S101: Types should be named in PascalCase +dotnet_diagnostic.S101.severity = none +# S1144: Unused private types or members should be removed +dotnet_diagnostic.S1144.severity = none +# S2933: Fields that are only assigned in the constructor should be "readonly" +dotnet_diagnostic.S2933.severity = none \ No newline at end of file diff --git a/Tests/TestFrameworks/MSpec.Specs/MSpec.Specs.csproj b/Tests/TestFrameworks/MSpec.Specs/MSpec.Specs.csproj index 7973403022..e954efef76 100644 --- a/Tests/TestFrameworks/MSpec.Specs/MSpec.Specs.csproj +++ b/Tests/TestFrameworks/MSpec.Specs/MSpec.Specs.csproj @@ -3,7 +3,6 @@ - net6.0MSpec.SpecsMSpec.SpecsRules.ruleset diff --git a/Tests/TestFrameworks/MSpec.Specs/Rules.ruleset b/Tests/TestFrameworks/MSpec.Specs/Rules.ruleset deleted file mode 100644 index 526932240c..0000000000 --- a/Tests/TestFrameworks/MSpec.Specs/Rules.ruleset +++ /dev/null @@ -1,16 +0,0 @@ - - \ No newline at end of file diff --git a/Tests/TestFrameworks/NSpec3.Net47.Specs/NSpec3.Net47.Specs.csproj b/Tests/TestFrameworks/NSpec3.Net47.Specs/NSpec3.Net47.Specs.csproj index 03e057c9be..6ec84c6e14 100644 --- a/Tests/TestFrameworks/NSpec3.Net47.Specs/NSpec3.Net47.Specs.csproj +++ b/Tests/TestFrameworks/NSpec3.Net47.Specs/NSpec3.Net47.Specs.csproj @@ -3,7 +3,6 @@ - - - - - - - - - - - - - - - net47NSpec3.SpecsNSpec3.Specs..\..\..\TestRules.ruleset diff --git a/Tests/TestFrameworks/NUnit3.Specs/NUnit3.Specs.csproj b/Tests/TestFrameworks/NUnit3.Specs/NUnit3.Specs.csproj index 29d74d3189..f1cc3d3b52 100644 --- a/Tests/TestFrameworks/NUnit3.Specs/NUnit3.Specs.csproj +++ b/Tests/TestFrameworks/NUnit3.Specs/NUnit3.Specs.csproj @@ -3,7 +3,6 @@ - net6.0NUnit3.SpecsNUnit3.Specs..\..\..\TestRules.ruleset diff --git a/Tests/TestFrameworks/XUnit2.Specs/XUnit2.Specs.csproj b/Tests/TestFrameworks/XUnit2.Specs/XUnit2.Specs.csproj index f3c9165b2f..b0c2687735 100644 --- a/Tests/TestFrameworks/XUnit2.Specs/XUnit2.Specs.csproj +++ b/Tests/TestFrameworks/XUnit2.Specs/XUnit2.Specs.csproj @@ -3,7 +3,6 @@ - net47;net6.0XUnit2.SpecsXUnit2.Specs..\..\..\TestRules.ruleset From 2215c31d72cd6d727acfbe17cba32e14f94ba77e Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Fri, 7 Apr 2023 20:19:47 +0200 Subject: [PATCH 91/98] Prevent `InvalidOperationException` when formatting a lambda expression calling a constructor --- ...PredicateLambdaExpressionValueFormatter.cs | 18 +++++++++-- ...cateLambdaExpressionValueFormatterSpecs.cs | 32 +++++++++++++++++++ docs/_pages/releases.md | 3 +- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/Src/FluentAssertions/Formatting/PredicateLambdaExpressionValueFormatter.cs b/Src/FluentAssertions/Formatting/PredicateLambdaExpressionValueFormatter.cs index 0313f1cc16..0408e4487c 100644 --- a/Src/FluentAssertions/Formatting/PredicateLambdaExpressionValueFormatter.cs +++ b/Src/FluentAssertions/Formatting/PredicateLambdaExpressionValueFormatter.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -37,7 +38,15 @@ public void Format(object value, FormattedObjectGraph formattedGraph, Formatting /// @@ -104,6 +113,11 @@ private static bool HasLiftedOperator(Expression expression) => private static bool ExpressionIsConstant(Expression expression) { + if (expression is NewExpression or MemberInitExpression) + { + return false; + } + var visitor = new ParameterDetector(); visitor.Visit(expression); return !visitor.HasParameters; diff --git a/Tests/FluentAssertions.Specs/Formatting/PredicateLambdaExpressionValueFormatterSpecs.cs b/Tests/FluentAssertions.Specs/Formatting/PredicateLambdaExpressionValueFormatterSpecs.cs index d09dcd79cf..b70ce9c4e5 100644 --- a/Tests/FluentAssertions.Specs/Formatting/PredicateLambdaExpressionValueFormatterSpecs.cs +++ b/Tests/FluentAssertions.Specs/Formatting/PredicateLambdaExpressionValueFormatterSpecs.cs @@ -11,6 +11,38 @@ public class PredicateLambdaExpressionValueFormatterSpecs { private readonly PredicateLambdaExpressionValueFormatter formatter = new(); + [Fact] + public void Constructor_expression_with_argument_can_be_formatted() + { + // Arrange + Expression expression = (string arg) => new TestItem { Value = arg }; + + // Act + string result = Formatter.ToString(expression); + + // Assert + result.Should().Be("new TestItem() {Value = arg}"); + } + + [Fact] + public void Constructor_expression_can_be_simplified() + { + // Arrange + string value = "foo"; + Expression expression = () => new TestItem { Value = value }; + + // Act + string result = Formatter.ToString(expression); + + // Assert + result.Should().Be("new TestItem() {Value = \"foo\"}"); + } + + private sealed class TestItem + { + public string Value { get; set; } + } + [Fact] public void When_first_level_properties_are_tested_for_equality_against_constants_then_output_should_be_readable() { diff --git a/docs/_pages/releases.md b/docs/_pages/releases.md index 962a4414cd..d7c2482dc2 100644 --- a/docs/_pages/releases.md +++ b/docs/_pages/releases.md @@ -13,14 +13,13 @@ sidebar: * Added `ThrowWithinAsync` for assertions on `Task` - [#1974](https://github.com/fluentassertions/fluentassertions/pull/1974) * Added support for converting integers to enums using `AutoConversion` - [#2147](https://github.com/fluentassertions/fluentassertions/pull/2147) * Changed exception formatting to include any inner exception - [#2150](https://github.com/fluentassertions/fluentassertions/pull/2150) - * Added an expression overload for `WithoutStrictOrderingFor` - [#2151](https://github.com/fluentassertions/fluentassertions/pull/2151) ### Fixes * Improved robustness of several assertions when they're wrapped in an `AssertionScope` - [#2133](https://github.com/fluentassertions/fluentassertions/pull/2133) * The maximum depth `BeEquivalentTo` uses for recursive comparisons was 9 instead of the expected 10 - [#2145](https://github.com/fluentassertions/fluentassertions/pull/2145) - * Fixed `.Excluding()` and `.For().Exclude()` not working if root is a collection - [#2135](https://github.com/fluentassertions/fluentassertions/pull/2135) +* Prevent `InvalidOperationException` when formatting a lambda expression calling a constructor - [#2176](https://github.com/fluentassertions/fluentassertions/pull/2176) ## 6.10.0 From e12e8abd397cddaf2a450501ca8932243704b475 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Mon, 10 Apr 2023 20:18:27 +0200 Subject: [PATCH 92/98] Use builtin coveralls flag to ignore missing coverage file (#2178) --- .github/workflows/build.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 08caf2633d..111f05e66c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,18 +29,12 @@ jobs: env: NuGetApiKey: ${{ secrets.NUGETAPIKEY }} - - name: Check for 'lcov.info' existence - id: check_files - uses: andstor/file-existence-action@v2 - with: - files: "TestResults/reports/lcov.info" - - name: coveralls uses: coverallsapp/github-action@v2 - if: steps.check_files.outputs.files_exists == 'true' with: github-token: ${{ secrets.GITHUB_TOKEN }} file: TestResults/reports/lcov.info + allow-empty: true - name: Upload artifacts uses: actions/upload-artifact@v3 From ae97fc369b342ee75d1856f27edbb1cd7bdb459c Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sat, 15 Apr 2023 15:45:51 +0200 Subject: [PATCH 93/98] prepare for 6.11 release --- docs/_pages/releases.md | 2 ++ docs/index.html | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/_pages/releases.md b/docs/_pages/releases.md index d7c2482dc2..35e47709b2 100644 --- a/docs/_pages/releases.md +++ b/docs/_pages/releases.md @@ -9,6 +9,8 @@ sidebar: ## Unreleased +## 6.11.0 + ### What's new * Added `ThrowWithinAsync` for assertions on `Task` - [#1974](https://github.com/fluentassertions/fluentassertions/pull/1974) * Added support for converting integers to enums using `AutoConversion` - [#2147](https://github.com/fluentassertions/fluentassertions/pull/2147) diff --git a/docs/index.html b/docs/index.html index 8c6b5121c7..995ff6b927 100644 --- a/docs/index.html +++ b/docs/index.html @@ -6,8 +6,8 @@ overlay_color: "#373737" overlay_filter: "0.7" overlay_image: "/assets/images/fluent_assertions_large_horizontal.svg" - cta_label: "Fluent Assertions 6.10 is out!" - cta_url: "https://fluentassertions.com/releases/#6100" + cta_label: "Fluent Assertions 6.11 is out!" + cta_url: "https://fluentassertions.com/releases/#6110" caption: "Logo by [**IUserName**](https://github.com/IUsername) and icons by [**Zlatko Najdenovski**](https://www.flaticon.com/authors/zlatko-najdenovski) from [Flaticon](https://www.flaticon.com/) " excerpt: '_"There''s a life before Fluent Assertions, and there''s a life after it"_ - [Meisam Alifallahi](https://www.linkedin.com/in/meisam-alifallahi/) From 888050bb61f2813c8a819f50a74df504b645fbdd Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sun, 16 Apr 2023 17:54:01 +0200 Subject: [PATCH 94/98] Revert "Use builtin coveralls flag to ignore missing coverage file (#2178)" (#2183) --- .github/workflows/build.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 111f05e66c..08caf2633d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,12 +29,18 @@ jobs: env: NuGetApiKey: ${{ secrets.NUGETAPIKEY }} + - name: Check for 'lcov.info' existence + id: check_files + uses: andstor/file-existence-action@v2 + with: + files: "TestResults/reports/lcov.info" + - name: coveralls uses: coverallsapp/github-action@v2 + if: steps.check_files.outputs.files_exists == 'true' with: github-token: ${{ secrets.GITHUB_TOKEN }} file: TestResults/reports/lcov.info - allow-empty: true - name: Upload artifacts uses: actions/upload-artifact@v3 From 838f2b2eccde830a2c68ee9de0c8b318ec497fdd Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sun, 16 Apr 2023 15:22:14 +0200 Subject: [PATCH 95/98] Do not interpret double braces as liquid template --- docs/_pages/releases.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_pages/releases.md b/docs/_pages/releases.md index 35e47709b2..507e6a552e 100644 --- a/docs/_pages/releases.md +++ b/docs/_pages/releases.md @@ -237,7 +237,7 @@ sidebar: ### Fixes -* Reported actual value when it contained `{{{{` or `}}}}` - [#1234](https://github.com/fluentassertions/fluentassertions/pull/1234). +* Reported actual value when it contained {% raw %}`{{{{` or `}}}}`{% endraw %} - [#1234](https://github.com/fluentassertions/fluentassertions/pull/1234). * Changed dictionary assertion `NotContainKeys` to honour the key comparer if applicable - [#1233](https://github.com/fluentassertions/fluentassertions/pull/1233). * Ensures that date time assertions like "a is less than an hour after b" don't succeed when `a - b == -30.Minutes()` [#1313](https://github.com/fluentassertions/fluentassertions/pull/1313). * Event raising assertions like `WithSender` and `WithArgs` will only return the events that match the constraints - [#1321](https://github.com/fluentassertions/fluentassertions/pull/1321) From a9b30ef2ef5e19531a6b7c579fa2f6fae73c4d35 Mon Sep 17 00:00:00 2001 From: Dennis Doomen Date: Sun, 16 Apr 2023 18:42:05 +0200 Subject: [PATCH 96/98] Ensure running the site works again --- docs/run.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/run.bat b/docs/run.bat index fbc3f41b8e..f7ef535146 100644 --- a/docs/run.bat +++ b/docs/run.bat @@ -1,6 +1,6 @@ del _site /s /q rem Documentation spell check -..\build.cmd --target SpellCheck +powershell -ExecutionPolicy ByPass -NoProfile -File "..\build.ps1" --target SpellCheck --no-logo bundle exec jekyll serve --incremental \ No newline at end of file From 6f754b13add7a06bbcbbd6acff3fdd81976673e8 Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Sun, 16 Apr 2023 14:14:41 +0200 Subject: [PATCH 97/98] Prepare for .NET 8 analyzers CA1859 suggests using concrete types instead of interfaces --- .../Collections/MaximumMatching/MaximumMatchingSolver.cs | 2 +- Src/FluentAssertions/Common/TypeMemberReflector.cs | 6 +++--- .../Equivalency/Steps/DataColumnEquivalencyStep.cs | 2 +- .../Equivalency/Steps/DictionaryInterfaceInfo.cs | 4 ++-- .../Formatting/PredicateLambdaExpressionValueFormatter.cs | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Src/FluentAssertions/Collections/MaximumMatching/MaximumMatchingSolver.cs b/Src/FluentAssertions/Collections/MaximumMatching/MaximumMatchingSolver.cs index 988964539a..b096f61c99 100644 --- a/Src/FluentAssertions/Collections/MaximumMatching/MaximumMatchingSolver.cs +++ b/Src/FluentAssertions/Collections/MaximumMatching/MaximumMatchingSolver.cs @@ -79,7 +79,7 @@ private IEnumerable FindMatchForPredicate(Predicate predicate, Ma return Enumerable.Empty(); } - private IEnumerable> GetMatchingElements(Predicate predicate) + private List> GetMatchingElements(Predicate predicate) { if (!matchingElementsByPredicate.TryGetValue(predicate, out var matchingElements)) { diff --git a/Src/FluentAssertions/Common/TypeMemberReflector.cs b/Src/FluentAssertions/Common/TypeMemberReflector.cs index 2757cdafb4..5d1569f605 100644 --- a/Src/FluentAssertions/Common/TypeMemberReflector.cs +++ b/Src/FluentAssertions/Common/TypeMemberReflector.cs @@ -38,7 +38,7 @@ where HasNonPrivateGetter(propertyInfo) return query.ToArray(); } - private static IEnumerable GetPropertiesFromHierarchy(Type typeToReflect, MemberVisibility memberVisibility) + private static List GetPropertiesFromHierarchy(Type typeToReflect, MemberVisibility memberVisibility) { bool includeInternals = memberVisibility.HasFlag(MemberVisibility.Internal); @@ -63,7 +63,7 @@ from fieldInfo in GetFieldsFromHierarchy(typeToReflect, visibility) return query.ToArray(); } - private static IEnumerable GetFieldsFromHierarchy(Type typeToReflect, MemberVisibility memberVisibility) + private static List GetFieldsFromHierarchy(Type typeToReflect, MemberVisibility memberVisibility) { bool includeInternals = memberVisibility.HasFlag(MemberVisibility.Internal); @@ -77,7 +77,7 @@ private static IEnumerable GetFieldsFromHierarchy(Type typeToReflect, }); } - private static IEnumerable GetMembersFromHierarchy( + private static List GetMembersFromHierarchy( Type typeToReflect, Func> getMembers) where TMemberInfo : MemberInfo diff --git a/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs b/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs index 54ef3e307b..1e5e2fb180 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DataColumnEquivalencyStep.cs @@ -106,7 +106,7 @@ where match is not null // NOTE: This list of candidate members is duplicated in the XML documentation for the // DataColumn.BeEquivalentTo extension method in DataColumnAssertions.cs. If this ever // needs to change, keep them in sync. - private static readonly ISet CandidateMembers = + private static readonly HashSet CandidateMembers = new HashSet { nameof(DataColumn.AllowDBNull), diff --git a/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs b/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs index 622bf11b7a..0c0c36feac 100644 --- a/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs +++ b/Src/FluentAssertions/Equivalency/Steps/DictionaryInterfaceInfo.cs @@ -15,7 +15,7 @@ internal sealed class DictionaryInterfaceInfo { // ReSharper disable once PossibleNullReferenceException private static readonly MethodInfo ConvertToDictionaryMethod = - new Func>, IDictionary>(ConvertToDictionaryInternal) + new Func>, Dictionary>(ConvertToDictionaryInternal) .GetMethodInfo().GetGenericMethodDefinition(); private static readonly ConcurrentDictionary Cache = new(); @@ -140,7 +140,7 @@ public bool TryConvertFrom(object convertable, out object dictionary) return false; } - private static IDictionary ConvertToDictionaryInternal( + private static Dictionary ConvertToDictionaryInternal( IEnumerable> collection) { return collection.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); diff --git a/Src/FluentAssertions/Formatting/PredicateLambdaExpressionValueFormatter.cs b/Src/FluentAssertions/Formatting/PredicateLambdaExpressionValueFormatter.cs index 0408e4487c..2528b91b33 100644 --- a/Src/FluentAssertions/Formatting/PredicateLambdaExpressionValueFormatter.cs +++ b/Src/FluentAssertions/Formatting/PredicateLambdaExpressionValueFormatter.cs @@ -56,7 +56,7 @@ private static Expression ReduceConstantSubExpressions(Expression expression) /// This simplification is only implemented for the chain of AND operators because this is the most common predicate scenario. /// Similar logic can be implemented in the future for other operators. /// ExtractChainOfExpressionsJoinedWithAndOperator(BinaryExpression binaryExpression) + private static List ExtractChainOfExpressionsJoinedWithAndOperator(BinaryExpression binaryExpression) { var visitor = new AndOperatorChainExtractor(); visitor.Visit(binaryExpression); From 73eb91924fd9303065b78c9a58657e9def86a8bf Mon Sep 17 00:00:00 2001 From: Jonas Nyrup Date: Thu, 20 Apr 2023 18:52:24 +0200 Subject: [PATCH 98/98] Update Ruby dependencies (#2182) --- docs/Gemfile | 2 +- docs/Gemfile.lock | 133 ++++++++++++++++++---------------------------- 2 files changed, 54 insertions(+), 81 deletions(-) diff --git a/docs/Gemfile b/docs/Gemfile index 4e6654a2c4..136ccdaf66 100644 --- a/docs/Gemfile +++ b/docs/Gemfile @@ -1,3 +1,3 @@ source 'https://rubygems.org' gem "github-pages", group: :jekyll_plugins -gem "webrick", "~> 1.7" \ No newline at end of file +gem "webrick", "~> 1.8.1" \ No newline at end of file diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index aa65294a16..15cf99beb1 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -1,65 +1,44 @@ GEM remote: https://rubygems.org/ specs: - activesupport (6.0.4.4) + activesupport (7.0.4.3) concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 0.7, < 2) - minitest (~> 5.1) - tzinfo (~> 1.1) - zeitwerk (~> 2.2, >= 2.2.2) - addressable (2.8.0) - public_suffix (>= 2.0.2, < 5.0) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + addressable (2.8.4) + public_suffix (>= 2.0.2, < 6.0) coffee-script (2.4.1) coffee-script-source execjs coffee-script-source (1.11.1) colorator (1.1.0) - commonmarker (0.17.13) - ruby-enum (~> 0.5) - concurrent-ruby (1.1.9) - dnsruby (1.61.9) - simpleidn (~> 0.1) + commonmarker (0.23.9) + concurrent-ruby (1.2.2) + dnsruby (1.70.0) + simpleidn (~> 0.2.1) em-websocket (0.5.3) eventmachine (>= 0.12.9) http_parser.rb (~> 0) - ethon (0.15.0) + ethon (0.16.0) ffi (>= 1.15.0) eventmachine (1.2.7) eventmachine (1.2.7-x64-mingw32) execjs (2.8.1) - faraday (1.9.3) - faraday-em_http (~> 1.0) - faraday-em_synchrony (~> 1.0) - faraday-excon (~> 1.1) - faraday-httpclient (~> 1.0) - faraday-multipart (~> 1.0) - faraday-net_http (~> 1.0) - faraday-net_http_persistent (~> 1.0) - faraday-patron (~> 1.0) - faraday-rack (~> 1.0) - faraday-retry (~> 1.0) + faraday (2.7.4) + faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) - faraday-em_http (1.0.0) - faraday-em_synchrony (1.0.0) - faraday-excon (1.1.0) - faraday-httpclient (1.0.1) - faraday-multipart (1.0.3) - multipart-post (>= 1.2, < 3) - faraday-net_http (1.0.1) - faraday-net_http_persistent (1.2.0) - faraday-patron (1.0.0) - faraday-rack (1.0.0) - faraday-retry (1.0.3) + faraday-net_http (3.0.2) ffi (1.15.5-x64-mingw-ucrt) ffi (1.15.5-x64-mingw32) forwardable-extended (2.6.0) gemoji (3.0.1) - github-pages (223) + github-pages (228) github-pages-health-check (= 1.17.9) - jekyll (= 3.9.0) + jekyll (= 3.9.3) jekyll-avatar (= 0.7.0) jekyll-coffeescript (= 1.1.1) - jekyll-commonmark-ghpages (= 0.1.6) + jekyll-commonmark-ghpages (= 0.4.0) jekyll-default-layout (= 0.1.4) jekyll-feed (= 0.15.1) jekyll-gist (= 1.5.0) @@ -73,7 +52,7 @@ GEM jekyll-relative-links (= 0.6.1) jekyll-remote-theme (= 0.4.3) jekyll-sass-converter (= 1.5.2) - jekyll-seo-tag (= 2.7.1) + jekyll-seo-tag (= 2.8.0) jekyll-sitemap (= 1.4.0) jekyll-swiss (= 1.0.0) jekyll-theme-architect (= 0.2.0) @@ -91,12 +70,12 @@ GEM jekyll-theme-time-machine (= 0.2.0) jekyll-titles-from-headings (= 0.5.3) jemoji (= 0.12.0) - kramdown (= 2.3.1) + kramdown (= 2.3.2) kramdown-parser-gfm (= 1.1.0) - liquid (= 4.0.3) + liquid (= 4.0.4) mercenary (~> 0.3) minima (= 2.5.1) - nokogiri (>= 1.12.5, < 2.0) + nokogiri (>= 1.13.6, < 2.0) rouge (= 3.26.0) terminal-table (~> 1.4) github-pages-health-check (1.17.9) @@ -105,17 +84,17 @@ GEM octokit (~> 4.0) public_suffix (>= 3.0, < 5.0) typhoeus (~> 1.3) - html-pipeline (2.14.0) + html-pipeline (2.14.3) activesupport (>= 2) nokogiri (>= 1.4) http_parser.rb (0.8.0) - i18n (0.9.5) + i18n (1.12.0) concurrent-ruby (~> 1.0) - jekyll (3.9.0) + jekyll (3.9.3) addressable (~> 2.4) colorator (~> 1.0) em-websocket (~> 0.5) - i18n (~> 0.7) + i18n (>= 0.7, < 2) jekyll-sass-converter (~> 1.0) jekyll-watch (~> 2.0) kramdown (>= 1.17, < 3) @@ -129,13 +108,13 @@ GEM jekyll-coffeescript (1.1.1) coffee-script (~> 2.2) coffee-script-source (~> 1.11.1) - jekyll-commonmark (1.3.1) - commonmarker (~> 0.14) - jekyll (>= 3.7, < 5.0) - jekyll-commonmark-ghpages (0.1.6) - commonmarker (~> 0.17.6) - jekyll-commonmark (~> 1.2) - rouge (>= 2.0, < 4.0) + jekyll-commonmark (1.4.0) + commonmarker (~> 0.22) + jekyll-commonmark-ghpages (0.4.0) + commonmarker (~> 0.23.7) + jekyll (~> 3.9.0) + jekyll-commonmark (~> 1.4.0) + rouge (>= 2.0, < 5.0) jekyll-default-layout (0.1.4) jekyll (~> 3.0) jekyll-feed (0.15.1) @@ -166,7 +145,7 @@ GEM rubyzip (>= 1.3.0, < 3.0) jekyll-sass-converter (1.5.2) sass (~> 3.4) - jekyll-seo-tag (2.7.1) + jekyll-seo-tag (2.8.0) jekyll (>= 3.8, < 5.0) jekyll-sitemap (1.4.0) jekyll (>= 3.7, < 5.0) @@ -219,39 +198,36 @@ GEM gemoji (~> 3.0) html-pipeline (~> 2.2) jekyll (>= 3.0, < 5.0) - kramdown (2.3.1) + kramdown (2.3.2) rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) - liquid (4.0.3) - listen (3.7.1) + liquid (4.0.4) + listen (3.8.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) mercenary (0.3.6) + mini_portile2 (2.8.1) minima (2.5.1) jekyll (>= 3.5, < 5.0) jekyll-feed (~> 0.9) jekyll-seo-tag (~> 2.1) - minitest (5.15.0) - multipart-post (2.1.1) - nokogiri (1.13.1-x64-mingw-ucrt) + minitest (5.18.0) + nokogiri (1.14.3) + mini_portile2 (~> 2.8.0) racc (~> 1.4) - nokogiri (1.13.1-x64-mingw32) - racc (~> 1.4) - octokit (4.22.0) - faraday (>= 0.9) - sawyer (~> 0.8.0, >= 0.5.3) + octokit (4.25.1) + faraday (>= 1, < 3) + sawyer (~> 0.9) pathutil (0.16.2) forwardable-extended (~> 2.6) - public_suffix (4.0.6) - racc (1.6.0) - rb-fsevent (0.11.1) + public_suffix (4.0.7) + racc (1.6.2) + rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) rexml (3.2.5) rouge (3.26.0) - ruby-enum (0.9.0) - i18n ruby2_keywords (0.0.5) rubyzip (2.3.2) safe_yaml (1.0.5) @@ -260,25 +236,22 @@ GEM sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) - sawyer (0.8.2) + sawyer (0.9.2) addressable (>= 2.3.5) - faraday (> 0.8, < 2.0) + faraday (>= 0.17.3, < 3) simpleidn (0.2.1) unf (~> 0.1.4) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) - thread_safe (0.3.6) typhoeus (1.4.0) ethon (>= 0.9.0) - tzinfo (1.2.9) - thread_safe (~> 0.1) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) unf (0.1.4) unf_ext - unf_ext (0.0.8) - unf_ext (0.0.8-x64-mingw32) + unf_ext (0.0.8.2) unicode-display_width (1.8.0) - webrick (1.7.0) - zeitwerk (2.5.4) + webrick (1.8.1) PLATFORMS x64-mingw-ucrt @@ -286,7 +259,7 @@ PLATFORMS DEPENDENCIES github-pages - webrick (~> 1.7) + webrick (~> 1.8.1) BUNDLED WITH 2.3.7