Skip to content

Commit aa54ccf

Browse files
committed
Introduced new FindFirstParent() extension method
The new `FindFirstParent()` extension method is similar to the existing `FindFirst()` method, except it crawls the ancestors instead of the descendants. I've included a unit test for validating the functionality.
1 parent 09be263 commit aa54ccf

2 files changed

Lines changed: 61 additions & 0 deletions

File tree

OnTopic.Tests/TopicQueryingTest.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,26 @@ public void FindAllByAttribute_ReturnsCorrectTopics() {
6969

7070
}
7171

72+
/*==========================================================================================================================
73+
| TEST: FIND FIRST PARENT: RETURNS CORRECT TOPIC
74+
\-------------------------------------------------------------------------------------------------------------------------*/
75+
/// <summary>
76+
/// Given a deeply nested <see cref="Topic"/>, returns the first parent <see cref="Topic"/> which satisfies a delegate.
77+
/// </summary>
78+
[TestMethod]
79+
public void FindFirstParent_ReturnsCorrectTopic() {
80+
81+
var parentTopic = TopicFactory.Create("ParentTopic", "Page", 1);
82+
var childTopic = TopicFactory.Create("ChildTopic", "Page", 5, parentTopic);
83+
var grandChildTopic = TopicFactory.Create("GrandChildTopic", "Page", 20, childTopic);
84+
var greatGrandChildTopic = TopicFactory.Create("GreatGrandChildTopic", "Page", 7, grandChildTopic);
85+
86+
var foundTopic = greatGrandChildTopic.FindFirstParent(t => t.Id.Equals(5));
87+
88+
Assert.ReferenceEquals(childTopic, foundTopic);
89+
90+
}
91+
7292
/*==========================================================================================================================
7393
| TEST: GET ROOT TOPIC: RETURNS ROOT TOPIC
7494
\-------------------------------------------------------------------------------------------------------------------------*/

OnTopic/Querying/TopicExtensions.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,47 @@ public static class TopicExtensions {
6060

6161
}
6262

63+
/*==========================================================================================================================
64+
| METHOD: FIND FIRST PARENT
65+
\-------------------------------------------------------------------------------------------------------------------------*/
66+
/// <summary>
67+
/// Finds the first instance of <see cref="Topic"/> among the parents that satisfies the delegate.
68+
/// </summary>
69+
/// <param name="topic">The instance of the <see cref="Topic"/> to operate against; populated automatically by .NET.</param>
70+
/// <param name="predicate">The function to validate whether a <see cref="Topic"/> should be included in the output.</param>
71+
/// <returns>The first instance of a parent topic to be satisfied.</returns>
72+
public static Topic? FindFirstParent(this Topic topic, Func<Topic, bool> predicate) {
73+
74+
/*------------------------------------------------------------------------------------------------------------------------
75+
| Validate contracts
76+
\-----------------------------------------------------------------------------------------------------------------------*/
77+
Contract.Requires(topic, nameof(topic));
78+
Contract.Requires(predicate, nameof(predicate));
79+
80+
/*------------------------------------------------------------------------------------------------------------------------
81+
| Search attributes
82+
\-----------------------------------------------------------------------------------------------------------------------*/
83+
if (predicate(topic)) {
84+
return topic;
85+
}
86+
87+
/*------------------------------------------------------------------------------------------------------------------------
88+
| Find lowest common root
89+
\-----------------------------------------------------------------------------------------------------------------------*/
90+
while (topic.Parent != null) {
91+
if (predicate(topic.Parent)) {
92+
return topic.Parent;
93+
}
94+
topic = topic.Parent;
95+
}
96+
97+
/*------------------------------------------------------------------------------------------------------------------------
98+
| Indicate no results found
99+
\-----------------------------------------------------------------------------------------------------------------------*/
100+
return null;
101+
102+
}
103+
63104
/*==========================================================================================================================
64105
| METHOD: FIND ALL
65106
\-------------------------------------------------------------------------------------------------------------------------*/

0 commit comments

Comments
 (0)