-Added JToken.AncestorsAndSelf

-Added Extensions.AncestorsAndSelf and Extensions.DescendantsAndSelf
-Tests
This commit is contained in:
James Newton-King
2014-12-22 17:05:13 +13:00
parent 33ae4624bd
commit f760b78fbe
3 changed files with 186 additions and 31 deletions
@@ -697,6 +697,85 @@ namespace Newtonsoft.Json.Tests.Linq
Assert.AreEqual(a, ancestors[1]);
}
[Test]
public void AncestorsAndSelf()
{
JArray a =
new JArray(
5,
new JArray(1),
new JArray(1, 2),
new JArray(1, 2, 3)
);
JToken t = a[1][0];
List<JToken> ancestors = t.AncestorsAndSelf().ToList();
Assert.AreEqual(3, ancestors.Count());
Assert.AreEqual(t, ancestors[0]);
Assert.AreEqual(a[1], ancestors[1]);
Assert.AreEqual(a, ancestors[2]);
}
[Test]
public void AncestorsAndSelf_Many()
{
JArray a =
new JArray(
5,
new JArray(1),
new JArray(1, 2),
new JArray(1, 2, 3)
);
JObject o = new JObject
{
{"prop1", "value1"}
};
JToken t1 = a[1][0];
JToken t2 = o["prop1"];
List<JToken> source = new List<JToken> {t1, t2};
List<JToken> ancestors = source.AncestorsAndSelf().ToList();
Assert.AreEqual(6, ancestors.Count());
Assert.AreEqual(t1, ancestors[0]);
Assert.AreEqual(a[1], ancestors[1]);
Assert.AreEqual(a, ancestors[2]);
Assert.AreEqual(t2, ancestors[3]);
Assert.AreEqual(o.Property("prop1"), ancestors[4]);
Assert.AreEqual(o, ancestors[5]);
}
[Test]
public void Ancestors_Many()
{
JArray a =
new JArray(
5,
new JArray(1),
new JArray(1, 2),
new JArray(1, 2, 3)
);
JObject o = new JObject
{
{"prop1", "value1"}
};
JToken t1 = a[1][0];
JToken t2 = o["prop1"];
List<JToken> source = new List<JToken> { t1, t2 };
List<JToken> ancestors = source.Ancestors().ToList();
Assert.AreEqual(4, ancestors.Count());
Assert.AreEqual(a[1], ancestors[0]);
Assert.AreEqual(a, ancestors[1]);
Assert.AreEqual(o.Property("prop1"), ancestors[2]);
Assert.AreEqual(o, ancestors[3]);
}
[Test]
public void Descendants()
{
@@ -717,6 +796,35 @@ namespace Newtonsoft.Json.Tests.Linq
Assert.AreEqual(3, (int)descendants[descendants.Count - 1]);
}
[Test]
public void Descendants_Many()
{
JArray a =
new JArray(
5,
new JArray(1),
new JArray(1, 2),
new JArray(1, 2, 3)
);
JObject o = new JObject
{
{"prop1", "value1"}
};
List<JContainer> source = new List<JContainer> { a, o };
List<JToken> descendants = source.Descendants().ToList();
Assert.AreEqual(12, descendants.Count());
Assert.AreEqual(5, (int)descendants[0]);
Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), descendants[descendants.Count - 6]));
Assert.AreEqual(1, (int)descendants[descendants.Count - 5]);
Assert.AreEqual(2, (int)descendants[descendants.Count - 4]);
Assert.AreEqual(3, (int)descendants[descendants.Count - 3]);
Assert.AreEqual(o.Property("prop1"), descendants[descendants.Count - 2]);
Assert.AreEqual(o["prop1"], descendants[descendants.Count - 1]);
}
[Test]
public void DescendantsAndSelf()
{
@@ -738,6 +846,37 @@ namespace Newtonsoft.Json.Tests.Linq
Assert.AreEqual(3, (int)descendantsAndSelf[descendantsAndSelf.Count - 1]);
}
[Test]
public void DescendantsAndSelf_Many()
{
JArray a =
new JArray(
5,
new JArray(1),
new JArray(1, 2),
new JArray(1, 2, 3)
);
JObject o = new JObject
{
{"prop1", "value1"}
};
List<JContainer> source = new List<JContainer> { a, o };
List<JToken> descendantsAndSelf = source.DescendantsAndSelf().ToList();
Assert.AreEqual(14, descendantsAndSelf.Count());
Assert.AreEqual(a, descendantsAndSelf[0]);
Assert.AreEqual(5, (int)descendantsAndSelf[1]);
Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), descendantsAndSelf[descendantsAndSelf.Count - 7]));
Assert.AreEqual(1, (int)descendantsAndSelf[descendantsAndSelf.Count - 6]);
Assert.AreEqual(2, (int)descendantsAndSelf[descendantsAndSelf.Count - 5]);
Assert.AreEqual(3, (int)descendantsAndSelf[descendantsAndSelf.Count - 4]);
Assert.AreEqual(o, descendantsAndSelf[descendantsAndSelf.Count - 3]);
Assert.AreEqual(o.Property("prop1"), descendantsAndSelf[descendantsAndSelf.Count - 2]);
Assert.AreEqual(o["prop1"], descendantsAndSelf[descendantsAndSelf.Count - 1]);
}
[Test]
public void CreateWriter()
{
+30 -27
View File
@@ -46,7 +46,7 @@ namespace Newtonsoft.Json.Linq
/// </summary>
/// <typeparam name="T">The type of the objects in source, constrained to <see cref="JToken"/>.</typeparam>
/// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
/// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the ancestors of every node in the source collection.</returns>
/// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the ancestors of every token in the source collection.</returns>
public static IJEnumerable<JToken> Ancestors<T>(this IEnumerable<T> source) where T : JToken
{
ValidationUtils.ArgumentNotNull(source, "source");
@@ -54,20 +54,25 @@ namespace Newtonsoft.Json.Linq
return source.SelectMany(j => j.Ancestors()).AsJEnumerable();
}
//TODO
//public static IEnumerable<JObject> AncestorsAndSelf<T>(this IEnumerable<T> source) where T : JObject
//{
// ValidationUtils.ArgumentNotNull(source, "source");
/// <summary>
/// Returns a collection of tokens that contains every token in the source collection, and the ancestors of every token in the source collection.
/// </summary>
/// <typeparam name="T">The type of the objects in source, constrained to <see cref="JToken"/>.</typeparam>
/// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
/// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains every token in the source collection, the ancestors of every token in the source collection.</returns>
public static IJEnumerable<JToken> AncestorsAndSelf<T>(this IEnumerable<T> source) where T : JToken
{
ValidationUtils.ArgumentNotNull(source, "source");
// return source.SelectMany(j => j.AncestorsAndSelf());
//}
return source.SelectMany(j => j.AncestorsAndSelf()).AsJEnumerable();
}
/// <summary>
/// Returns a collection of tokens that contains the descendants of every token in the source collection.
/// </summary>
/// <typeparam name="T">The type of the objects in source, constrained to <see cref="JContainer"/>.</typeparam>
/// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
/// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the descendants of every node in the source collection.</returns>
/// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the descendants of every token in the source collection.</returns>
public static IJEnumerable<JToken> Descendants<T>(this IEnumerable<T> source) where T : JContainer
{
ValidationUtils.ArgumentNotNull(source, "source");
@@ -75,13 +80,18 @@ namespace Newtonsoft.Json.Linq
return source.SelectMany(j => j.Descendants()).AsJEnumerable();
}
//TODO
//public static IEnumerable<JObject> DescendantsAndSelf<T>(this IEnumerable<T> source) where T : JContainer
//{
// ValidationUtils.ArgumentNotNull(source, "source");
/// <summary>
/// Returns a collection of tokens that contains every token in the source collection, and the descendants of every token in the source collection.
/// </summary>
/// <typeparam name="T">The type of the objects in source, constrained to <see cref="JContainer"/>.</typeparam>
/// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
/// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains every token in the source collection, and the descendants of every token in the source collection.</returns>
public static IJEnumerable<JToken> DescendantsAndSelf<T>(this IEnumerable<T> source) where T : JContainer
{
ValidationUtils.ArgumentNotNull(source, "source");
// return source.SelectMany(j => j.DescendantsAndSelf());
//}
return source.SelectMany(j => j.DescendantsAndSelf()).AsJEnumerable();
}
/// <summary>
/// Returns a collection of child properties of every object in the source collection.
@@ -100,7 +110,7 @@ namespace Newtonsoft.Json.Linq
/// </summary>
/// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
/// <param name="key">The token key.</param>
/// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the values of every node in the source collection with the given key.</returns>
/// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the values of every token in the source collection with the given key.</returns>
public static IJEnumerable<JToken> Values(this IEnumerable<JToken> source, object key)
{
return Values<JToken, JToken>(source, key).AsJEnumerable();
@@ -110,7 +120,7 @@ namespace Newtonsoft.Json.Linq
/// Returns a collection of child values of every object in the source collection.
/// </summary>
/// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
/// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the values of every node in the source collection.</returns>
/// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the values of every token in the source collection.</returns>
public static IJEnumerable<JToken> Values(this IEnumerable<JToken> source)
{
return source.Values(null);
@@ -122,7 +132,7 @@ namespace Newtonsoft.Json.Linq
/// <typeparam name="U">The type to convert the values to.</typeparam>
/// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
/// <param name="key">The token key.</param>
/// <returns>An <see cref="IEnumerable{T}"/> that contains the converted values of every node in the source collection with the given key.</returns>
/// <returns>An <see cref="IEnumerable{T}"/> that contains the converted values of every token in the source collection with the given key.</returns>
public static IEnumerable<U> Values<U>(this IEnumerable<JToken> source, object key)
{
return Values<JToken, U>(source, key);
@@ -133,7 +143,7 @@ namespace Newtonsoft.Json.Linq
/// </summary>
/// <typeparam name="U">The type to convert the values to.</typeparam>
/// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
/// <returns>An <see cref="IEnumerable{T}"/> that contains the converted values of every node in the source collection.</returns>
/// <returns>An <see cref="IEnumerable{T}"/> that contains the converted values of every token in the source collection.</returns>
public static IEnumerable<U> Values<U>(this IEnumerable<JToken> source)
{
return Values<JToken, U>(source, null);
@@ -203,19 +213,12 @@ namespace Newtonsoft.Json.Linq
//TODO
//public static IEnumerable<T> InDocumentOrder<T>(this IEnumerable<T> source) where T : JObject;
//public static IEnumerable<JToken> Children<T>(this IEnumerable<T> source) where T : JToken
//{
// ValidationUtils.ArgumentNotNull(source, "source");
// return source.SelectMany(c => c.Children());
//}
/// <summary>
/// Returns a collection of child tokens of every array in the source collection.
/// </summary>
/// <typeparam name="T">The source collection type.</typeparam>
/// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
/// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the values of every node in the source collection.</returns>
/// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the values of every token in the source collection.</returns>
public static IJEnumerable<JToken> Children<T>(this IEnumerable<T> source) where T : JToken
{
return Children<T, JToken>(source).AsJEnumerable();
@@ -227,7 +230,7 @@ namespace Newtonsoft.Json.Linq
/// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
/// <typeparam name="U">The type to convert the values to.</typeparam>
/// <typeparam name="T">The source collection type.</typeparam>
/// <returns>An <see cref="IEnumerable{T}"/> that contains the converted values of every node in the source collection.</returns>
/// <returns>An <see cref="IEnumerable{T}"/> that contains the converted values of every token in the source collection.</returns>
public static IEnumerable<U> Children<T, U>(this IEnumerable<T> source) where T : JToken
{
ValidationUtils.ArgumentNotNull(source, "source");
+17 -4
View File
@@ -187,8 +187,7 @@ namespace Newtonsoft.Json.Linq
if (Parent == null)
return string.Empty;
IList<JToken> ancestors = Ancestors().Reverse().ToList();
ancestors.Add(this);
IList<JToken> ancestors = AncestorsAndSelf().Reverse().ToList();
IList<JsonPosition> positions = new List<JsonPosition>();
for (int i = 0; i < ancestors.Count; i++)
@@ -258,9 +257,23 @@ namespace Newtonsoft.Json.Linq
/// <returns>A collection of the ancestor tokens of this token.</returns>
public IEnumerable<JToken> Ancestors()
{
for (JToken parent = Parent; parent != null; parent = parent.Parent)
return GetAncestors(false);
}
/// <summary>
/// Returns a collection of tokens that contain this token, and the ancestors of this token.
/// </summary>
/// <returns>A collection of tokens that contain this token, and the ancestors of this token.</returns>
public IEnumerable<JToken> AncestorsAndSelf()
{
return GetAncestors(true);
}
internal IEnumerable<JToken> GetAncestors(bool self)
{
for (JToken current = self ? this : Parent; current != null; current = current.Parent)
{
yield return parent;
yield return current;
}
}