-
Notifications
You must be signed in to change notification settings - Fork 729
Implemented BeSingle and HaveCount for XElement #1681 #1684
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1c60318
04de03a
5b5d398
88c0bfa
fb63688
70f14c6
c0d2f3d
679fd69
2327fa0
70f4e27
f311bfb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
using System; | ||
using System.Diagnostics; | ||
using System.Linq; | ||
using System.Xml; | ||
using System.Xml.Linq; | ||
|
||
|
@@ -237,6 +238,71 @@ public AndWhichConstraint<XDocumentAssertions, XElement> HaveElement(XName expec | |
return new AndWhichConstraint<XDocumentAssertions, XElement>(this, xElement); | ||
} | ||
|
||
/// <summary> | ||
/// Asserts that the <see cref="XDocument.Root"/> element of the current <see cref="XDocument"/> has a single | ||
/// child element with the specified <paramref name="expected"/> name. | ||
/// </summary> | ||
/// <param name="expected"> | ||
/// The full name <see cref="XName"/> of the expected child element of the current document's Root <see cref="XDocument.Root"/> element. | ||
/// </param> | ||
/// <param name="because"> | ||
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion | ||
/// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically. | ||
/// </param> | ||
/// <param name="becauseArgs"> | ||
/// Zero or more objects to format using the placeholders in <paramref name="because" />. | ||
/// </param> | ||
public AndConstraint<XDocumentAssertions> HaveSingleElement(XName expected, string because = "", params object[] becauseArgs) | ||
{ | ||
return HaveElementCount(expected, 1, because, becauseArgs); | ||
} | ||
|
||
/// <summary> | ||
/// Asserts that the <see cref="XDocument.Root"/> element of the current <see cref="XDocument"/> has a the specified <paramref name="count"/> of | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's a typo around "has a the specified" |
||
/// child elements with the specified <paramref name="expected"/> name. | ||
/// </summary> | ||
/// <param name="expected"> | ||
/// The full name <see cref="XName"/> of the expected child element of the current document's Root <see cref="XDocument.Root"/> element. | ||
/// </param> | ||
/// <param name="count">The expected count of elements in the document.</param> | ||
/// <param name="because"> | ||
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion | ||
/// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically. | ||
/// </param> | ||
/// <param name="becauseArgs"> | ||
/// Zero or more objects to format using the placeholders in <paramref name="because" />. | ||
/// </param> | ||
public AndConstraint<XDocumentAssertions> HaveElementCount(XName expected, int count, string because = "", | ||
params object[] becauseArgs) | ||
{ | ||
if (Subject is null) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The subject being |
||
{ | ||
throw new InvalidOperationException("Cannot assert the count if the document itself is <null>."); | ||
} | ||
|
||
Guard.ThrowIfArgumentIsNull(expected, nameof(expected), | ||
"Cannot assert the document has an element count if the element name is <null>*"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should the trailing |
||
|
||
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()); | ||
|
||
var xElements = Subject.Root.Elements(expected); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If |
||
int actualCount = xElements.Count(); | ||
|
||
Execute.Assertion | ||
.ForCondition(actualCount == count) | ||
.BecauseOf(because, becauseArgs) | ||
.FailWith( | ||
"Expected {context:subject} to have {0} child element(s) {1}{reason}, but found {2}.", | ||
count, expected.ToString(), actualCount); | ||
|
||
return new AndConstraint<XDocumentAssertions>(this); | ||
} | ||
|
||
/// <summary> | ||
/// Returns the type of the subject the assertion applies on. | ||
/// </summary> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1111,5 +1111,105 @@ public void When_asserting_a_document_has_a_null_element_it_should_fail() | |
} | ||
|
||
#endregion | ||
|
||
#region HaveSingleElement | ||
|
||
[Fact] | ||
public void When_asserting_document_has_a_single_child_element_and_it_does_it_should_succeed() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔧 I suggest to keep the name more functional and concise: |
||
{ | ||
// Arrange | ||
var document = XDocument.Parse( | ||
@"<parent> | ||
<child /> | ||
</parent>"); | ||
|
||
// Act / Assert | ||
document.Should().HaveSingleElement("child"); | ||
} | ||
|
||
[Fact] | ||
public void When_asserting_document_has_single_child_element_but_it_does_have_two_it_should_fail() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔧 Suggestion: |
||
{ | ||
// Arrange | ||
var document = XDocument.Parse( | ||
@"<parent> | ||
<child /> | ||
<child /> | ||
</parent>"); | ||
|
||
// Act | ||
Action act = () => document.Should().HaveSingleElement("child"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could also validate that |
||
|
||
// Assert | ||
act.Should().Throw<XunitException>().WithMessage( | ||
"Expected document to have 1 child element(s) \"child\", but found 2."); | ||
} | ||
|
||
[Fact] | ||
public void When_asserting_a_null_xDocument_to_have_a_single_element_it_should_fail() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔧 Suggestion: |
||
{ | ||
// Arrange | ||
XDocument xDocument = null; | ||
|
||
// Act | ||
Action act = () => xDocument.Should().HaveSingleElement("child"); | ||
|
||
// Assert | ||
act.Should().Throw<InvalidOperationException>().WithMessage( | ||
"Cannot assert the count if the document itself is <null>."); | ||
} | ||
|
||
#endregion | ||
|
||
#region HaveElementCount | ||
|
||
[Fact] | ||
public void When_asserting_document_has_two_child_elements_and_it_does_it_should_succeed() | ||
{ | ||
// Arrange | ||
var document = XDocument.Parse( | ||
@"<parent> | ||
<child /> | ||
<child /> | ||
</parent>"); | ||
|
||
// Act / Assert | ||
document.Should().HaveElementCount("child", 2); | ||
} | ||
|
||
[Fact] | ||
public void When_asserting_document_has_two_child_elements_but_it_does_have_three_it_should_fail() | ||
{ | ||
// Arrange | ||
var document = XDocument.Parse( | ||
@"<parent> | ||
<child /> | ||
<child /> | ||
<child /> | ||
</parent>"); | ||
|
||
// Act | ||
Action act = () => document.Should().HaveElementCount("child", 2); | ||
|
||
// Assert | ||
act.Should().Throw<XunitException>().WithMessage( | ||
"Expected document to have 2 child element(s) \"child\", but found 3."); | ||
} | ||
|
||
[Fact] | ||
public void When_asserting_a_null_xDocument_to_have_a_element_count_it_should_fail() | ||
{ | ||
// Arrange | ||
XDocument xDocument = null; | ||
|
||
// Act | ||
Action act = () => xDocument.Should().HaveElementCount("child", 1); | ||
|
||
// Assert | ||
act.Should().Throw<InvalidOperationException>().WithMessage( | ||
"Cannot assert the count if the document itself is <null>."); | ||
} | ||
|
||
#endregion | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -20,13 +20,15 @@ sidebar: | |||||
* Adding new overloads to all `GreaterOrEqualTo` and `LessOrEqualTo` assertions, adding the word `Than` - [#1673](https://github.com/fluentassertions/fluentassertions/pull/1673) | ||||||
* `BeAsync()` and `NotBeAsync()` are now also available on `MethodInfoSelectorAssertions` - [#1700](https://github.com/fluentassertions/fluentassertions/pull/1700) | ||||||
|
||||||
* Added `HaveSingleElement` and `HaveElementCount` for `XDocument` - [#1681](https://github.com/fluentassertions/fluentassertions/pull/1684) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
### Fixes | ||||||
|
||||||
* Prevent exceptions when asserting on `ImmutableArray<T>` - [#1668](https://github.com/fluentassertions/fluentassertions/pull/1668) | ||||||
* `At` now retains the `DateTimeKind` and keeps sub-second precision when using a `TimeSpan` - [#1687](https://github.com/fluentassertions/fluentassertions/pull/1687). | ||||||
* Removed iteration over enumerable when generating the `BeEmpty` assertion failure message - [#1692](https://github.com/fluentassertions/fluentassertions/pull/1692). | ||||||
* Prevent `ArgumentNullException` when formatting a lambda expression containing an extension method - [#1696](https://github.com/fluentassertions/fluentassertions/pull/1696) | ||||||
* `IgnoringCyclicReferences` in `BeEquivalentTo` now works while comparing value types using `ComparingByMembers` - [#1708](https://github.com/fluentassertions/fluentassertions/pull/1708) | ||||||
* `IgnoringCyclicReferences` in `BeEquivalentTo` now works while comparing value types using `ComparingByMembers` - [#1708](https://github.com/fluentassertions/fluentassertions/pull/1708) | ||||||
* Using `BeEquivalentTo` on a collection with nested collections would complain about missing members - [#1713](https://github.com/fluentassertions/fluentassertions/pull/1713) | ||||||
* Formatting a lambda expression containing lifted operators - [#1714](https://github.com/fluentassertions/fluentassertions/pull/1714). | ||||||
* Performance improvements in `BeEquivalentTo` by caching expensive Reflection operations - [#1719](https://github.com/fluentassertions/fluentassertions/pull/1719) | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should return a
AndWhichConstraint<XDocumentAssertions, XElement>
likeHaveElement
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And use the
Which
thatAndWhichConstraint
exposes in your test