Skip to content

Commit e2c88f2

Browse files
committed
Finished DiffBuilder
1 parent 0f71d0d commit e2c88f2

28 files changed

+375
-219
lines changed

src/Core/AttributeComparisonSource.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public AttributeComparisonSource(string attributeName, in ComparisonSource eleme
2929
}
3030

3131
#region Equals and HashCode
32-
public bool Equals(AttributeComparisonSource other) => Attribute == other.Attribute && ElementSource.Equals(other.ElementSource) && Path.Equals(other.Path, StringComparison.Ordinal);
32+
public bool Equals(AttributeComparisonSource other) => Object.ReferenceEquals(Attribute, other.Attribute) && Path.Equals(other.Path, StringComparison.Ordinal) && ElementSource.Equals(other.ElementSource) ;
3333
public override int GetHashCode() => (Attribute, ElementSource).GetHashCode();
3434
public override bool Equals(object obj) => obj is AttributeComparisonSource other && Equals(other);
3535
public static bool operator ==(AttributeComparisonSource left, AttributeComparisonSource right) => left.Equals(right);

src/Core/ComparisonSource.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ private static string CalculateNodePath(INode node, int index)
6868
}
6969

7070
#region Equals and HashCode
71-
public bool Equals(ComparisonSource other) => Node == other.Node && Index == other.Index && Path.Equals(other.Path, StringComparison.Ordinal) && SourceType == other.SourceType;
71+
public bool Equals(ComparisonSource other) => Object.ReferenceEquals(Node, other.Node) && Index == other.Index && Path.Equals(other.Path, StringComparison.Ordinal) && SourceType == other.SourceType;
7272
public override int GetHashCode() => _hashCode;
7373
public override bool Equals(object obj) => obj is ComparisonSource other && Equals(other);
7474
public static bool operator ==(ComparisonSource left, ComparisonSource right) => left.Equals(right);

src/Core/Diffs/DiffBase.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System;
2-
using System.Diagnostics;
1+
using System.Diagnostics;
32

43
namespace Egil.AngleSharp.Diffing.Core
54
{

src/Core/Diffs/MissingDiffBase.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using System;
2-
3-
namespace Egil.AngleSharp.Diffing.Core
1+
namespace Egil.AngleSharp.Diffing.Core
42
{
53
public abstract class MissingDiffBase<T> : IDiff where T : struct
64
{

src/Core/Diffs/UnexpectedDiffBase.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System;
2-
using System.Diagnostics;
1+
using System.Diagnostics;
32

43
namespace Egil.AngleSharp.Diffing.Core
54
{

src/Core/HtmlDifferenceEngine.cs

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace Egil.AngleSharp.Diffing.Core
88
{
9+
// TODO: Create a class that holds all working data for a diff, and all the diffing logic itself. A mix between DiffContext and HtmlDifferenceEngine.
910
public class HtmlDifferenceEngine
1011
{
1112
private readonly IFilterStrategy _filterStrategy;

src/Core/SourceMap.cs

-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ public AttributeComparisonSource this[string name]
2222
{
2323
get
2424
{
25-
//if (!_sources.ContainsKey(name))
26-
// throw new ArgumentException($"The map does not contain an attribute comparison source that matches the name '{name}'.");
2725
return _sources[name];
2826
}
2927
}

src/DiffBuilder.cs

+97-10
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
using System;
22
using System.Collections.Generic;
3+
using AngleSharp;
4+
using AngleSharp.Dom;
5+
using AngleSharp.Html.Parser;
36
using Egil.AngleSharp.Diffing.Core;
7+
using Egil.AngleSharp.Diffing.Strategies;
48

59
namespace Egil.AngleSharp.Diffing
610
{
711
public class DiffBuilder
812
{
13+
private readonly IBrowsingContext _context;
14+
private readonly IHtmlParser _htmlParser;
15+
private readonly IDocument _document;
16+
private readonly DiffingStrategyPipeline _strategyPipeline;
17+
918
private string _control = string.Empty;
1019
private string _test = string.Empty;
1120

@@ -16,6 +25,11 @@ public class DiffBuilder
1625
private DiffBuilder(string control)
1726
{
1827
Control = control;
28+
var config = Configuration.Default.WithCss();
29+
_context = BrowsingContext.New(config);
30+
_htmlParser = _context.GetService<IHtmlParser>();
31+
_document = _context.OpenNewAsync().Result;
32+
_strategyPipeline = new DiffingStrategyPipeline();
1933
}
2034

2135
public DiffBuilder WithTest(string test)
@@ -28,26 +42,99 @@ public static DiffBuilder Compare(string control)
2842
{
2943
return new DiffBuilder(control);
3044
}
31-
32-
public DiffBuilder WithFilter(FilterStrategy<ComparisonSource> filterStrategy)
45+
46+
/// <summary>
47+
/// Adds a node filter to the pipeline.
48+
/// Specialized filters always execute after any generalized filters in the pipeline.
49+
/// That enables them to correct for the generic filters decision.
50+
/// </summary>
51+
/// <param name="filterStrategy"></param>
52+
/// <param name="isSpecializedFilter">true if <paramref name="filterStrategy"/> is a specialized filter, false if it is a generalized filter</param>
53+
public DiffBuilder WithFilter(FilterStrategy<ComparisonSource> filterStrategy, bool isSpecializedFilter = true)
54+
{
55+
_strategyPipeline.AddFilter(filterStrategy, isSpecializedFilter);
56+
return this;
57+
}
58+
59+
/// <summary>
60+
/// Adds an attribute filter to the pipeline.
61+
/// Specialized filters always execute after any generalized filters in the pipeline.
62+
/// That enables them to correct for the generic filters decision.
63+
/// </summary>
64+
/// <param name="filterStrategy"></param>
65+
/// <param name="isSpecializedFilter">true if <paramref name="filterStrategy"/> is a specialized filter, false if it is a generalized filter</param>
66+
public DiffBuilder WithFilter(FilterStrategy<AttributeComparisonSource> filterStrategy, bool isSpecializedFilter = true)
67+
{
68+
_strategyPipeline.AddFilter(filterStrategy, isSpecializedFilter);
69+
return this;
70+
}
71+
72+
/// <summary>
73+
/// Adds a node matcher to the pipeline.
74+
/// Specialized matchers always execute before any generalized matchers in the pipeline.
75+
/// This enables the special matchers to handle special matching cases before the more simple generalized matchers process the rest.
76+
/// </summary>
77+
/// <param name="matchStrategy"></param>
78+
/// <param name="isSpecializedMatcher">true if <paramref name="matchStrategy"/> is a specialized matcher, false if it is a generalized matcher</param>
79+
public DiffBuilder WithMatcher(MatchStrategy<SourceCollection, Comparison> matchStrategy, bool isSpecializedMatcher = true)
80+
{
81+
_strategyPipeline.AddMatcher(matchStrategy, isSpecializedMatcher);
82+
return this;
83+
}
84+
85+
/// <summary>
86+
/// Adds an attribute matcher to the pipeline.
87+
/// Specialized matchers always execute before any generalized matchers in the pipeline.
88+
/// This enables the special matchers to handle special matching cases before the more simple generalized matchers process the rest.
89+
/// </summary>
90+
/// <param name="matchStrategy"></param>
91+
/// <param name="isSpecializedMatcher">true if <paramref name="matchStrategy"/> is a specialized matcher, false if it is a generalized matcher</param>
92+
public DiffBuilder WithMatcher(MatchStrategy<SourceMap, AttributeComparison> matchStrategy, bool isSpecializedMatcher = true)
3393
{
94+
_strategyPipeline.AddMatcher(matchStrategy, isSpecializedMatcher);
3495
return this;
3596
}
3697

37-
public DiffBuilder WithFilter(FilterStrategy<AttributeComparisonSource> filterStrategy)
98+
/// <summary>
99+
/// Adds a node comparer to the pipeline.
100+
/// Specialized comparers always execute after any generalized comparers in the pipeline.
101+
/// That enables them to correct for the generic comparers decision.
102+
/// </summary>
103+
/// <param name="compareStrategy"></param>
104+
/// <param name="isSpecializedComparer">true if <paramref name="compareStrategy"/> is a specialized comparer, false if it is a generalized comparer</param>
105+
public DiffBuilder WithComparer(CompareStrategy<Comparison> compareStrategy, bool isSpecializedComparer = true)
38106
{
39-
107+
_strategyPipeline.AddComparer(compareStrategy, isSpecializedComparer);
108+
return this;
109+
}
110+
111+
/// <summary>
112+
/// Adds a attribute comparer to the pipeline.
113+
/// Specialized comparers always execute after any generalized comparers in the pipeline.
114+
/// That enables them to correct for the generic comparers decision.
115+
/// </summary>
116+
/// <param name="compareStrategy"></param>
117+
/// <param name="isSpecializedComparer">true if <paramref name="compareStrategy"/> is a specialized comparer, false if it is a generalized comparer</param>
118+
public DiffBuilder WithComparer(CompareStrategy<AttributeComparison> compareStrategy, bool isSpecializedComparer = true)
119+
{
120+
_strategyPipeline.AddComparer(compareStrategy, isSpecializedComparer);
40121
return this;
41122
}
42123

43124
public IList<IDiff> Build()
44125
{
45-
//var context = BrowsingContext.New();
46-
//var htmlParser = context.GetService<IHtmlParser>();
47-
//var document = context.OpenNewAsync().Result;
48-
//var control = htmlParser.ParseFragment(Control, document.Body);
49-
//var test = htmlParser.ParseFragment(Test, document.Body);
50-
return Array.Empty<IDiff>();
126+
if (!_strategyPipeline.HasMatchers)
127+
throw new InvalidOperationException("No comparer's has been added to the builder. Add at least one and try again.");
128+
if (!_strategyPipeline.HasComparers)
129+
throw new InvalidOperationException("No matcher's has been added to the builder. Add at least one and try again.");
130+
131+
return new HtmlDifferenceEngine(_strategyPipeline, _strategyPipeline, _strategyPipeline)
132+
.Compare(Parse(Control), Parse(Test));
133+
}
134+
135+
private INodeList Parse(string html)
136+
{
137+
return _htmlParser.ParseFragment(html, _document.Body);
51138
}
52139
}
53140
}

src/Strategies/AttributeStrategies/AttributeNameMatcher.cs

-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
63
using Egil.AngleSharp.Diffing.Core;
74

85
namespace Egil.AngleSharp.Diffing.Strategies.AttributeStrategies
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,63 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
1+
using Egil.AngleSharp.Diffing.Strategies.AttributeStrategies;
62

7-
namespace Egil.AngleSharp.Diffing.Strategies.AttributeStrategies
3+
namespace Egil.AngleSharp.Diffing
84
{
9-
public static class DiffingStrategyPipelineExtensions
5+
public static partial class DiffBuilderExtensions
106
{
117
/// <summary>
128
/// Enables ignoring of the special "diff"-attributes during diffing.
139
/// </summary>
14-
public static DiffingStrategyPipeline IgnoreDiffAttributes(this DiffingStrategyPipeline pipeline)
10+
public static DiffBuilder IgnoreDiffAttributes(this DiffBuilder builder)
1511
{
16-
pipeline.AddFilter(IgnoreDiffAttributesFilter.Filter, true);
17-
return pipeline;
12+
builder.WithFilter(IgnoreDiffAttributesFilter.Filter, true);
13+
return builder;
1814
}
1915

2016
/// <summary>
2117
/// Enables the name-based attribute matching strategy during diffing.
2218
/// </summary>
23-
public static DiffingStrategyPipeline WithAttributeNameMatcher(this DiffingStrategyPipeline pipeline)
19+
public static DiffBuilder WithAttributeNameMatcher(this DiffBuilder builder)
2420
{
25-
pipeline.AddMatcher(AttributeNameMatcher.Match, isSpecializedMatcher: false);
26-
return pipeline;
21+
builder.WithMatcher(AttributeNameMatcher.Match, isSpecializedMatcher: false);
22+
return builder;
2723
}
2824

2925
/// <summary>
3026
/// Enables the basic name and value attribute comparer during diffing.
3127
/// </summary>
32-
public static DiffingStrategyPipeline WithAttributeComparer(this DiffingStrategyPipeline pipeline)
28+
public static DiffBuilder WithAttributeComparer(this DiffBuilder builder)
3329
{
34-
pipeline.AddMatcher(PostfixedAttributeMatcher.Match, isSpecializedMatcher: true);
35-
pipeline.AddComparer(AttributeComparer.Compare, isSpecializedComparer: false);
36-
pipeline.AddComparer(IgnoreAttributeComparer.Compare, isSpecializedComparer: true);
37-
return pipeline;
30+
builder.WithMatcher(PostfixedAttributeMatcher.Match, isSpecializedMatcher: true);
31+
builder.WithComparer(AttributeComparer.Compare, isSpecializedComparer: false);
32+
builder.WithComparer(IgnoreAttributeComparer.Compare, isSpecializedComparer: true);
33+
return builder;
3834
}
3935

4036
/// <summary>
4137
/// Enables the special class attribute comparer during diffing.
4238
/// </summary>
43-
public static DiffingStrategyPipeline WithClassAttributeComparer(this DiffingStrategyPipeline pipeline)
39+
public static DiffBuilder WithClassAttributeComparer(this DiffBuilder builder)
4440
{
45-
pipeline.AddComparer(ClassAttributeComparer.Compare, isSpecializedComparer: true);
46-
return pipeline;
41+
builder.WithComparer(ClassAttributeComparer.Compare, isSpecializedComparer: true);
42+
return builder;
4743
}
4844

4945
/// <summary>
5046
/// Enables the special boolean attribute comparer during diffing.
5147
/// </summary>
52-
public static DiffingStrategyPipeline WithBooleanAttributeComparer(this DiffingStrategyPipeline pipeline, BooleanAttributeComparision booleanAttributeComparision)
48+
public static DiffBuilder WithBooleanAttributeComparer(this DiffBuilder builder, BooleanAttributeComparision booleanAttributeComparision)
5349
{
54-
pipeline.AddComparer(new BooleanAttributeComparer(booleanAttributeComparision).Compare, isSpecializedComparer: true);
55-
return pipeline;
50+
builder.WithComparer(new BooleanAttributeComparer(booleanAttributeComparision).Compare, isSpecializedComparer: true);
51+
return builder;
5652
}
5753

5854
/// <summary>
5955
/// Enables the special style attributes comparer during diffing.
6056
/// </summary>
61-
public static DiffingStrategyPipeline WithStyleAttributeComparer(this DiffingStrategyPipeline pipeline)
57+
public static DiffBuilder WithStyleAttributeComparer(this DiffBuilder builder)
6258
{
63-
pipeline.AddComparer(StyleAttributeComparer.Compare, isSpecializedComparer: true);
64-
return pipeline;
59+
builder.WithComparer(StyleAttributeComparer.Compare, isSpecializedComparer: true);
60+
return builder;
6561
}
6662
}
6763
}

src/Strategies/AttributeStrategies/PostfixedAttributeMatcher.cs

-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
64
using Egil.AngleSharp.Diffing.Core;
75

86
namespace Egil.AngleSharp.Diffing.Strategies.AttributeStrategies

src/Strategies/AttributeStrategies/StyleAttributeComparer.cs

-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
62
using Egil.AngleSharp.Diffing.Core;
73
using AngleSharp.Css.Dom;
8-
using AngleSharp.Css.Parser;
94
using AngleSharp.Dom;
105

116
namespace Egil.AngleSharp.Diffing.Strategies.AttributeStrategies
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using Egil.AngleSharp.Diffing.Strategies.CommentStrategies;
2+
3+
namespace Egil.AngleSharp.Diffing
4+
{
5+
public static partial class DiffBuilderExtensions
6+
{
7+
/// <summary>
8+
/// Enables ignoring HTML comments during diffing.
9+
/// </summary>
10+
public static DiffBuilder IgnoreComments(this DiffBuilder builder)
11+
{
12+
builder.WithFilter(IgnoreCommentsFilter.Filter, true);
13+
return builder;
14+
}
15+
}
16+
}

src/Strategies/CommentStrategies/DiffingStrategyPipelineExtensions.cs

-21
This file was deleted.

src/Strategies/DiffingStrategyPipelineExtensions.cs renamed to src/Strategies/DiffBuilderExtensions.cs

+5-13
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,16 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
6-
using Egil.AngleSharp.Diffing.Strategies.AttributeStrategies;
7-
using Egil.AngleSharp.Diffing.Strategies.CommentStrategies;
8-
using Egil.AngleSharp.Diffing.Strategies.ElementStrategies;
9-
using Egil.AngleSharp.Diffing.Strategies.NodeStrategies;
1+
using Egil.AngleSharp.Diffing.Strategies.AttributeStrategies;
102
using Egil.AngleSharp.Diffing.Strategies.TextNodeStrategies;
113

12-
namespace Egil.AngleSharp.Diffing.Strategies
4+
namespace Egil.AngleSharp.Diffing
135
{
14-
public static class DiffingStrategyPipelineExtensions
6+
public static partial class DiffBuilderExtensions
157
{
168
/// <summary>
179
/// Sets up the diffing process using the default options.
1810
/// </summary>
19-
public static DiffingStrategyPipeline WithDefaultOptions(this DiffingStrategyPipeline pipeline)
11+
public static DiffBuilder WithDefaultOptions(this DiffBuilder builder)
2012
{
21-
return pipeline
13+
return builder
2214
.IgnoreDiffAttributes()
2315
.IgnoreComments()
2416
.WithSearchingNodeMatcher()

0 commit comments

Comments
 (0)