Skip to content

Commit 02484c7

Browse files
committed
Fixed path index calculation
1 parent efd9467 commit 02484c7

File tree

10 files changed

+133
-83
lines changed

10 files changed

+133
-83
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# 0.13.0
2+
3+
Released on ddd, mmmm dd, yyyy.
4+
5+
- Updated path's index' calculation in `ComparisonSource` to only include nodes that implement the IParentNode.
6+
17
# 0.13.0-preview-3
28

39
Released on Sunday, November 24, 2019.

src/AngleSharp.Diffing.Tests/AngleSharp.DiffingTests.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFramework>netcoreapp3.0</TargetFramework>
@@ -10,7 +10,7 @@
1010
<ItemGroup>
1111
<PackageReference Include="AngleSharp" Version="$(AngleSharpVersion)" />
1212
<PackageReference Include="AngleSharp.Css" Version="$(AngleSharpVersion)" />
13-
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="$(FxCopAnalyzersVersion)">
13+
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8">
1414
<PrivateAssets>all</PrivateAssets>
1515
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1616
</PackageReference>

src/AngleSharp.Diffing.Tests/Core/ComparisonSourceTest.cs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Shouldly;
1+
using System;
2+
using Shouldly;
23
using Xunit;
34

45
namespace AngleSharp.Diffing.Core
@@ -65,5 +66,44 @@ public void Test002()
6566

6667
source.GetHashCode().ShouldNotBe(otherSource.GetHashCode());
6768
}
69+
70+
[Theory(DisplayName = "The index in the source's path is based on its position in it's parents" +
71+
"child node list, i.e. excluding other node types that does not contain children")]
72+
[InlineData("<p>", 0, "p(0)")]
73+
[InlineData("text<p>", 1, "p(0)")]
74+
[InlineData("<!--x--><p>", 1, "p(0)")]
75+
[InlineData("<i></i>text<p>", 2, "p(1)")]
76+
[InlineData("<i></i><!--x--><p>", 2, "p(1)")]
77+
public void Test005(string sourceMarkup, int nodeIndex, string expectedPath)
78+
{
79+
var node = ToNodeList(sourceMarkup)[nodeIndex];
80+
81+
var sut = new ComparisonSource(node, ComparisonSourceType.Control);
82+
83+
sut.Path.ShouldBe(expectedPath);
84+
}
85+
86+
[Fact(DisplayName = "The parent path is calculated correctly when not provided")]
87+
public void Test006()
88+
{
89+
var nodes = ToNodeList("<p>txt<br/><i>text</i></p>");
90+
var textNode = nodes[0].ChildNodes[2].FirstChild;
91+
92+
var sut = new ComparisonSource(textNode, ComparisonSourceType.Control);
93+
94+
sut.Path.ShouldBe("p(0) > i(1) > #text(0)");
95+
}
96+
97+
[Fact(DisplayName = "Source uses parent path if provided to construct own path")]
98+
public void Test007()
99+
{
100+
var node = ToNode("<p>");
101+
var parentPath = "SOME > PAHT";
102+
103+
var sut = new ComparisonSource(node, 0, parentPath, ComparisonSourceType.Control);
104+
105+
var expectedPath = ComparisonSource.CombinePath(parentPath, ComparisonSource.GetNodePathSegment(node));
106+
sut.Path.ShouldBe(expectedPath);
107+
}
68108
}
69109
}

src/AngleSharp.Diffing.Tests/Core/HtmlDifferenceEngineTest.cs

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -296,51 +296,7 @@ public void OnlyOnePartHasChildNodes(string control, string test, Type expectedD
296296
results.Count.ShouldBe(2);
297297
results[0].ShouldBeOfType<NodeDiff>();
298298
results[1].ShouldBeOfType(expectedDiffType);
299-
}
300-
301-
[Fact(DisplayName = "Path in Diffs is set correctly when nested nodes are compared")]
302-
public void PathIsSetCorrectly()
303-
{
304-
var ctrlNodes = ToNodeList(@"<main><h1><!--foo--><p>hello world</p></h1></main>");
305-
var testNodes = ToNodeList(@"<!--foo--><main><h1><p>hello world</p></h1></main>");
306-
307-
var sut = CreateHtmlDiffEngine(
308-
nodeMatcher: OneToOneNodeListMatcher,
309-
nodeFilter: RemoveCommentNodeFilter,
310-
nodeComparer: DiffResultNodeComparer);
311-
312-
var results = sut.Compare(ctrlNodes, testNodes).ToList();
313-
314-
results.Count.ShouldBe(4);
315-
results[0].ShouldBeOfType<NodeDiff>().Control.Path.ShouldBe("main(0)");
316-
results[0].ShouldBeOfType<NodeDiff>().Test.Path.ShouldBe("main(1)");
317-
results[1].ShouldBeOfType<NodeDiff>().Control.Path.ShouldBe("main(0) > h1(0)");
318-
results[1].ShouldBeOfType<NodeDiff>().Test.Path.ShouldBe("main(1) > h1(0)");
319-
results[2].ShouldBeOfType<NodeDiff>().Control.Path.ShouldBe("main(0) > h1(0) > p(1)");
320-
results[2].ShouldBeOfType<NodeDiff>().Test.Path.ShouldBe("main(1) > h1(0) > p(0)");
321-
results[3].ShouldBeOfType<NodeDiff>().Control.Path.ShouldBe("main(0) > h1(0) > p(1) > #text(0)");
322-
results[3].ShouldBeOfType<NodeDiff>().Test.Path.ShouldBe("main(1) > h1(0) > p(0) > #text(0)");
323-
}
324-
325-
[Fact(DisplayName = "Attribute path in comparison sources are based on nodes tree structure")]
326-
public void AttributeSourcePathisBasedOnParentElements()
327-
{
328-
var nodes = ToNodeList(@"<p id=""foo""></p>");
329-
330-
var sut = CreateHtmlDiffEngine(
331-
nodeMatcher: OneToOneNodeListMatcher,
332-
nodeFilter: NoneNodeFilter,
333-
nodeComparer: SameResultNodeComparer,
334-
attrMatcher: AttributeNameMatcher,
335-
attrFilter: NoneAttrFilter,
336-
attrComparer: DiffResultAttrComparer);
337-
338-
var results = sut.Compare(nodes, nodes).ToList();
339-
340-
results.Count.ShouldBe(1);
341-
results[0].ShouldBeOfType<AttrDiff>().Control.Path.ShouldBe("p(0)[id]");
342-
results[0].ShouldBeOfType<AttrDiff>().Test.Path.ShouldBe("p(0)[id]");
343-
}
299+
}
344300

345301
[Fact(DisplayName = "Comparison sources have their type set correctly")]
346302
public void ComparisonSourcesHaveCorrectType()

src/AngleSharp.Diffing/AngleSharp.Diffing.csproj

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,30 @@
2727
</PropertyGroup>
2828

2929
<ItemGroup>
30-
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" PrivateAssets="All" />
30+
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
31+
</ItemGroup>
32+
33+
<PropertyGroup>
34+
<AnnotatedReferenceAssemblyVersion>3.0.0</AnnotatedReferenceAssemblyVersion>
35+
</PropertyGroup>
36+
37+
<ItemGroup>
38+
<PackageReference Include="TunnelVisionLabs.ReferenceAssemblyAnnotator" Version="1.0.0-alpha.77" PrivateAssets="all" />
39+
<PackageDownload Include="Microsoft.NETCore.App.Ref" Version="[$(AnnotatedReferenceAssemblyVersion)]" />
3140
</ItemGroup>
3241

3342
<ItemGroup>
3443
<PackageReference Include="AngleSharp" Version="$(AngleSharpVersion)" />
3544
<PackageReference Include="AngleSharp.Css" Version="$(AngleSharpVersion)" />
36-
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="$(FxCopAnalyzersVersion)">
45+
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8">
3746
<PrivateAssets>all</PrivateAssets>
3847
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
3948
</PackageReference>
4049
</ItemGroup>
4150

4251
<ItemGroup>
43-
<None Include="..\..\docs\logo.png" Pack="true" PackagePath="\"/>
44-
<None Include="..\..\LICENSE" Pack="true" PackagePath="\"/>
52+
<None Include="..\..\docs\logo.png" Pack="true" PackagePath="\" />
53+
<None Include="..\..\LICENSE" Pack="true" PackagePath="\" />
4554
</ItemGroup>
4655

4756
</Project>

src/AngleSharp.Diffing/Core/ComparisonSource.cs

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
using System;
1+
using System;
22
using System.Diagnostics;
33
using System.Diagnostics.CodeAnalysis;
44
using AngleSharp.Dom;
55
using AngleSharp.Diffing.Extensions;
6+
using System.Linq;
67

78
namespace AngleSharp.Diffing.Core
89
{
@@ -12,6 +13,8 @@ namespace AngleSharp.Diffing.Core
1213
{
1314
private readonly int _hashCode;
1415

16+
public const char PathSeparatorChar = '>';
17+
1518
public INode Node { get; }
1619

1720
public int Index { get; }
@@ -21,23 +24,18 @@ namespace AngleSharp.Diffing.Core
2124
public ComparisonSourceType SourceType { get; }
2225

2326
public ComparisonSource(INode node, ComparisonSourceType sourceType)
24-
{
25-
Node = node;
26-
Index = GetNodeIndex(node);
27-
Path = CalculateNodePath(node, Index);
28-
SourceType = sourceType;
29-
_hashCode = (Node, Index, Path, SourceType).GetHashCode();
30-
}
27+
: this(node, GetNodeIndex(node), CalculateParentPath(node), sourceType) { }
3128

32-
public ComparisonSource(INode node, int index, string path, ComparisonSourceType sourceType)
29+
public ComparisonSource(INode node, int index, string parentsPath, ComparisonSourceType sourceType)
3330
{
3431
if (node is null) throw new ArgumentNullException(nameof(node));
3532

33+
var pathSegment = GetNodePathSegment(node);
3634
Node = node;
3735
Index = index;
38-
Path = string.IsNullOrEmpty(path)
39-
? $"{Node.NodeName.ToLowerInvariant()}({Index})"
40-
: $"{path} > {Node.NodeName.ToLowerInvariant()}({Index})";
36+
Path = string.IsNullOrEmpty(parentsPath)
37+
? pathSegment
38+
: CombinePath(parentsPath, pathSegment);
4139

4240
SourceType = sourceType;
4341
_hashCode = (Node, Index, Path, SourceType).GetHashCode();
@@ -55,16 +53,46 @@ private static int GetNodeIndex(INode node)
5553
}
5654
}
5755

58-
private static string CalculateNodePath(INode node, int index)
56+
private static string CalculateParentPath(INode node)
5957
{
60-
var path = $"{node.NodeName.ToLowerInvariant()}({index})";
58+
var result = string.Empty;
59+
foreach (var parent in node.GetParents().TakeWhile(x => x.Parent is { }))
60+
{
61+
var pathSegment = GetNodePathSegment(parent);
62+
if (pathSegment is { })
63+
result = CombinePath(pathSegment, result);
64+
}
65+
return result;
66+
}
67+
68+
private static int GetPathIndex(INode node)
69+
{
70+
var result = 0;
6171
var parent = node.Parent;
62-
while (parent is { } && parent.TryGetNodeIndex(out var parentIndex))
72+
var childNodes = parent.ChildNodes;
73+
for (int index = 0; index < childNodes.Length; index++)
6374
{
64-
path = $"{parent.NodeName.ToLowerInvariant()}({parentIndex}) > {path}";
65-
parent = parent.Parent;
75+
if (ReferenceEquals(childNodes[index], node))
76+
return result;
77+
if(childNodes[index] is IParentNode)
78+
result += 1;
6679
}
67-
return path;
80+
throw new InvalidOperationException("Unexpected node tree state. The node was not found in its parents child nodes collection.");
81+
}
82+
83+
public static string GetNodePathSegment(INode node)
84+
{
85+
var index = GetPathIndex(node);
86+
return $"{node.NodeName.ToLowerInvariant()}({index})";
87+
}
88+
89+
public static string CombinePath(string parentPath, string path)
90+
{
91+
if(string.IsNullOrWhiteSpace(parentPath))
92+
return path;
93+
if(string.IsNullOrWhiteSpace(path))
94+
return parentPath;
95+
return $"{parentPath} {PathSeparatorChar} {path}";
6896
}
6997

7098
#region Equals and HashCode

src/AngleSharp.Diffing/Core/HtmlDifferenceEngine.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ public IEnumerable<IDiff> Compare(IEnumerable<INode> controlNodes, IEnumerable<I
3232
var controlSources = controlNodes.ToSourceCollection(ComparisonSourceType.Control);
3333
var testSources = testNodes.ToSourceCollection(ComparisonSourceType.Test);
3434

35+
return Compare(controlSources, testSources);
36+
}
37+
38+
public IEnumerable<IDiff> Compare(SourceCollection controlSources, SourceCollection testSources)
39+
{
40+
if (controlSources is null) throw new ArgumentNullException(nameof(controlSources));
41+
if (testSources is null) throw new ArgumentNullException(nameof(testSources));
42+
3543
var context = CreateDiffContext(controlSources, testSources);
3644

3745
var diffs = CompareNodeLists(context, controlSources, testSources);

src/AngleSharp.Diffing/Extensions/ElementExtensions.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System;
1+
using System;
2+
using System.Collections.Generic;
23
using System.Diagnostics.CodeAnalysis;
34
using AngleSharp.Dom;
45

@@ -75,7 +76,7 @@ public static bool TryGetNodeIndex(this INode node, [NotNullWhen(true)]out int i
7576
{
7677
index = -1;
7778

78-
if(node.ParentElement is null) return false;
79+
if (node.ParentElement is null) return false;
7980

8081
var parentElement = node.ParentElement;
8182

@@ -90,5 +91,15 @@ public static bool TryGetNodeIndex(this INode node, [NotNullWhen(true)]out int i
9091

9192
return false;
9293
}
94+
95+
public static IEnumerable<INode> GetParents(this INode node)
96+
{
97+
var parent = node.Parent;
98+
while (parent is { })
99+
{
100+
yield return parent;
101+
parent = parent.Parent;
102+
}
103+
}
93104
}
94105
}

src/AngleSharp.Diffing/Extensions/NodeListExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public static IEnumerable<ComparisonSource> ToComparisonSourceList(this IEnumera
2525
yield break;
2626
}
2727

28-
public static ComparisonSource ToComparisonSource(this INode node, int index, ComparisonSourceType sourceType, string path = "") => new ComparisonSource(node, index, path, sourceType);
28+
public static ComparisonSource ToComparisonSource(this INode node, int index, ComparisonSourceType sourceType, string path = "")
29+
=> new ComparisonSource(node, index, path, sourceType);
2930
}
3031
}

src/Directory.Build.props

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup>
3-
<Version>0.13.0-preview-1</Version>
3+
<Version>0.13.0</Version>
44
</PropertyGroup>
55

66
<PropertyGroup>
@@ -9,15 +9,6 @@
99
<WarningsAsErrors>CS8600;CS8602;CS8603;CS8625</WarningsAsErrors>
1010
</PropertyGroup>
1111

12-
<PropertyGroup>
13-
<AnnotatedReferenceAssemblyVersion>3.0.0</AnnotatedReferenceAssemblyVersion>
14-
</PropertyGroup>
15-
16-
<ItemGroup>
17-
<PackageReference Include="TunnelVisionLabs.ReferenceAssemblyAnnotator" Version="1.0.0-alpha.77" PrivateAssets="all" />
18-
<PackageDownload Include="Microsoft.NETCore.App.Ref" Version="[$(AnnotatedReferenceAssemblyVersion)]" />
19-
</ItemGroup>
20-
2112
<PropertyGroup>
2213
<AngleSharpVersion>0.13.0</AngleSharpVersion>
2314
<FxCopAnalyzersVersion>2.9.7</FxCopAnalyzersVersion>

0 commit comments

Comments
 (0)