From 6fb2ebe10ca611233cb8892de8db948b1421c808 Mon Sep 17 00:00:00 2001 From: Egil Hansen Date: Sun, 5 Mar 2023 14:48:36 +0000 Subject: [PATCH 1/2] refactor: clean up usings, switc to file scoped namespaces --- .../AngleSharp.DiffingTests.csproj | 2 +- .../Core/AttributeComparisonSourceTest.cs | 139 ++-- .../Core/AttributeComparisonTest.cs | 273 +++--- .../Core/ComparisonSourceTest.cs | 205 +++-- .../Core/DiffingEngineTestBase.cs | 122 ++- .../Core/HtmlDifferenceEngineTest.cs | 786 +++++++++--------- .../Core/SourceCollectionTest.cs | 160 ++-- .../Core/SourceMapTest.cs | 192 ++--- .../DiffBuilderTest.cs | 232 +++--- .../DiffingTestBase.cs | 118 ++- .../DiffingTestFixture.cs | 42 +- .../ShouldlyTestExtensions.cs | 19 +- .../AttributeComparerTest.cs | 175 ++-- .../AttributeNameMatcherTest.cs | 144 ++-- .../BooleanAttributeComparerTest.cs | 114 ++- .../ClassAttributeComparerTest.cs | 107 ++- .../IgnoreAttributeComparerTest.cs | 52 +- .../IgnoreDiffAttributesFilterTest.cs | 47 +- .../OrderingStyleAttributeComparerTest.cs | 105 ++- .../PostfixedAttributeMatcherTest.cs | 116 ++- .../StyleAttributeComparerTest.cs | 89 +- .../IgnoreCommentsFilterTest.cs | 45 +- .../CssSelectorElementMatcherTest.cs | 124 ++- .../IgnoreAttributesElementComparerTest.cs | 61 +- .../IgnoreChildrenElementComparerTest.cs | 61 +- .../IgnoreElementComparerTest.cs | 59 +- .../ForwardSearchingNodeMatcherTest.cs | 220 +++-- .../NodeStrategies/OneToOneNodeMatcherTest.cs | 171 ++-- .../StyleSheetTextNodeComparerTest.cs | 95 +-- .../TextNodeComparerTest.cs | 459 +++++----- .../TextNodeStrategies/TextNodeFilterTest.cs | 181 ++-- .../TextNodeStrategies/TextNodeTestBase.cs | 37 +- src/AngleSharp.Diffing.Tests/Usings.cs | 5 + src/AngleSharp.Diffing.lutconfig | 6 + .../Core/AttributeComparison.cs | 81 +- .../Core/AttributeComparisonSource.cs | 105 ++- src/AngleSharp.Diffing/Core/CompareResult.cs | 77 +- src/AngleSharp.Diffing/Core/Comparison.cs | 123 ++- .../Core/ComparisonSource.cs | 245 +++--- src/AngleSharp.Diffing/Core/DiffContext.cs | 106 ++- src/AngleSharp.Diffing/Core/DiffResult.cs | 33 +- src/AngleSharp.Diffing/Core/DiffTarget.cs | 88 +- src/AngleSharp.Diffing/Core/Diffs/AttrDiff.cs | 19 +- src/AngleSharp.Diffing/Core/Diffs/DiffBase.cs | 53 +- .../Core/Diffs/MissingAttrDiff.cs | 19 +- .../Core/Diffs/MissingDiffBase.cs | 43 +- .../Core/Diffs/MissingNodeDiff.cs | 19 +- src/AngleSharp.Diffing/Core/Diffs/NodeDiff.cs | 19 +- .../Core/Diffs/UnexpectedAttrDiff.cs | 19 +- .../Core/Diffs/UnexpectedDiffBase.cs | 40 +- .../Core/Diffs/UnexpectedNodeDiff.cs | 19 +- src/AngleSharp.Diffing/Core/FilterDecision.cs | 49 +- .../Core/HtmlDifferenceEngine.cs | 294 ++++--- .../Core/IComparisonSource.cs | 29 +- src/AngleSharp.Diffing/Core/IDiff.cs | 25 +- src/AngleSharp.Diffing/Core/IDiffContext.cs | 33 +- .../Core/IDiffingStrategy.cs | 91 +- .../Core/SourceCollection.cs | 212 +++-- .../Core/SourceCollectionRemovePredicate.cs | 13 +- src/AngleSharp.Diffing/Core/SourceMap.cs | 170 ++-- .../Core/SourceMapRemovePredicate.cs | 13 +- src/AngleSharp.Diffing/Core/SourceType.cs | 25 +- src/AngleSharp.Diffing/DiffBuilder.cs | 160 ++-- .../Extensions/CollectionExtensions.cs | 32 +- .../Extensions/ElementExtensions.cs | 225 +++-- .../Extensions/EmptyHtmlCollection.cs | 54 +- .../Extensions/EnumExtensions.cs | 21 +- .../Extensions/NodeExtensions.cs | 140 ++-- .../Extensions/NodeListExtensions.cs | 63 +- .../UnexpectedDOMTreeStructureException.cs | 30 +- src/AngleSharp.Diffing/HtmlDiffer.cs | 217 +++-- .../AttributeStrategies/AttributeComparer.cs | 120 ++- .../AttributeNameMatcher.cs | 40 +- .../BooleanAttributeComparer.cs | 149 ++-- .../BooleanAttributeComparision.cs | 25 +- .../ClassAttributeComparer.cs | 56 +- ...iffingStrategyPipelineBuilderExtensions.cs | 121 ++- .../IgnoreAttributeComparer.cs | 33 +- .../IgnoreDiffAttributesFilter.cs | 33 +- .../OrderingStyleAttributeComparer.cs | 76 +- .../PostfixedAttributeMatcher.cs | 85 +- .../StyleAttributeComparer.cs | 71 +- .../CommentStrategies/CommentComparer.cs | 28 +- ...iffingStrategyPipelineBuilderExtensions.cs | 37 +- .../CommentStrategies/IgnoreCommentsFilter.cs | 28 +- .../Strategies/CompareStrategy.cs | 27 +- .../Strategies/DiffingStrategyPipeline.cs | 235 +++--- ...iffingStrategyPipelineBuilderExtensions.cs | 47 +- .../CssSelectorElementMatcher.cs | 81 +- ...SelectorReturnedTooManyResultsException.cs | 58 +- ...iffingStrategyPipelineBuilderExtensions.cs | 80 +- .../IgnoreAttributesElementComparer.cs | 45 +- .../IgnoreChildrenElementComparer.cs | 45 +- .../IgnoreElementComparer.cs | 45 +- .../Strategies/FilterStrategy.cs | 29 +- .../Strategies/IDiffingStrategyCollection.cs | 105 ++- .../Strategies/MatchStrategy.cs | 37 +- ...iffingStrategyPipelineBuilderExtensions.cs | 35 +- .../ForwardSearchingNodeMatcher.cs | 65 +- .../NodeStrategies/OneToOneNodeMatcher.cs | 50 +- .../Strategies/StrategyType.cs | 25 +- ...iffingStrategyPipelineBuilderExtensions.cs | 37 +- .../StyleSheetTextNodeComparer.cs | 77 +- .../TextNodeStrategies/TextNodeComparer.cs | 196 +++-- .../TextNodeStrategies/TextNodeFilter.cs | 105 ++- .../TextNodeStrategies/WhitespaceOption.cs | 35 +- src/AngleSharp.Diffing/Usings.cs | 9 + src/Directory.Build.props | 3 +- 108 files changed, 4818 insertions(+), 5322 deletions(-) create mode 100644 src/AngleSharp.Diffing.Tests/Usings.cs create mode 100644 src/AngleSharp.Diffing.lutconfig create mode 100644 src/AngleSharp.Diffing/Usings.cs diff --git a/src/AngleSharp.Diffing.Tests/AngleSharp.DiffingTests.csproj b/src/AngleSharp.Diffing.Tests/AngleSharp.DiffingTests.csproj index 4683794..c3605ce 100644 --- a/src/AngleSharp.Diffing.Tests/AngleSharp.DiffingTests.csproj +++ b/src/AngleSharp.Diffing.Tests/AngleSharp.DiffingTests.csproj @@ -6,7 +6,7 @@ AngleSharp.Diffing.Tests AngleSharp.Diffing true - annotations + annotations diff --git a/src/AngleSharp.Diffing.Tests/Core/AttributeComparisonSourceTest.cs b/src/AngleSharp.Diffing.Tests/Core/AttributeComparisonSourceTest.cs index 8daa7ff..6fc2402 100644 --- a/src/AngleSharp.Diffing.Tests/Core/AttributeComparisonSourceTest.cs +++ b/src/AngleSharp.Diffing.Tests/Core/AttributeComparisonSourceTest.cs @@ -1,89 +1,82 @@ -using System; +namespace AngleSharp.Diffing.Core; -using Shouldly; - -using Xunit; - -namespace AngleSharp.Diffing.Core +public class AttributeComparisonSourceTest : DiffingTestBase { - public class AttributeComparisonSourceTest : DiffingTestBase + public AttributeComparisonSourceTest(DiffingTestFixture fixture) : base(fixture) { - public AttributeComparisonSourceTest(DiffingTestFixture fixture) : base(fixture) - { - } - - [Fact(DisplayName = "When a null is used for element source, an exception is thrown")] - public void Test003() - { - Should.Throw(() => new AttributeComparisonSource(null!, new ComparisonSource())); - Should.Throw(() => new AttributeComparisonSource("", new ComparisonSource())); - } - - [Fact(DisplayName = "When a element source does not contain the specified attribute name, an exception is thrown")] - public void Test004() - { - var elementSource = ToComparisonSource(@"
", ComparisonSourceType.Control); + } - Should.Throw(() => new AttributeComparisonSource("notFoundAttr", elementSource)); - } + [Fact(DisplayName = "When a null is used for element source, an exception is thrown")] + public void Test003() + { + Should.Throw(() => new AttributeComparisonSource(null!, new ComparisonSource())); + Should.Throw(() => new AttributeComparisonSource("", new ComparisonSource())); + } - [Fact(DisplayName = "Two sources are equal if all their properties are equal")] - public void Test1() - { - var elementSource = ToComparisonSource(@"
", ComparisonSourceType.Control); - var source = new AttributeComparisonSource("foo", elementSource); - var otherSource = new AttributeComparisonSource("foo", elementSource); + [Fact(DisplayName = "When a element source does not contain the specified attribute name, an exception is thrown")] + public void Test004() + { + var elementSource = ToComparisonSource(@"
", ComparisonSourceType.Control); - source.Equals(otherSource).ShouldBeTrue(); - source.Equals((object)otherSource).ShouldBeTrue(); - (source == otherSource).ShouldBeTrue(); - (source != otherSource).ShouldBeFalse(); - } + Should.Throw(() => new AttributeComparisonSource("notFoundAttr", elementSource)); + } - [Fact(DisplayName = "Two sources are not equal if their attribute is different")] - public void Test11() - { - var elementSource = ToComparisonSource(@"
", ComparisonSourceType.Control); - var source = new AttributeComparisonSource("foo", elementSource); - var otherSource = new AttributeComparisonSource("bar", elementSource); + [Fact(DisplayName = "Two sources are equal if all their properties are equal")] + public void Test1() + { + var elementSource = ToComparisonSource(@"
", ComparisonSourceType.Control); + var source = new AttributeComparisonSource("foo", elementSource); + var otherSource = new AttributeComparisonSource("foo", elementSource); + + source.Equals(otherSource).ShouldBeTrue(); + source.Equals((object)otherSource).ShouldBeTrue(); + (source == otherSource).ShouldBeTrue(); + (source != otherSource).ShouldBeFalse(); + } - source.Equals(otherSource).ShouldBeFalse(); - (source == otherSource).ShouldBeFalse(); - (source != otherSource).ShouldBeTrue(); - } + [Fact(DisplayName = "Two sources are not equal if their attribute is different")] + public void Test11() + { + var elementSource = ToComparisonSource(@"
", ComparisonSourceType.Control); + var source = new AttributeComparisonSource("foo", elementSource); + var otherSource = new AttributeComparisonSource("bar", elementSource); - [Fact(DisplayName = "Two sources are not equal if their element source is different")] - public void Test3() - { - var elementSource = ToComparisonSource(@"
", ComparisonSourceType.Control); - var otherElementSource = ToComparisonSource(@"
", ComparisonSourceType.Control); - var source = new AttributeComparisonSource("foo", elementSource); - var otherSource = new AttributeComparisonSource("bar", otherElementSource); + source.Equals(otherSource).ShouldBeFalse(); + (source == otherSource).ShouldBeFalse(); + (source != otherSource).ShouldBeTrue(); + } - source.Equals(otherSource).ShouldBeFalse(); - (source == otherSource).ShouldBeFalse(); - (source != otherSource).ShouldBeTrue(); - } + [Fact(DisplayName = "Two sources are not equal if their element source is different")] + public void Test3() + { + var elementSource = ToComparisonSource(@"
", ComparisonSourceType.Control); + var otherElementSource = ToComparisonSource(@"
", ComparisonSourceType.Control); + var source = new AttributeComparisonSource("foo", elementSource); + var otherSource = new AttributeComparisonSource("bar", otherElementSource); + + source.Equals(otherSource).ShouldBeFalse(); + (source == otherSource).ShouldBeFalse(); + (source != otherSource).ShouldBeTrue(); + } - [Fact(DisplayName = "GetHashCode correctly returns same value for two equal sources")] - public void Test001() - { - var elementSource = ToComparisonSource(@"
", ComparisonSourceType.Control); - var source = new AttributeComparisonSource("foo", elementSource); - var otherSource = new AttributeComparisonSource("foo", elementSource); + [Fact(DisplayName = "GetHashCode correctly returns same value for two equal sources")] + public void Test001() + { + var elementSource = ToComparisonSource(@"
", ComparisonSourceType.Control); + var source = new AttributeComparisonSource("foo", elementSource); + var otherSource = new AttributeComparisonSource("foo", elementSource); - source.GetHashCode().ShouldBe(otherSource.GetHashCode()); - } + source.GetHashCode().ShouldBe(otherSource.GetHashCode()); + } - [Fact(DisplayName = "GetHashCode correctly returns different values for two unequal sources")] - public void Test002() - { - var elementSource = ToComparisonSource(@"
", ComparisonSourceType.Control); - var otherElementSource = ToComparisonSource(@"
", ComparisonSourceType.Control); - var source = new AttributeComparisonSource("foo", elementSource); - var otherSource = new AttributeComparisonSource("bar", otherElementSource); + [Fact(DisplayName = "GetHashCode correctly returns different values for two unequal sources")] + public void Test002() + { + var elementSource = ToComparisonSource(@"
", ComparisonSourceType.Control); + var otherElementSource = ToComparisonSource(@"
", ComparisonSourceType.Control); + var source = new AttributeComparisonSource("foo", elementSource); + var otherSource = new AttributeComparisonSource("bar", otherElementSource); - source.GetHashCode().ShouldNotBe(otherSource.GetHashCode()); - } + source.GetHashCode().ShouldNotBe(otherSource.GetHashCode()); } } diff --git a/src/AngleSharp.Diffing.Tests/Core/AttributeComparisonTest.cs b/src/AngleSharp.Diffing.Tests/Core/AttributeComparisonTest.cs index e9288c9..d7ec516 100644 --- a/src/AngleSharp.Diffing.Tests/Core/AttributeComparisonTest.cs +++ b/src/AngleSharp.Diffing.Tests/Core/AttributeComparisonTest.cs @@ -1,148 +1,143 @@ -using Shouldly; +namespace AngleSharp.Diffing.Core; -using Xunit; +public class ComparisonTest : DiffingTestBase +{ + public ComparisonTest(DiffingTestFixture fixture) : base(fixture) + { + } + + [Fact(DisplayName = "When Control and Test properties are equal, the equal tests returns true")] + public void Test001() + { + var control = ToComparisonSource(@"

"); + var test = ToComparisonSource(@"

"); + var comparison = new Comparison(control, test); + var otherComparison = new Comparison(control, test); + + comparison.Equals(otherComparison).ShouldBeTrue(); + comparison.Equals((object)otherComparison).ShouldBeTrue(); + (comparison == otherComparison).ShouldBeTrue(); + (comparison != otherComparison).ShouldBeFalse(); + } + + [Fact(DisplayName = "When Control and Test properties not equal, the equal tests returns false")] + public void Test002() + { + var source1 = ToComparisonSource(@"

"); + var source2 = ToComparisonSource(@"

"); + var comparison = new Comparison(source1, source1); + var otherComparison = new Comparison(source2, source2); + + comparison.Equals(otherComparison).ShouldBeFalse(); + comparison.Equals((object)otherComparison).ShouldBeFalse(); + (comparison == otherComparison).ShouldBeFalse(); + (comparison != otherComparison).ShouldBeTrue(); + } + + [Fact(DisplayName = "GetHashCode correctly returns same value for two equal sources")] + public void Test003() + { + var control = ToComparisonSource(@"

"); + var test = ToComparisonSource(@"

"); + var comparison = new Comparison(control, test); + var otherComparison = new Comparison(control, test); + + comparison.GetHashCode().ShouldBe(otherComparison.GetHashCode()); + } + + [Fact(DisplayName = "GetHashCode correctly returns different values for two unequal sources")] + public void Test004() + { + var source1 = ToComparisonSource(@"

"); + var source2 = ToComparisonSource(@"

"); + var comparison = new Comparison(source1, source1); + var otherComparison = new Comparison(source2, source2); + + comparison.GetHashCode().ShouldNotBe(otherComparison.GetHashCode()); + } + + // AreNodeTypesEqual + + [Fact(DisplayName = "GetAttributeElements returns the elements in the attribute comparison")] + public void Test005() + { + var control = ToAttributeComparisonSource(@"
", "foo"); + var test = ToAttributeComparisonSource(@"
", "foo"); + var comparison = new AttributeComparison(control, test); -namespace AngleSharp.Diffing.Core + var (actualCtrlElm, actualTestElm) = comparison.GetAttributeElements(); + + actualCtrlElm.ShouldBe(control.ElementSource.Node); + actualTestElm.ShouldBe(test.ElementSource.Node); + } +} + +public class AttributeComparisonTest : DiffingTestBase { - public class ComparisonTest : DiffingTestBase + public AttributeComparisonTest(DiffingTestFixture fixture) : base(fixture) + { + } + + [Fact(DisplayName = "When Control and Test properties are equal, the equal tests returns true")] + public void Test001() + { + var control = ToAttributeComparisonSource(@"
", "foo"); + var test = ToAttributeComparisonSource(@"
", "foo"); + var comparison = new AttributeComparison(control, test); + var otherComparison = new AttributeComparison(control, test); + + comparison.Equals(otherComparison).ShouldBeTrue(); + comparison.Equals((object)otherComparison).ShouldBeTrue(); + (comparison == otherComparison).ShouldBeTrue(); + (comparison != otherComparison).ShouldBeFalse(); + } + + [Fact(DisplayName = "When Control and Test properties not equal, the equal tests returns false")] + public void Test002() { - public ComparisonTest(DiffingTestFixture fixture) : base(fixture) - { - } - - [Fact(DisplayName = "When Control and Test properties are equal, the equal tests returns true")] - public void Test001() - { - var control = ToComparisonSource(@"

"); - var test = ToComparisonSource(@"

"); - var comparison = new Comparison(control, test); - var otherComparison = new Comparison(control, test); - - comparison.Equals(otherComparison).ShouldBeTrue(); - comparison.Equals((object)otherComparison).ShouldBeTrue(); - (comparison == otherComparison).ShouldBeTrue(); - (comparison != otherComparison).ShouldBeFalse(); - } - - [Fact(DisplayName = "When Control and Test properties not equal, the equal tests returns false")] - public void Test002() - { - var source1 = ToComparisonSource(@"

"); - var source2 = ToComparisonSource(@"

"); - var comparison = new Comparison(source1, source1); - var otherComparison = new Comparison(source2, source2); - - comparison.Equals(otherComparison).ShouldBeFalse(); - comparison.Equals((object)otherComparison).ShouldBeFalse(); - (comparison == otherComparison).ShouldBeFalse(); - (comparison != otherComparison).ShouldBeTrue(); - } - - [Fact(DisplayName = "GetHashCode correctly returns same value for two equal sources")] - public void Test003() - { - var control = ToComparisonSource(@"

"); - var test = ToComparisonSource(@"

"); - var comparison = new Comparison(control, test); - var otherComparison = new Comparison(control, test); - - comparison.GetHashCode().ShouldBe(otherComparison.GetHashCode()); - } - - [Fact(DisplayName = "GetHashCode correctly returns different values for two unequal sources")] - public void Test004() - { - var source1 = ToComparisonSource(@"

"); - var source2 = ToComparisonSource(@"

"); - var comparison = new Comparison(source1, source1); - var otherComparison = new Comparison(source2, source2); - - comparison.GetHashCode().ShouldNotBe(otherComparison.GetHashCode()); - } - - // AreNodeTypesEqual - - [Fact(DisplayName = "GetAttributeElements returns the elements in the attribute comparison")] - public void Test005() - { - var control = ToAttributeComparisonSource(@"
", "foo"); - var test = ToAttributeComparisonSource(@"
", "foo"); - var comparison = new AttributeComparison(control, test); - - var (actualCtrlElm, actualTestElm) = comparison.GetAttributeElements(); - - actualCtrlElm.ShouldBe(control.ElementSource.Node); - actualTestElm.ShouldBe(test.ElementSource.Node); - } + var source1 = ToAttributeComparisonSource(@"
", "foo"); + var source2 = ToAttributeComparisonSource(@"
", "foo"); + var comparison = new AttributeComparison(source1, source1); + var otherComparison = new AttributeComparison(source2, source2); + + comparison.Equals(otherComparison).ShouldBeFalse(); + comparison.Equals((object)otherComparison).ShouldBeFalse(); + (comparison == otherComparison).ShouldBeFalse(); + (comparison != otherComparison).ShouldBeTrue(); } - public class AttributeComparisonTest : DiffingTestBase + [Fact(DisplayName = "GetHashCode correctly returns same value for two equal sources")] + public void Test003() { - public AttributeComparisonTest(DiffingTestFixture fixture) : base(fixture) - { - } - - [Fact(DisplayName = "When Control and Test properties are equal, the equal tests returns true")] - public void Test001() - { - var control = ToAttributeComparisonSource(@"
", "foo"); - var test = ToAttributeComparisonSource(@"
", "foo"); - var comparison = new AttributeComparison(control, test); - var otherComparison = new AttributeComparison(control, test); - - comparison.Equals(otherComparison).ShouldBeTrue(); - comparison.Equals((object)otherComparison).ShouldBeTrue(); - (comparison == otherComparison).ShouldBeTrue(); - (comparison != otherComparison).ShouldBeFalse(); - } - - [Fact(DisplayName = "When Control and Test properties not equal, the equal tests returns false")] - public void Test002() - { - var source1 = ToAttributeComparisonSource(@"
", "foo"); - var source2 = ToAttributeComparisonSource(@"
", "foo"); - var comparison = new AttributeComparison(source1, source1); - var otherComparison = new AttributeComparison(source2, source2); - - comparison.Equals(otherComparison).ShouldBeFalse(); - comparison.Equals((object)otherComparison).ShouldBeFalse(); - (comparison == otherComparison).ShouldBeFalse(); - (comparison != otherComparison).ShouldBeTrue(); - } - - [Fact(DisplayName = "GetHashCode correctly returns same value for two equal sources")] - public void Test003() - { - var control = ToAttributeComparisonSource(@"
", "foo"); - var test = ToAttributeComparisonSource(@"
", "foo"); - var comparison = new AttributeComparison(control, test); - var otherComparison = new AttributeComparison(control, test); - - comparison.GetHashCode().ShouldBe(otherComparison.GetHashCode()); - } - - [Fact(DisplayName = "GetHashCode correctly returns different values for two unequal sources")] - public void Test004() - { - var source1 = ToAttributeComparisonSource(@"
", "foo"); - var source2 = ToAttributeComparisonSource(@"
", "foo"); - var comparison = new AttributeComparison(source1, source1); - var otherComparison = new AttributeComparison(source2, source2); - - comparison.GetHashCode().ShouldNotBe(otherComparison.GetHashCode()); - } - - [Fact(DisplayName = "GetAttributeElements returns the elements in the attribute comparison")] - public void Test005() - { - var control = ToAttributeComparisonSource(@"
", "foo"); - var test = ToAttributeComparisonSource(@"
", "foo"); - var comparison = new AttributeComparison(control, test); - - var (actualCtrlElm, actualTestElm) = comparison.GetAttributeElements(); - - actualCtrlElm.ShouldBe(control.ElementSource.Node); - actualTestElm.ShouldBe(test.ElementSource.Node); - } + var control = ToAttributeComparisonSource(@"
", "foo"); + var test = ToAttributeComparisonSource(@"
", "foo"); + var comparison = new AttributeComparison(control, test); + var otherComparison = new AttributeComparison(control, test); + + comparison.GetHashCode().ShouldBe(otherComparison.GetHashCode()); + } + + [Fact(DisplayName = "GetHashCode correctly returns different values for two unequal sources")] + public void Test004() + { + var source1 = ToAttributeComparisonSource(@"
", "foo"); + var source2 = ToAttributeComparisonSource(@"
", "foo"); + var comparison = new AttributeComparison(source1, source1); + var otherComparison = new AttributeComparison(source2, source2); + + comparison.GetHashCode().ShouldNotBe(otherComparison.GetHashCode()); + } + + [Fact(DisplayName = "GetAttributeElements returns the elements in the attribute comparison")] + public void Test005() + { + var control = ToAttributeComparisonSource(@"
", "foo"); + var test = ToAttributeComparisonSource(@"
", "foo"); + var comparison = new AttributeComparison(control, test); + + var (actualCtrlElm, actualTestElm) = comparison.GetAttributeElements(); + + actualCtrlElm.ShouldBe(control.ElementSource.Node); + actualTestElm.ShouldBe(test.ElementSource.Node); } } diff --git a/src/AngleSharp.Diffing.Tests/Core/ComparisonSourceTest.cs b/src/AngleSharp.Diffing.Tests/Core/ComparisonSourceTest.cs index 47ae7ef..64449ca 100644 --- a/src/AngleSharp.Diffing.Tests/Core/ComparisonSourceTest.cs +++ b/src/AngleSharp.Diffing.Tests/Core/ComparisonSourceTest.cs @@ -1,110 +1,105 @@ -using Shouldly; +namespace AngleSharp.Diffing.Core; -using Xunit; - -namespace AngleSharp.Diffing.Core +public class ComparisonSourceTest : DiffingTestBase { - public class ComparisonSourceTest : DiffingTestBase + public ComparisonSourceTest(DiffingTestFixture fixture) : base(fixture) + { + } + + [Fact(DisplayName = "Two sources are equal if all their properties are equal")] + public void Test1() + { + var node = ToNode("
"); + var source = new ComparisonSource(node, 1, "path", ComparisonSourceType.Control); + var otherSource = new ComparisonSource(node, 1, "path", ComparisonSourceType.Control); + + source.Equals(otherSource).ShouldBeTrue(); + source.Equals((object)otherSource).ShouldBeTrue(); + (source == otherSource).ShouldBeTrue(); + (source != otherSource).ShouldBeFalse(); + } + + [Theory(DisplayName = "Two sources are not equal if one of their properties are not equal")] + [InlineData(2, "path", ComparisonSourceType.Control)] + [InlineData(1, "otherPath", ComparisonSourceType.Control)] + [InlineData(1, "path", ComparisonSourceType.Test)] + public void Test11(int otherIndex, string otherPath, ComparisonSourceType otherSourceType) + { + var node = ToNode("
"); + var source = new ComparisonSource(node, 1, "path", ComparisonSourceType.Control); + var otherSource = new ComparisonSource(node, otherIndex, otherPath, otherSourceType); + + source.Equals(otherSource).ShouldBeFalse(); + (source == otherSource).ShouldBeFalse(); + (source != otherSource).ShouldBeTrue(); + } + + [Fact(DisplayName = "Two sources are not equal if their nodes are not equal")] + public void Test3() + { + var source = new ComparisonSource(ToNode("

"), 1, "path", ComparisonSourceType.Control); + var otherSource = new ComparisonSource(ToNode("

"), 1, "path", ComparisonSourceType.Control); + + source.Equals(otherSource).ShouldBeFalse(); + (source == otherSource).ShouldBeFalse(); + (source != otherSource).ShouldBeTrue(); + } + + [Fact(DisplayName = "GetHashCode correctly returns same value for two equal sources")] + public void Test001() + { + var node = ToNode("
"); + var source = new ComparisonSource(node, 1, "path", ComparisonSourceType.Control); + var otherSource = new ComparisonSource(node, 1, "path", ComparisonSourceType.Control); + + source.GetHashCode().ShouldBe(otherSource.GetHashCode()); + } + [Fact(DisplayName = "GetHashCode correctly returns different values for two unequal sources")] + public void Test002() + { + var source = new ComparisonSource(ToNode("
"), 1, "path", ComparisonSourceType.Control); + var otherSource = new ComparisonSource(ToNode("

"), 2, "path/other", ComparisonSourceType.Test); + + source.GetHashCode().ShouldNotBe(otherSource.GetHashCode()); + } + + [Theory(DisplayName = "The index in the source's path is based on its position in it's parents" + + "child node list")] + [InlineData("

", 0, "p(0)")] + [InlineData("text

", 1, "p(1)")] + [InlineData("

", 1, "p(1)")] + [InlineData("text

", 2, "p(2)")] + [InlineData("

", 2, "p(2)")] + [InlineData("text

text", 2, "#comment(2)")] + public void Test005(string sourceMarkup, int nodeIndex, string expectedPath) { - public ComparisonSourceTest(DiffingTestFixture fixture) : base(fixture) - { - } - - [Fact(DisplayName = "Two sources are equal if all their properties are equal")] - public void Test1() - { - var node = ToNode("
"); - var source = new ComparisonSource(node, 1, "path", ComparisonSourceType.Control); - var otherSource = new ComparisonSource(node, 1, "path", ComparisonSourceType.Control); - - source.Equals(otherSource).ShouldBeTrue(); - source.Equals((object)otherSource).ShouldBeTrue(); - (source == otherSource).ShouldBeTrue(); - (source != otherSource).ShouldBeFalse(); - } - - [Theory(DisplayName = "Two sources are not equal if one of their properties are not equal")] - [InlineData(2, "path", ComparisonSourceType.Control)] - [InlineData(1, "otherPath", ComparisonSourceType.Control)] - [InlineData(1, "path", ComparisonSourceType.Test)] - public void Test11(int otherIndex, string otherPath, ComparisonSourceType otherSourceType) - { - var node = ToNode("
"); - var source = new ComparisonSource(node, 1, "path", ComparisonSourceType.Control); - var otherSource = new ComparisonSource(node, otherIndex, otherPath, otherSourceType); - - source.Equals(otherSource).ShouldBeFalse(); - (source == otherSource).ShouldBeFalse(); - (source != otherSource).ShouldBeTrue(); - } - - [Fact(DisplayName = "Two sources are not equal if their nodes are not equal")] - public void Test3() - { - var source = new ComparisonSource(ToNode("

"), 1, "path", ComparisonSourceType.Control); - var otherSource = new ComparisonSource(ToNode("

"), 1, "path", ComparisonSourceType.Control); - - source.Equals(otherSource).ShouldBeFalse(); - (source == otherSource).ShouldBeFalse(); - (source != otherSource).ShouldBeTrue(); - } - - [Fact(DisplayName = "GetHashCode correctly returns same value for two equal sources")] - public void Test001() - { - var node = ToNode("
"); - var source = new ComparisonSource(node, 1, "path", ComparisonSourceType.Control); - var otherSource = new ComparisonSource(node, 1, "path", ComparisonSourceType.Control); - - source.GetHashCode().ShouldBe(otherSource.GetHashCode()); - } - [Fact(DisplayName = "GetHashCode correctly returns different values for two unequal sources")] - public void Test002() - { - var source = new ComparisonSource(ToNode("
"), 1, "path", ComparisonSourceType.Control); - var otherSource = new ComparisonSource(ToNode("

"), 2, "path/other", ComparisonSourceType.Test); - - source.GetHashCode().ShouldNotBe(otherSource.GetHashCode()); - } - - [Theory(DisplayName = "The index in the source's path is based on its position in it's parents" + - "child node list")] - [InlineData("

", 0, "p(0)")] - [InlineData("text

", 1, "p(1)")] - [InlineData("

", 1, "p(1)")] - [InlineData("text

", 2, "p(2)")] - [InlineData("

", 2, "p(2)")] - [InlineData("text

text", 2, "#comment(2)")] - public void Test005(string sourceMarkup, int nodeIndex, string expectedPath) - { - var node = ToNodeList(sourceMarkup)[nodeIndex]; - - var sut = new ComparisonSource(node, ComparisonSourceType.Control); - - sut.Path.ShouldBe(expectedPath); - } - - [Fact(DisplayName = "The parent path is calculated correctly when not provided")] - public void Test006() - { - var nodes = ToNodeList("

txt
text

"); - var textNode = nodes[0].ChildNodes[2].FirstChild; - - var sut = new ComparisonSource(textNode, ComparisonSourceType.Control); - - sut.Path.ShouldBe("p(0) > i(2) > #text(0)"); - } - - [Fact(DisplayName = "Source uses parent path if provided to construct own path")] - public void Test007() - { - var node = ToNode("

"); - var parentPath = "SOME > PAHT"; - - var sut = new ComparisonSource(node, 0, parentPath, ComparisonSourceType.Control); - - var expectedPath = ComparisonSource.CombinePath(parentPath, ComparisonSource.GetNodePathSegment(node)); - sut.Path.ShouldBe(expectedPath); - } + var node = ToNodeList(sourceMarkup)[nodeIndex]; + + var sut = new ComparisonSource(node, ComparisonSourceType.Control); + + sut.Path.ShouldBe(expectedPath); + } + + [Fact(DisplayName = "The parent path is calculated correctly when not provided")] + public void Test006() + { + var nodes = ToNodeList("

txt
text

"); + var textNode = nodes[0].ChildNodes[2].FirstChild; + + var sut = new ComparisonSource(textNode, ComparisonSourceType.Control); + + sut.Path.ShouldBe("p(0) > i(2) > #text(0)"); + } + + [Fact(DisplayName = "Source uses parent path if provided to construct own path")] + public void Test007() + { + var node = ToNode("

"); + var parentPath = "SOME > PAHT"; + + var sut = new ComparisonSource(node, 0, parentPath, ComparisonSourceType.Control); + + var expectedPath = ComparisonSource.CombinePath(parentPath, ComparisonSource.GetNodePathSegment(node)); + sut.Path.ShouldBe(expectedPath); } } diff --git a/src/AngleSharp.Diffing.Tests/Core/DiffingEngineTestBase.cs b/src/AngleSharp.Diffing.Tests/Core/DiffingEngineTestBase.cs index 6af1904..901b004 100644 --- a/src/AngleSharp.Diffing.Tests/Core/DiffingEngineTestBase.cs +++ b/src/AngleSharp.Diffing.Tests/Core/DiffingEngineTestBase.cs @@ -1,78 +1,74 @@ -using System; -using System.Collections.Generic; +namespace AngleSharp.Diffing.Core; -namespace AngleSharp.Diffing.Core +public abstract class DiffingEngineTestBase : DiffingTestBase { - public abstract class DiffingEngineTestBase : DiffingTestBase + public DiffingEngineTestBase(DiffingTestFixture fixture) : base(fixture) { - public DiffingEngineTestBase(DiffingTestFixture fixture) : base(fixture) - { - } + } - protected static HtmlDiffer CreateHtmlDiffer( - Func>? nodeMatcher = null, - Func>? attrMatcher = null, - Func? nodeFilter = null, - Func? attrFilter = null, - Func? nodeComparer = null, - Func? attrComparer = null + protected static HtmlDiffer CreateHtmlDiffer( + Func>? nodeMatcher = null, + Func>? attrMatcher = null, + Func? nodeFilter = null, + Func? attrFilter = null, + Func? nodeComparer = null, + Func? attrComparer = null + ) + { + return new HtmlDiffer( + new MockDiffingStrategy( + nodeFilter, attrFilter, + nodeMatcher, attrMatcher, + nodeComparer, attrComparer ) - { - return new HtmlDiffer( - new MockDiffingStrategy( - nodeFilter, attrFilter, - nodeMatcher, attrMatcher, - nodeComparer, attrComparer - ) - ); - } + ); + } - private class MockDiffingStrategy : IDiffingStrategy - { - private readonly Func? _nodeFilter; - private readonly Func? _attrFilter; - private readonly Func>? _nodeMatcher; - private readonly Func>? _attrMatcher; - private readonly Func? _nodeCompare; - private readonly Func? _attrCompare; + private class MockDiffingStrategy : IDiffingStrategy + { + private readonly Func? _nodeFilter; + private readonly Func? _attrFilter; + private readonly Func>? _nodeMatcher; + private readonly Func>? _attrMatcher; + private readonly Func? _nodeCompare; + private readonly Func? _attrCompare; - public MockDiffingStrategy( - Func? nodeFilter = null, - Func? attrFilter = null, - Func>? nodeMatcher = null, - Func>? attrMatcher = null, - Func? nodeCompare = null, - Func? attrCompare = null) - { - _nodeFilter = nodeFilter; - _attrFilter = attrFilter; - _nodeMatcher = nodeMatcher; - _attrMatcher = attrMatcher; - _nodeCompare = nodeCompare; - _attrCompare = attrCompare; - } + public MockDiffingStrategy( + Func? nodeFilter = null, + Func? attrFilter = null, + Func>? nodeMatcher = null, + Func>? attrMatcher = null, + Func? nodeCompare = null, + Func? attrCompare = null) + { + _nodeFilter = nodeFilter; + _attrFilter = attrFilter; + _nodeMatcher = nodeMatcher; + _attrMatcher = attrMatcher; + _nodeCompare = nodeCompare; + _attrCompare = attrCompare; + } - public FilterDecision Filter(in AttributeComparisonSource attributeComparisonSource) - => _attrFilter!(attributeComparisonSource); + public FilterDecision Filter(in AttributeComparisonSource attributeComparisonSource) + => _attrFilter!(attributeComparisonSource); - public FilterDecision Filter(in ComparisonSource comparisonSource) - => _nodeFilter!(comparisonSource); + public FilterDecision Filter(in ComparisonSource comparisonSource) + => _nodeFilter!(comparisonSource); - public IEnumerable Match( - IDiffContext context, - SourceCollection controlNodes, - SourceCollection testNodes) => _nodeMatcher!(context, controlNodes, testNodes); + public IEnumerable Match( + IDiffContext context, + SourceCollection controlNodes, + SourceCollection testNodes) => _nodeMatcher!(context, controlNodes, testNodes); - public IEnumerable Match( - IDiffContext context, - SourceMap controlAttributes, - SourceMap testAttributes) => _attrMatcher!(context, controlAttributes, testAttributes); + public IEnumerable Match( + IDiffContext context, + SourceMap controlAttributes, + SourceMap testAttributes) => _attrMatcher!(context, controlAttributes, testAttributes); - public CompareResult Compare(in Comparison comparison) - => _nodeCompare!(comparison); + public CompareResult Compare(in Comparison comparison) + => _nodeCompare!(comparison); - public CompareResult Compare(in AttributeComparison comparison) - => _attrCompare!(comparison); - } + public CompareResult Compare(in AttributeComparison comparison) + => _attrCompare!(comparison); } } \ No newline at end of file diff --git a/src/AngleSharp.Diffing.Tests/Core/HtmlDifferenceEngineTest.cs b/src/AngleSharp.Diffing.Tests/Core/HtmlDifferenceEngineTest.cs index 6068afb..6fc8cc6 100644 --- a/src/AngleSharp.Diffing.Tests/Core/HtmlDifferenceEngineTest.cs +++ b/src/AngleSharp.Diffing.Tests/Core/HtmlDifferenceEngineTest.cs @@ -1,466 +1,456 @@ -using System; -using System.Collections.Generic; -using System.Linq; - using AngleSharp.Diffing.Strategies.NodeStrategies; -using AngleSharp.Dom; - -using Shouldly; -using Xunit; +namespace AngleSharp.Diffing.Core; -namespace AngleSharp.Diffing.Core +public class HtmlDifferenceEngineTest : DiffingEngineTestBase { - public class HtmlDifferenceEngineTest : DiffingEngineTestBase + public HtmlDifferenceEngineTest(DiffingTestFixture fixture) : base(fixture) { - public HtmlDifferenceEngineTest(DiffingTestFixture fixture) : base(fixture) - { - } + } - [Fact(DisplayName = "Unmatched nodes in control/test are returned as missing/unexpected diffs")] - public void UnmatchedNodesBecomesMissingUnexpectedDiffs() - { - var sut = CreateHtmlDiffer(nodeMatcher: NoneNodeMatcher, nodeFilter: NoneNodeFilter); + [Fact(DisplayName = "Unmatched nodes in control/test are returned as missing/unexpected diffs")] + public void UnmatchedNodesBecomesMissingUnexpectedDiffs() + { + var sut = CreateHtmlDiffer(nodeMatcher: NoneNodeMatcher, nodeFilter: NoneNodeFilter); + + var results = sut.Compare("

text", "

text") + .ToList(); + + results.Count.ShouldBe(6); + results[0].ShouldSatisfyAllConditions( + diff => diff.Result.ShouldBe(DiffResult.Missing), + diff => diff.Target.ShouldBe(DiffTarget.Element) + ); + results[1].ShouldSatisfyAllConditions( + diff => diff.Result.ShouldBe(DiffResult.Missing), + diff => diff.Target.ShouldBe(DiffTarget.Comment) + ); + results[2].ShouldSatisfyAllConditions( + diff => diff.Result.ShouldBe(DiffResult.Missing), + diff => diff.Target.ShouldBe(DiffTarget.Text) + ); + results[3].ShouldSatisfyAllConditions( + diff => diff.Result.ShouldBe(DiffResult.Unexpected), + diff => diff.Target.ShouldBe(DiffTarget.Element) + ); + results[4].ShouldSatisfyAllConditions( + diff => diff.Result.ShouldBe(DiffResult.Unexpected), + diff => diff.Target.ShouldBe(DiffTarget.Comment) + ); + results[5].ShouldSatisfyAllConditions( + diff => diff.Result.ShouldBe(DiffResult.Unexpected), + diff => diff.Target.ShouldBe(DiffTarget.Text) + ); + } - var results = sut.Compare("

text", "

text") - .ToList(); + [Theory(DisplayName = "When partial match of nodes in control/test, remaining unmatched are returned as missing/unexpected diffs")] + [InlineData(0)] + [InlineData(1)] + public void AnyUnmatchedNodesBecomesMissingUnexpectedDiffs(int matchIndex) + { + var nodes = ToNodeList("

"); + var sut = CreateHtmlDiffer( + nodeMatcher: SpecificIndexNodeMatcher(matchIndex), + nodeFilter: NoneNodeFilter, + nodeComparer: SameResultNodeComparer); - results.Count.ShouldBe(6); - results[0].ShouldSatisfyAllConditions( - diff => diff.Result.ShouldBe(DiffResult.Missing), - diff => diff.Target.ShouldBe(DiffTarget.Element) - ); - results[1].ShouldSatisfyAllConditions( - diff => diff.Result.ShouldBe(DiffResult.Missing), - diff => diff.Target.ShouldBe(DiffTarget.Comment) - ); - results[2].ShouldSatisfyAllConditions( - diff => diff.Result.ShouldBe(DiffResult.Missing), - diff => diff.Target.ShouldBe(DiffTarget.Text) - ); - results[3].ShouldSatisfyAllConditions( - diff => diff.Result.ShouldBe(DiffResult.Unexpected), - diff => diff.Target.ShouldBe(DiffTarget.Element) - ); - results[4].ShouldSatisfyAllConditions( - diff => diff.Result.ShouldBe(DiffResult.Unexpected), - diff => diff.Target.ShouldBe(DiffTarget.Comment) - ); - results[5].ShouldSatisfyAllConditions( - diff => diff.Result.ShouldBe(DiffResult.Unexpected), - diff => diff.Target.ShouldBe(DiffTarget.Text) - ); - } + var results = sut.Compare(nodes, nodes).ToList(); - [Theory(DisplayName = "When partial match of nodes in control/test, remaining unmatched are returned as missing/unexpected diffs")] - [InlineData(0)] - [InlineData(1)] - public void AnyUnmatchedNodesBecomesMissingUnexpectedDiffs(int matchIndex) - { - var nodes = ToNodeList("

"); - var sut = CreateHtmlDiffer( - nodeMatcher: SpecificIndexNodeMatcher(matchIndex), - nodeFilter: NoneNodeFilter, - nodeComparer: SameResultNodeComparer); + results.Count.ShouldBe(2); + results[0].ShouldBeOfType().Control.Node.ShouldNotBe(nodes[matchIndex]); + results[1].ShouldBeOfType().Test.Node.ShouldNotBe(nodes[matchIndex]); + } - var results = sut.Compare(nodes, nodes).ToList(); + [Theory(DisplayName = "Filtered out nodes does not take part in comparison")] + [InlineData("

")] + [InlineData("

")] + [InlineData("

")] + public void FilteredOutNodesNotPartOfComparison(string html) + { + var nodes = ToNodeList(html); + var sut = CreateHtmlDiffer(nodeMatcher: NoneNodeMatcher, nodeFilter: RemoveCommentNodeFilter); - results.Count.ShouldBe(2); - results[0].ShouldBeOfType().Control.Node.ShouldNotBe(nodes[matchIndex]); - results[1].ShouldBeOfType().Test.Node.ShouldNotBe(nodes[matchIndex]); - } + var results = sut.Compare(nodes, nodes).ToList(); - [Theory(DisplayName = "Filtered out nodes does not take part in comparison")] - [InlineData("

")] - [InlineData("

")] - [InlineData("

")] - public void FilteredOutNodesNotPartOfComparison(string html) - { - var nodes = ToNodeList(html); - var sut = CreateHtmlDiffer(nodeMatcher: NoneNodeMatcher, nodeFilter: RemoveCommentNodeFilter); + results.ShouldNotContain(diff => diff.Target == DiffTarget.Comment); + } - var results = sut.Compare(nodes, nodes).ToList(); + [Fact(DisplayName = "Index in comparison sources are based of input node lists (before filtering)")] + public void IndexesAreBasedOnInputNodeLists() + { + var nodes = ToNodeList("

"); + var nodes2 = ToNodeList("

"); + var sut = CreateHtmlDiffer(nodeMatcher: NoneNodeMatcher, nodeFilter: RemoveCommentNodeFilter); - results.ShouldNotContain(diff => diff.Target == DiffTarget.Comment); - } + var results = sut.Compare(nodes, nodes).ToList(); - [Fact(DisplayName = "Index in comparison sources are based of input node lists (before filtering)")] - public void IndexesAreBasedOnInputNodeLists() - { - var nodes = ToNodeList("

"); - var nodes2 = ToNodeList("

"); - var sut = CreateHtmlDiffer(nodeMatcher: NoneNodeMatcher, nodeFilter: RemoveCommentNodeFilter); + results.Count.ShouldBe(4); + results[0].ShouldBeOfType().Control.Index.ShouldBe(0); + results[1].ShouldBeOfType().Control.Index.ShouldBe(2); + results[2].ShouldBeOfType().Test.Index.ShouldBe(0); + results[3].ShouldBeOfType().Test.Index.ShouldBe(2); + } - var results = sut.Compare(nodes, nodes).ToList(); + [Fact(DisplayName = "When matched control/test nodes are different, a diff is returned")] + public void WhenNodesAreDifferentADiffIsReturned() + { + var nodes = ToNodeList("

textnode"); + var sut = CreateHtmlDiffer( + nodeMatcher: OneToOneNodeListMatcher, + nodeFilter: NoneNodeFilter, + nodeComparer: DiffResultNodeComparer); + + var results = sut.Compare(nodes, nodes).ToList(); + + results.Count.ShouldBe(3); + results[0].ShouldBeOfType().ShouldSatisfyAllConditions( + diff => diff.Control.Node.NodeName.ShouldBe("P"), + diff => diff.Result.ShouldBe(DiffResult.Different), + diff => diff.Target.ShouldBe(DiffTarget.Element) + ); + results[1].ShouldBeOfType().ShouldSatisfyAllConditions( + diff => diff.Control.Node.NodeName.ShouldBe("#comment"), + diff => diff.Result.ShouldBe(DiffResult.Different), + diff => diff.Target.ShouldBe(DiffTarget.Comment) + ); + results[2].ShouldBeOfType().ShouldSatisfyAllConditions( + diff => diff.Control.Node.NodeName.ShouldBe("#text"), + diff => diff.Result.ShouldBe(DiffResult.Different), + diff => diff.Target.ShouldBe(DiffTarget.Text) + ); + } - results.Count.ShouldBe(4); - results[0].ShouldBeOfType().Control.Index.ShouldBe(0); - results[1].ShouldBeOfType().Control.Index.ShouldBe(2); - results[2].ShouldBeOfType().Test.Index.ShouldBe(0); - results[3].ShouldBeOfType().Test.Index.ShouldBe(2); - } + [Fact(DisplayName = "When matched control/test nodes are the same, no diffs are returned")] + public void WhenNodesAreSameNoDiffIsReturned() + { + var nodes = ToNodeList("

textnode"); + var sut = CreateHtmlDiffer( + nodeMatcher: OneToOneNodeListMatcher, + nodeFilter: NoneNodeFilter, + nodeComparer: SameResultNodeComparer); - [Fact(DisplayName = "When matched control/test nodes are different, a diff is returned")] - public void WhenNodesAreDifferentADiffIsReturned() - { - var nodes = ToNodeList("

textnode"); - var sut = CreateHtmlDiffer( - nodeMatcher: OneToOneNodeListMatcher, - nodeFilter: NoneNodeFilter, - nodeComparer: DiffResultNodeComparer); - - var results = sut.Compare(nodes, nodes).ToList(); - - results.Count.ShouldBe(3); - results[0].ShouldBeOfType().ShouldSatisfyAllConditions( - diff => diff.Control.Node.NodeName.ShouldBe("P"), - diff => diff.Result.ShouldBe(DiffResult.Different), - diff => diff.Target.ShouldBe(DiffTarget.Element) - ); - results[1].ShouldBeOfType().ShouldSatisfyAllConditions( - diff => diff.Control.Node.NodeName.ShouldBe("#comment"), - diff => diff.Result.ShouldBe(DiffResult.Different), - diff => diff.Target.ShouldBe(DiffTarget.Comment) - ); - results[2].ShouldBeOfType().ShouldSatisfyAllConditions( - diff => diff.Control.Node.NodeName.ShouldBe("#text"), - diff => diff.Result.ShouldBe(DiffResult.Different), - diff => diff.Target.ShouldBe(DiffTarget.Text) - ); - } + var results = sut.Compare(nodes, nodes).ToList(); - [Fact(DisplayName = "When matched control/test nodes are the same, no diffs are returned")] - public void WhenNodesAreSameNoDiffIsReturned() - { - var nodes = ToNodeList("

textnode"); - var sut = CreateHtmlDiffer( - nodeMatcher: OneToOneNodeListMatcher, - nodeFilter: NoneNodeFilter, - nodeComparer: SameResultNodeComparer); + results.ShouldBeEmpty(); + } - var results = sut.Compare(nodes, nodes).ToList(); + [Fact(DisplayName = "Unmatched attributes in control/test node are returned as missing/unexpected diffs")] + public void UnmatchedAttr() + { + var nodes = ToNodeList(@"

"); + var expectedElementSource = (IElement)nodes[0]; + var sut = CreateHtmlDiffer( + nodeMatcher: OneToOneNodeListMatcher, + nodeFilter: NoneNodeFilter, + nodeComparer: SameResultNodeComparer, + attrMatcher: NoneAttributeMatcher, + attrFilter: NoneAttrFilter, + attrComparer: SameResultAttrComparer); + + var results = sut.Compare(nodes, nodes).ToList(); + + results.Count.ShouldBe(2); + results[0].ShouldBeOfType().ShouldSatisfyAllConditions( + diff => diff.Result.ShouldBe(DiffResult.Missing), + diff => diff.Target.ShouldBe(DiffTarget.Attribute), + diff => diff.Control.Attribute.Name.ShouldBe("id"), + diff => diff.Control.ElementSource.Node.ShouldBe(expectedElementSource) + ); + results[1].ShouldBeOfType().ShouldSatisfyAllConditions( + diff => diff.Result.ShouldBe(DiffResult.Unexpected), + diff => diff.Target.ShouldBe(DiffTarget.Attribute), + diff => diff.Test.Attribute.Name.ShouldBe("id"), + diff => diff.Test.ElementSource.Node.ShouldBe(expectedElementSource) + ); + } - results.ShouldBeEmpty(); - } + [Theory(DisplayName = "When partial match of attributes in control/test node, remaining unmatched are returned as missing/unexpected diffs")] + [InlineData("id")] + [InlineData("lang")] + [InlineData("custom")] + public void PartialUnmatchedAttrs(string matchedAttr) + { + var nodes = ToNodeList(@"

"); + var sut = CreateHtmlDiffer( + nodeMatcher: OneToOneNodeListMatcher, + nodeFilter: NoneNodeFilter, + nodeComparer: SameResultNodeComparer, + attrMatcher: SpecificAttributeMatcher(matchedAttr), + attrFilter: NoneAttrFilter, + attrComparer: SameResultAttrComparer); + + var results = sut.Compare(nodes, nodes).ToList(); + + results.Count.ShouldBe(4); + results[0].ShouldBeOfType().Control.Attribute.Name.ShouldNotBe(matchedAttr); + results[1].ShouldBeOfType().Control.Attribute.Name.ShouldNotBe(matchedAttr); + results[2].ShouldBeOfType().Test.Attribute.Name.ShouldNotBe(matchedAttr); + results[3].ShouldBeOfType().Test.Attribute.Name.ShouldNotBe(matchedAttr); + } - [Fact(DisplayName = "Unmatched attributes in control/test node are returned as missing/unexpected diffs")] - public void UnmatchedAttr() - { - var nodes = ToNodeList(@"

"); - var expectedElementSource = (IElement)nodes[0]; - var sut = CreateHtmlDiffer( - nodeMatcher: OneToOneNodeListMatcher, - nodeFilter: NoneNodeFilter, - nodeComparer: SameResultNodeComparer, - attrMatcher: NoneAttributeMatcher, - attrFilter: NoneAttrFilter, - attrComparer: SameResultAttrComparer); - - var results = sut.Compare(nodes, nodes).ToList(); - - results.Count.ShouldBe(2); - results[0].ShouldBeOfType().ShouldSatisfyAllConditions( - diff => diff.Result.ShouldBe(DiffResult.Missing), - diff => diff.Target.ShouldBe(DiffTarget.Attribute), - diff => diff.Control.Attribute.Name.ShouldBe("id"), - diff => diff.Control.ElementSource.Node.ShouldBe(expectedElementSource) - ); - results[1].ShouldBeOfType().ShouldSatisfyAllConditions( - diff => diff.Result.ShouldBe(DiffResult.Unexpected), - diff => diff.Target.ShouldBe(DiffTarget.Attribute), - diff => diff.Test.Attribute.Name.ShouldBe("id"), - diff => diff.Test.ElementSource.Node.ShouldBe(expectedElementSource) - ); - } + [Theory(DisplayName = "Filtered out attributes does not take part in comparison")] + [InlineData("id")] + [InlineData("lang")] + [InlineData("custom")] + public void FilteredAttrNotPartOfComparison(string filterOutAttrName) + { + var nodes = ToNodeList(@"

"); + + var sut = CreateHtmlDiffer( + nodeMatcher: OneToOneNodeListMatcher, + nodeFilter: NoneNodeFilter, + nodeComparer: SameResultNodeComparer, + attrMatcher: NoneAttributeMatcher, + attrFilter: SpecificAttrFilter(filterOutAttrName), + attrComparer: SameResultAttrComparer); + + var results = sut.Compare(nodes, nodes).ToList(); + + results.Count.ShouldBe(4); + results[0].ShouldBeOfType().Control.Attribute.Name.ShouldNotBe(filterOutAttrName); + results[1].ShouldBeOfType().Control.Attribute.Name.ShouldNotBe(filterOutAttrName); + results[2].ShouldBeOfType().Test.Attribute.Name.ShouldNotBe(filterOutAttrName); + results[3].ShouldBeOfType().Test.Attribute.Name.ShouldNotBe(filterOutAttrName); + } - [Theory(DisplayName = "When partial match of attributes in control/test node, remaining unmatched are returned as missing/unexpected diffs")] - [InlineData("id")] - [InlineData("lang")] - [InlineData("custom")] - public void PartialUnmatchedAttrs(string matchedAttr) - { - var nodes = ToNodeList(@"

"); - var sut = CreateHtmlDiffer( - nodeMatcher: OneToOneNodeListMatcher, - nodeFilter: NoneNodeFilter, - nodeComparer: SameResultNodeComparer, - attrMatcher: SpecificAttributeMatcher(matchedAttr), - attrFilter: NoneAttrFilter, - attrComparer: SameResultAttrComparer); - - var results = sut.Compare(nodes, nodes).ToList(); - - results.Count.ShouldBe(4); - results[0].ShouldBeOfType().Control.Attribute.Name.ShouldNotBe(matchedAttr); - results[1].ShouldBeOfType().Control.Attribute.Name.ShouldNotBe(matchedAttr); - results[2].ShouldBeOfType().Test.Attribute.Name.ShouldNotBe(matchedAttr); - results[3].ShouldBeOfType().Test.Attribute.Name.ShouldNotBe(matchedAttr); - } + [Fact(DisplayName = "When matched control/test attributes are different, a diff is returned")] + public void WhenMatchedAttrsAreDiffAttrDiffIsReturned() + { + var nodes = ToNodeList(@"

"); + + var sut = CreateHtmlDiffer( + nodeMatcher: OneToOneNodeListMatcher, + nodeFilter: NoneNodeFilter, + nodeComparer: SameResultNodeComparer, + attrMatcher: AttributeNameMatcher, + attrFilter: NoneAttrFilter, + attrComparer: DiffResultAttrComparer); + + var results = sut.Compare(nodes, nodes).ToList(); + + results.Count.ShouldBe(1); + results[0].ShouldBeOfType().ShouldSatisfyAllConditions( + diff => diff.Control.Attribute.Name.ShouldBe("id"), + diff => diff.Test.Attribute.Name.ShouldBe("id"), + diff => diff.Result.ShouldBe(DiffResult.Different), + diff => diff.Target.ShouldBe(DiffTarget.Attribute) + ); + } - [Theory(DisplayName = "Filtered out attributes does not take part in comparison")] - [InlineData("id")] - [InlineData("lang")] - [InlineData("custom")] - public void FilteredAttrNotPartOfComparison(string filterOutAttrName) - { - var nodes = ToNodeList(@"

"); - - var sut = CreateHtmlDiffer( - nodeMatcher: OneToOneNodeListMatcher, - nodeFilter: NoneNodeFilter, - nodeComparer: SameResultNodeComparer, - attrMatcher: NoneAttributeMatcher, - attrFilter: SpecificAttrFilter(filterOutAttrName), - attrComparer: SameResultAttrComparer); - - var results = sut.Compare(nodes, nodes).ToList(); - - results.Count.ShouldBe(4); - results[0].ShouldBeOfType().Control.Attribute.Name.ShouldNotBe(filterOutAttrName); - results[1].ShouldBeOfType().Control.Attribute.Name.ShouldNotBe(filterOutAttrName); - results[2].ShouldBeOfType().Test.Attribute.Name.ShouldNotBe(filterOutAttrName); - results[3].ShouldBeOfType().Test.Attribute.Name.ShouldNotBe(filterOutAttrName); - } + [Fact(DisplayName = "When matched control/test attributes are the same, no diffs are returned")] + public void WhenMatchedAttrsAreSameNoDiffIsReturned() + { + var nodes = ToNodeList(@"

"); - [Fact(DisplayName = "When matched control/test attributes are different, a diff is returned")] - public void WhenMatchedAttrsAreDiffAttrDiffIsReturned() - { - var nodes = ToNodeList(@"

"); - - var sut = CreateHtmlDiffer( - nodeMatcher: OneToOneNodeListMatcher, - nodeFilter: NoneNodeFilter, - nodeComparer: SameResultNodeComparer, - attrMatcher: AttributeNameMatcher, - attrFilter: NoneAttrFilter, - attrComparer: DiffResultAttrComparer); - - var results = sut.Compare(nodes, nodes).ToList(); - - results.Count.ShouldBe(1); - results[0].ShouldBeOfType().ShouldSatisfyAllConditions( - diff => diff.Control.Attribute.Name.ShouldBe("id"), - diff => diff.Test.Attribute.Name.ShouldBe("id"), - diff => diff.Result.ShouldBe(DiffResult.Different), - diff => diff.Target.ShouldBe(DiffTarget.Attribute) - ); - } + var sut = CreateHtmlDiffer( + nodeMatcher: OneToOneNodeListMatcher, + nodeFilter: NoneNodeFilter, + nodeComparer: SameResultNodeComparer, + attrMatcher: AttributeNameMatcher, + attrFilter: NoneAttrFilter, + attrComparer: SameResultAttrComparer); - [Fact(DisplayName = "When matched control/test attributes are the same, no diffs are returned")] - public void WhenMatchedAttrsAreSameNoDiffIsReturned() - { - var nodes = ToNodeList(@"

"); + var results = sut.Compare(nodes, nodes); - var sut = CreateHtmlDiffer( - nodeMatcher: OneToOneNodeListMatcher, - nodeFilter: NoneNodeFilter, - nodeComparer: SameResultNodeComparer, - attrMatcher: AttributeNameMatcher, - attrFilter: NoneAttrFilter, - attrComparer: SameResultAttrComparer); + results.ShouldBeEmpty(); + } - var results = sut.Compare(nodes, nodes); + [Fact(DisplayName = "If both the control or test node in a comparison has child nodes, these nodelists are compared")] + public void WhenBothTestAndControlHaveChildNodesTheseAreCompared() + { + var nodes = ToNodeList(@"

hello world

"); - results.ShouldBeEmpty(); - } + var sut = CreateHtmlDiffer( + nodeMatcher: OneToOneNodeListMatcher, + nodeFilter: NoneNodeFilter, + nodeComparer: DiffResultNodeComparer); - [Fact(DisplayName = "If both the control or test node in a comparison has child nodes, these nodelists are compared")] - public void WhenBothTestAndControlHaveChildNodesTheseAreCompared() - { - var nodes = ToNodeList(@"

hello world

"); + var results = sut.Compare(nodes, nodes).ToList(); - var sut = CreateHtmlDiffer( - nodeMatcher: OneToOneNodeListMatcher, - nodeFilter: NoneNodeFilter, - nodeComparer: DiffResultNodeComparer); + results.Count.ShouldBe(5); + results[0].ShouldBeOfType().Control.Node.NodeName.ShouldBe("MAIN"); + results[1].ShouldBeOfType().Control.Node.NodeName.ShouldBe("H1"); + results[2].ShouldBeOfType().Control.Node.NodeValue.ShouldBe("foobar"); + results[3].ShouldBeOfType().Control.Node.NodeName.ShouldBe("P"); + results[4].ShouldBeOfType().Control.Node.NodeName.ShouldBe("#text"); + } - var results = sut.Compare(nodes, nodes).ToList(); + [Theory(DisplayName = "When only one of the control or test node in a comparison has child nodes, a missing/unexpected diff is returned")] + [InlineData("

", "

", typeof(MissingNodeDiff))] + [InlineData("

", "

", typeof(UnexpectedNodeDiff))] + public void OnlyOnePartHasChildNodes(string control, string test, Type expectedDiffType) + { + var sut = CreateHtmlDiffer( + nodeMatcher: OneToOneNodeListMatcher, + nodeFilter: NoneNodeFilter, + nodeComparer: DiffResultNodeComparer); - results.Count.ShouldBe(5); - results[0].ShouldBeOfType().Control.Node.NodeName.ShouldBe("MAIN"); - results[1].ShouldBeOfType().Control.Node.NodeName.ShouldBe("H1"); - results[2].ShouldBeOfType().Control.Node.NodeValue.ShouldBe("foobar"); - results[3].ShouldBeOfType().Control.Node.NodeName.ShouldBe("P"); - results[4].ShouldBeOfType().Control.Node.NodeName.ShouldBe("#text"); - } + var results = sut.Compare(ToNodeList(control), ToNodeList(test)).ToList(); - [Theory(DisplayName = "When only one of the control or test node in a comparison has child nodes, a missing/unexpected diff is returned")] - [InlineData("

", "

", typeof(MissingNodeDiff))] - [InlineData("

", "

", typeof(UnexpectedNodeDiff))] - public void OnlyOnePartHasChildNodes(string control, string test, Type expectedDiffType) - { - var sut = CreateHtmlDiffer( - nodeMatcher: OneToOneNodeListMatcher, - nodeFilter: NoneNodeFilter, - nodeComparer: DiffResultNodeComparer); + results.Count.ShouldBe(2); + results[0].ShouldBeOfType(); + results[1].ShouldBeOfType(expectedDiffType); + } - var results = sut.Compare(ToNodeList(control), ToNodeList(test)).ToList(); + [Fact(DisplayName = "Comparison sources have their type set correctly")] + public void ComparisonSourcesHaveCorrectType() + { + var nodes = ToNodeList(@"

"); - results.Count.ShouldBe(2); - results[0].ShouldBeOfType(); - results[1].ShouldBeOfType(expectedDiffType); - } + var sut = CreateHtmlDiffer( + nodeMatcher: OneToOneNodeListMatcher, + nodeFilter: NoneNodeFilter, + nodeComparer: DiffResultNodeComparer, + attrMatcher: AttributeNameMatcher, + attrFilter: NoneAttrFilter, + attrComparer: DiffResultAttrComparer); - [Fact(DisplayName = "Comparison sources have their type set correctly")] - public void ComparisonSourcesHaveCorrectType() - { - var nodes = ToNodeList(@"

"); + var results = sut.Compare(nodes, nodes).ToList(); - var sut = CreateHtmlDiffer( - nodeMatcher: OneToOneNodeListMatcher, - nodeFilter: NoneNodeFilter, - nodeComparer: DiffResultNodeComparer, - attrMatcher: AttributeNameMatcher, - attrFilter: NoneAttrFilter, - attrComparer: DiffResultAttrComparer); + results.Count.ShouldBe(2); - var results = sut.Compare(nodes, nodes).ToList(); + results[0].ShouldBeOfType().Control.SourceType.ShouldBe(ComparisonSourceType.Control); + results[0].ShouldBeOfType().Test.SourceType.ShouldBe(ComparisonSourceType.Test); + results[1].ShouldBeOfType().Control.SourceType.ShouldBe(ComparisonSourceType.Control); + results[1].ShouldBeOfType().Test.SourceType.ShouldBe(ComparisonSourceType.Test); + } - results.Count.ShouldBe(2); + [Fact(DisplayName = "When comparer returns Skip from an element comparison, none of the attributes or child nodes are compared")] + public void Test1() + { + var sut = CreateHtmlDiffer( + nodeMatcher: OneToOneNodeListMatcher, + nodeFilter: NoneNodeFilter, + nodeComparer: c => c.Control.Node.NodeName == "P" ? CompareResult.Skip : throw new Exception("NODE COMPARER SHOULD NOT BE CALLED ON CHILD NODES"), + attrMatcher: (c, x, y) => throw new Exception("ATTR MATCHER SHOULD NOT BE CALLED"), + attrFilter: _ => throw new Exception("ATTR FILTER SHOULD NOT BE CALLED"), + attrComparer: _ => throw new Exception("ATTR COMPARER SHOULD NOT BE CALLED")); - results[0].ShouldBeOfType().Control.SourceType.ShouldBe(ComparisonSourceType.Control); - results[0].ShouldBeOfType().Test.SourceType.ShouldBe(ComparisonSourceType.Test); - results[1].ShouldBeOfType().Control.SourceType.ShouldBe(ComparisonSourceType.Control); - results[1].ShouldBeOfType().Test.SourceType.ShouldBe(ComparisonSourceType.Test); - } + var results = sut.Compare(ToNodeList(@"

foo

"), ToNodeList(@"

baz

")); - [Fact(DisplayName = "When comparer returns Skip from an element comparison, none of the attributes or child nodes are compared")] - public void Test1() - { - var sut = CreateHtmlDiffer( - nodeMatcher: OneToOneNodeListMatcher, - nodeFilter: NoneNodeFilter, - nodeComparer: c => c.Control.Node.NodeName == "P" ? CompareResult.Skip : throw new Exception("NODE COMPARER SHOULD NOT BE CALLED ON CHILD NODES"), - attrMatcher: (c, x, y) => throw new Exception("ATTR MATCHER SHOULD NOT BE CALLED"), - attrFilter: _ => throw new Exception("ATTR FILTER SHOULD NOT BE CALLED"), - attrComparer: _ => throw new Exception("ATTR COMPARER SHOULD NOT BE CALLED")); + results.ShouldBeEmpty(); + } - var results = sut.Compare(ToNodeList(@"

foo

"), ToNodeList(@"

baz

")); + [Fact(DisplayName = "When comparer returns Skip from an attribute comparison, no diffs are returned")] + public void Test2() + { + var sut = CreateHtmlDiffer( + nodeMatcher: OneToOneNodeListMatcher, + nodeFilter: NoneNodeFilter, + nodeComparer: SameResultNodeComparer, + attrMatcher: AttributeNameMatcher, + attrFilter: NoneAttrFilter, + attrComparer: c => c.Control.Attribute.Name == "id" ? CompareResult.Skip : CompareResult.Different + ); - results.ShouldBeEmpty(); - } + var results = sut.Compare(ToNodeList(@"

"), ToNodeList(@"

")); - [Fact(DisplayName = "When comparer returns Skip from an attribute comparison, no diffs are returned")] - public void Test2() - { - var sut = CreateHtmlDiffer( - nodeMatcher: OneToOneNodeListMatcher, - nodeFilter: NoneNodeFilter, - nodeComparer: SameResultNodeComparer, - attrMatcher: AttributeNameMatcher, - attrFilter: NoneAttrFilter, - attrComparer: c => c.Control.Attribute.Name == "id" ? CompareResult.Skip : CompareResult.Different - ); - - var results = sut.Compare(ToNodeList(@"

"), ToNodeList(@"

")); - - results.ShouldBeEmpty(); - } + results.ShouldBeEmpty(); + } - [Theory(DisplayName = "When comparer returns SkipChildren flag from an element comparison, child nodes are not compared")] - [InlineData(CompareResult.Same | CompareResult.SkipChildren)] - [InlineData(CompareResult.Skip | CompareResult.SkipChildren)] - public void Test3(CompareResult compareResult) - { - var sut = CreateHtmlDiffer( - nodeMatcher: OneToOneNodeListMatcher, - nodeFilter: NoneNodeFilter, - nodeComparer: c => c.Control.Node.NodeName == "P" ? compareResult : throw new Exception("NODE COMPARER SHOULD NOT BE CALLED ON CHILD NODES"), - attrMatcher: AttributeNameMatcher, - attrFilter: NoneAttrFilter, - attrComparer: SameResultAttrComparer - ); - - var results = sut.Compare(ToNodeList(@"

foo

"), ToNodeList(@"

baz

")); - - results.ShouldBeEmpty(); - } + [Theory(DisplayName = "When comparer returns SkipChildren flag from an element comparison, child nodes are not compared")] + [InlineData(CompareResult.Same | CompareResult.SkipChildren)] + [InlineData(CompareResult.Skip | CompareResult.SkipChildren)] + public void Test3(CompareResult compareResult) + { + var sut = CreateHtmlDiffer( + nodeMatcher: OneToOneNodeListMatcher, + nodeFilter: NoneNodeFilter, + nodeComparer: c => c.Control.Node.NodeName == "P" ? compareResult : throw new Exception("NODE COMPARER SHOULD NOT BE CALLED ON CHILD NODES"), + attrMatcher: AttributeNameMatcher, + attrFilter: NoneAttrFilter, + attrComparer: SameResultAttrComparer + ); - [Theory(DisplayName = "When comparer returns SkipAttributes flag from an element comparison, attributes are not compared")] - [InlineData(CompareResult.Same | CompareResult.SkipAttributes)] - [InlineData(CompareResult.Skip | CompareResult.SkipAttributes)] - public void Test4(CompareResult compareResult) - { - var sut = CreateHtmlDiffer( - nodeMatcher: OneToOneNodeListMatcher, - nodeFilter: NoneNodeFilter, - nodeComparer: c => compareResult, - attrMatcher: AttributeNameMatcher, - attrFilter: NoneAttrFilter, - attrComparer: SameResultAttrComparer - ); - - var results = sut.Compare(ToNodeList(@"

"), ToNodeList(@"

")); - - results.ShouldBeEmpty(); - } + var results = sut.Compare(ToNodeList(@"

foo

"), ToNodeList(@"

baz

")); - #region NodeFilters - private static FilterDecision NoneNodeFilter(ComparisonSource source) => FilterDecision.Keep; - private static FilterDecision RemoveCommentNodeFilter(ComparisonSource source) => source.Node.NodeType == NodeType.Comment ? FilterDecision.Exclude : FilterDecision.Keep; - #endregion + results.ShouldBeEmpty(); + } - #region NodeMatchers - private static IEnumerable NoneNodeMatcher(IDiffContext ctx, SourceCollection controlNodes, SourceCollection testNodes) - => Array.Empty(); + [Theory(DisplayName = "When comparer returns SkipAttributes flag from an element comparison, attributes are not compared")] + [InlineData(CompareResult.Same | CompareResult.SkipAttributes)] + [InlineData(CompareResult.Skip | CompareResult.SkipAttributes)] + public void Test4(CompareResult compareResult) + { + var sut = CreateHtmlDiffer( + nodeMatcher: OneToOneNodeListMatcher, + nodeFilter: NoneNodeFilter, + nodeComparer: c => compareResult, + attrMatcher: AttributeNameMatcher, + attrFilter: NoneAttrFilter, + attrComparer: SameResultAttrComparer + ); - private static Func> SpecificIndexNodeMatcher(int index) - => (ctx, controlNodes, testNodes) => - { - return new List { new Comparison(controlNodes[index], testNodes[index]) }; - }; + var results = sut.Compare(ToNodeList(@"

"), ToNodeList(@"

")); - private static IEnumerable OneToOneNodeListMatcher( - IDiffContext context, - SourceCollection controlNodes, - SourceCollection testNodes) => OneToOneNodeMatcher.Match(context, controlNodes, testNodes); + results.ShouldBeEmpty(); + } + + #region NodeFilters + private static FilterDecision NoneNodeFilter(ComparisonSource source) => FilterDecision.Keep; + private static FilterDecision RemoveCommentNodeFilter(ComparisonSource source) => source.Node.NodeType == NodeType.Comment ? FilterDecision.Exclude : FilterDecision.Keep; + #endregion - #endregion + #region NodeMatchers + private static IEnumerable NoneNodeMatcher(IDiffContext ctx, SourceCollection controlNodes, SourceCollection testNodes) + => Array.Empty(); + + private static Func> SpecificIndexNodeMatcher(int index) + => (ctx, controlNodes, testNodes) => + { + return new List { new Comparison(controlNodes[index], testNodes[index]) }; + }; - #region NodeComparers - private static CompareResult SameResultNodeComparer(Comparison comparison) => CompareResult.Same; - private static CompareResult DiffResultNodeComparer(Comparison comparison) => CompareResult.Different; - #endregion + private static IEnumerable OneToOneNodeListMatcher( + IDiffContext context, + SourceCollection controlNodes, + SourceCollection testNodes) => OneToOneNodeMatcher.Match(context, controlNodes, testNodes); - #region AttributeMatchers - private static IReadOnlyList NoneAttributeMatcher( - IDiffContext context, - SourceMap controlAttributes, - SourceMap testAttributes) => Array.Empty(); + #endregion - private static Func> SpecificAttributeMatcher(string matchAttrName) + #region NodeComparers + private static CompareResult SameResultNodeComparer(Comparison comparison) => CompareResult.Same; + private static CompareResult DiffResultNodeComparer(Comparison comparison) => CompareResult.Different; + #endregion + + #region AttributeMatchers + private static IReadOnlyList NoneAttributeMatcher( + IDiffContext context, + SourceMap controlAttributes, + SourceMap testAttributes) => Array.Empty(); + + private static Func> SpecificAttributeMatcher(string matchAttrName) + { + return (ctx, ctrlAttrs, testAttrs) => new List { - return (ctx, ctrlAttrs, testAttrs) => new List - { - new AttributeComparison(ctrlAttrs[matchAttrName], testAttrs[matchAttrName] ) - }; - } + new AttributeComparison(ctrlAttrs[matchAttrName], testAttrs[matchAttrName] ) + }; + } - private static IEnumerable AttributeNameMatcher(IDiffContext context, SourceMap controlAttrs, SourceMap testAttrs) + private static IEnumerable AttributeNameMatcher(IDiffContext context, SourceMap controlAttrs, SourceMap testAttrs) + { + foreach (var ctrlAttrSrc in controlAttrs) { - foreach (var ctrlAttrSrc in controlAttrs) + if (testAttrs.Contains(ctrlAttrSrc.Attribute.Name)) { - if (testAttrs.Contains(ctrlAttrSrc.Attribute.Name)) - { - yield return new AttributeComparison(ctrlAttrSrc, testAttrs[ctrlAttrSrc.Attribute.Name]); - } + yield return new AttributeComparison(ctrlAttrSrc, testAttrs[ctrlAttrSrc.Attribute.Name]); } } + } - #endregion + #endregion - #region AttributeFilters + #region AttributeFilters - private static FilterDecision NoneAttrFilter(AttributeComparisonSource source) => FilterDecision.Keep; + private static FilterDecision NoneAttrFilter(AttributeComparisonSource source) => FilterDecision.Keep; - private static Func SpecificAttrFilter(string attrName) => - source => source.Attribute.Name == attrName ? FilterDecision.Exclude : FilterDecision.Keep; + private static Func SpecificAttrFilter(string attrName) => + source => source.Attribute.Name == attrName ? FilterDecision.Exclude : FilterDecision.Keep; - #endregion + #endregion - #region AttributeComparers - public static CompareResult SameResultAttrComparer(AttributeComparison comparison) => CompareResult.Same; - public static CompareResult DiffResultAttrComparer(AttributeComparison comparison) => CompareResult.Different; - #endregion - } + #region AttributeComparers + public static CompareResult SameResultAttrComparer(AttributeComparison comparison) => CompareResult.Same; + public static CompareResult DiffResultAttrComparer(AttributeComparison comparison) => CompareResult.Different; + #endregion } \ No newline at end of file diff --git a/src/AngleSharp.Diffing.Tests/Core/SourceCollectionTest.cs b/src/AngleSharp.Diffing.Tests/Core/SourceCollectionTest.cs index 2109c9a..45457dd 100644 --- a/src/AngleSharp.Diffing.Tests/Core/SourceCollectionTest.cs +++ b/src/AngleSharp.Diffing.Tests/Core/SourceCollectionTest.cs @@ -1,90 +1,82 @@ -using System; -using System.Linq; +namespace AngleSharp.Diffing.Core; -using Shouldly; +public class SourceCollectionTest : DiffingTestBase +{ + public SourceCollectionTest(DiffingTestFixture fixture) : base(fixture) + { + } -using Xunit; + [Theory(DisplayName = "Source type is correct saved in the collection")] + [InlineData(ComparisonSourceType.Control)] + [InlineData(ComparisonSourceType.Test)] + public void Test0(ComparisonSourceType sourceType) + { + var sut = new SourceCollection(sourceType, Array.Empty()); -namespace AngleSharp.Diffing.Core -{ - public class SourceCollectionTest : DiffingTestBase + sut.SourceType.ShouldBe(sourceType); + } + + [Fact(DisplayName = "When adding sources are added to the collection, they are accessible through the indexer")] + public void Test1() + { + var sut = ToNodeList("

").ToSourceCollection(ComparisonSourceType.Control); + + sut.Count.ShouldBe(2); + sut.First().ShouldSatisfyAllConditions( + (ComparisonSource cs) => cs.Index.ShouldBe(0), + (ComparisonSource cs) => cs.Node.NodeName.ShouldBe("P")); + sut.Last().ShouldSatisfyAllConditions( + (ComparisonSource cs) => cs.Index.ShouldBe(1), + (ComparisonSource cs) => cs.Node.NodeName.ShouldBe("SPAN")); + } + + [Fact(DisplayName = "When a source is marked as matched, it isnt included in output of GetUnmatched")] + public void Test2() + { + var sut = ToNodeList("

").ToSourceCollection(ComparisonSourceType.Control); + var first = sut.First(); + var last = sut.Last(); + + sut.MarkAsMatched(first); + + sut.GetUnmatched().Count().ShouldBe(1); + sut.GetUnmatched().First().ShouldBe(last); + sut.Count.ShouldBe(2); + } + + [Fact(DisplayName = "Collection throws if sources is not ordered source-index when enumerated")] + public void Test3() + { + var sources = ToNodeList("

      ") + .ToComparisonSourceList(ComparisonSourceType.Control) + .OrderBy(x => x.Node.NodeName); + + var cut = new SourceCollection(ComparisonSourceType.Control, sources); + + Should.Throw(() => cut.ToList()); + Should.Throw(() => cut.GetAllSources().ToList()); + } + + [Fact(DisplayName = "When an source is removed from the list, it does not add to the count nor is it returned when iterating")] + public void Test4() { - public SourceCollectionTest(DiffingTestFixture fixture) : base(fixture) - { - } - - [Theory(DisplayName = "Source type is correct saved in the collection")] - [InlineData(ComparisonSourceType.Control)] - [InlineData(ComparisonSourceType.Test)] - public void Test0(ComparisonSourceType sourceType) - { - var sut = new SourceCollection(sourceType, Array.Empty()); - - sut.SourceType.ShouldBe(sourceType); - } - - [Fact(DisplayName = "When adding sources are added to the collection, they are accessible through the indexer")] - public void Test1() - { - var sut = ToNodeList("

      ").ToSourceCollection(ComparisonSourceType.Control); - - sut.Count.ShouldBe(2); - sut.First().ShouldSatisfyAllConditions( - (ComparisonSource cs) => cs.Index.ShouldBe(0), - (ComparisonSource cs) => cs.Node.NodeName.ShouldBe("P")); - sut.Last().ShouldSatisfyAllConditions( - (ComparisonSource cs) => cs.Index.ShouldBe(1), - (ComparisonSource cs) => cs.Node.NodeName.ShouldBe("SPAN")); - } - - [Fact(DisplayName = "When a source is marked as matched, it isnt included in output of GetUnmatched")] - public void Test2() - { - var sut = ToNodeList("

      ").ToSourceCollection(ComparisonSourceType.Control); - var first = sut.First(); - var last = sut.Last(); - - sut.MarkAsMatched(first); - - sut.GetUnmatched().Count().ShouldBe(1); - sut.GetUnmatched().First().ShouldBe(last); - sut.Count.ShouldBe(2); - } - - [Fact(DisplayName = "Collection throws if sources is not ordered source-index when enumerated")] - public void Test3() - { - var sources = ToNodeList("

          ") - .ToComparisonSourceList(ComparisonSourceType.Control) - .OrderBy(x => x.Node.NodeName); - - var cut = new SourceCollection(ComparisonSourceType.Control, sources); - - Should.Throw(() => cut.ToList()); - Should.Throw(() => cut.GetAllSources().ToList()); - } - - [Fact(DisplayName = "When an source is removed from the list, it does not add to the count nor is it returned when iterating")] - public void Test4() - { - var sut = ToNodeList("

          ").ToSourceCollection(ComparisonSourceType.Control); - var first = sut.First(); - var last = sut.Last(); - - sut.Remove((in ComparisonSource x) => x == first ? FilterDecision.Exclude : FilterDecision.Keep); - - sut.Count.ShouldBe(1); - sut.First().ShouldBe(last); - } - - [Fact(DisplayName = "Marking removed source as matched throws")] - public void Test7() - { - var sut = ToNodeList("

          ").ToSourceCollection(ComparisonSourceType.Control); - var last = sut.Last(); - sut.Remove((in ComparisonSource x) => x == last ? FilterDecision.Exclude : FilterDecision.Keep); - - Should.Throw(() => sut.MarkAsMatched(last)); - } + var sut = ToNodeList("

          ").ToSourceCollection(ComparisonSourceType.Control); + var first = sut.First(); + var last = sut.Last(); + + sut.Remove((in ComparisonSource x) => x == first ? FilterDecision.Exclude : FilterDecision.Keep); + + sut.Count.ShouldBe(1); + sut.First().ShouldBe(last); + } + + [Fact(DisplayName = "Marking removed source as matched throws")] + public void Test7() + { + var sut = ToNodeList("

          ").ToSourceCollection(ComparisonSourceType.Control); + var last = sut.Last(); + sut.Remove((in ComparisonSource x) => x == last ? FilterDecision.Exclude : FilterDecision.Keep); + + Should.Throw(() => sut.MarkAsMatched(last)); } } diff --git a/src/AngleSharp.Diffing.Tests/Core/SourceMapTest.cs b/src/AngleSharp.Diffing.Tests/Core/SourceMapTest.cs index 4ad690c..e64d7c7 100644 --- a/src/AngleSharp.Diffing.Tests/Core/SourceMapTest.cs +++ b/src/AngleSharp.Diffing.Tests/Core/SourceMapTest.cs @@ -1,106 +1,98 @@ -using System; -using System.Linq; +namespace AngleSharp.Diffing.Core; -using Shouldly; +public class SourceMapTest : DiffingTestBase +{ + public SourceMapTest(DiffingTestFixture fixture) : base(fixture) + { + } -using Xunit; + [Fact(DisplayName = "When initialized with a non-element an exception is thrown")] + public void Test0() + { + var source = ToComparisonSource(@"textnode", ComparisonSourceType.Test); -namespace AngleSharp.Diffing.Core -{ - public class SourceMapTest : DiffingTestBase + Should.Throw(() => new SourceMap(source)); + } + + [Fact(DisplayName = "When initializing with an element source, its source type is used and its attributes are added at sources to the map")] + public void Test1() + { + var elementSource = ToComparisonSource(@"

          ", ComparisonSourceType.Test); + var sut = new SourceMap(elementSource); + + sut.SourceType.ShouldBe(ComparisonSourceType.Test); + sut.Count.ShouldBe(2); + sut["foo"].ShouldSatisfyAllConditions( + (cs) => cs.Attribute.Name.ShouldBe("foo"), + (cs) => cs.ElementSource.ShouldBe(elementSource) + ); + sut["baz"].ShouldSatisfyAllConditions( + (cs) => cs.Attribute.Name.ShouldBe("baz"), + (cs) => cs.ElementSource.ShouldBe(elementSource) + ); + } + + [Fact(DisplayName = "Accessing the indexer with a attr name that is not in the set throws")] + public void Test2() + { + var elementSource = ToComparisonSource(@"

          "); + var sut = new SourceMap(elementSource); + + Should.Throw(() => sut["foo"]); + } + + [Theory(DisplayName = "Contains returns true when map contains a source with the provided name, false otherwise")] + [InlineData(@"

          ", true)] + [InlineData(@"

          ", false)] + public void Tests3(string html, bool expectedResult) + { + var elementSource = ToComparisonSource(html); + var sut = new SourceMap(elementSource); + + sut.Contains("foo").ShouldBe(expectedResult); + } + + [Fact(DisplayName = "Sources can be removed from map by passing a predicate to the Remove method")] + public void Test4() { - public SourceMapTest(DiffingTestFixture fixture) : base(fixture) - { - } - - [Fact(DisplayName = "When initialized with a non-element an exception is thrown")] - public void Test0() - { - var source = ToComparisonSource(@"textnode", ComparisonSourceType.Test); - - Should.Throw(() => new SourceMap(source)); - } - - [Fact(DisplayName = "When initializing with an element source, its source type is used and its attributes are added at sources to the map")] - public void Test1() - { - var elementSource = ToComparisonSource(@"

          ", ComparisonSourceType.Test); - var sut = new SourceMap(elementSource); - - sut.SourceType.ShouldBe(ComparisonSourceType.Test); - sut.Count.ShouldBe(2); - sut["foo"].ShouldSatisfyAllConditions( - (cs) => cs.Attribute.Name.ShouldBe("foo"), - (cs) => cs.ElementSource.ShouldBe(elementSource) - ); - sut["baz"].ShouldSatisfyAllConditions( - (cs) => cs.Attribute.Name.ShouldBe("baz"), - (cs) => cs.ElementSource.ShouldBe(elementSource) - ); - } - - [Fact(DisplayName = "Accessing the indexer with a attr name that is not in the set throws")] - public void Test2() - { - var elementSource = ToComparisonSource(@"

          "); - var sut = new SourceMap(elementSource); - - Should.Throw(() => sut["foo"]); - } - - [Theory(DisplayName = "Contains returns true when map contains a source with the provided name, false otherwise")] - [InlineData(@"

          ", true)] - [InlineData(@"

          ", false)] - public void Tests3(string html, bool expectedResult) - { - var elementSource = ToComparisonSource(html); - var sut = new SourceMap(elementSource); - - sut.Contains("foo").ShouldBe(expectedResult); - } - - [Fact(DisplayName = "Sources can be removed from map by passing a predicate to the Remove method")] - public void Test4() - { - var elementSource = ToComparisonSource(@"

          "); - var sut = new SourceMap(elementSource); - - sut.Remove((in AttributeComparisonSource cs) => cs.Attribute.Name == "foo" ? FilterDecision.Exclude : FilterDecision.Keep); - - sut.Count.ShouldBe(1); - sut.Contains("foo").ShouldBeFalse(); - } - - [Fact(DisplayName = "When a source is marked as matched, it is not returned in GetUnmatched")] - public void Test5() - { - var elementSource = ToComparisonSource(@"

          "); - var sut = new SourceMap(elementSource); - var foo = sut["foo"]; - - sut.MarkAsMatched(foo); - - sut.GetUnmatched().ShouldNotContain(foo); - sut.GetUnmatched().Count().ShouldBe(1); - } - - [Fact(DisplayName = "When a source is marked as matched, IsUnmatched returns false")] - public void Test6() - { - var sut = ToSourceMap(@"

          "); - var foo = sut["foo"]; - - sut.MarkAsMatched(foo); - - sut.IsUnmatched("foo").ShouldBeFalse(); - } - - [Fact(DisplayName = "When a source is unmatched, IsUnmatched returns true")] - public void Test7() - { - var sut = ToSourceMap(@"

          "); - - sut.IsUnmatched("foo").ShouldBeTrue(); - } + var elementSource = ToComparisonSource(@"

          "); + var sut = new SourceMap(elementSource); + + sut.Remove((in AttributeComparisonSource cs) => cs.Attribute.Name == "foo" ? FilterDecision.Exclude : FilterDecision.Keep); + + sut.Count.ShouldBe(1); + sut.Contains("foo").ShouldBeFalse(); + } + + [Fact(DisplayName = "When a source is marked as matched, it is not returned in GetUnmatched")] + public void Test5() + { + var elementSource = ToComparisonSource(@"

          "); + var sut = new SourceMap(elementSource); + var foo = sut["foo"]; + + sut.MarkAsMatched(foo); + + sut.GetUnmatched().ShouldNotContain(foo); + sut.GetUnmatched().Count().ShouldBe(1); + } + + [Fact(DisplayName = "When a source is marked as matched, IsUnmatched returns false")] + public void Test6() + { + var sut = ToSourceMap(@"

          "); + var foo = sut["foo"]; + + sut.MarkAsMatched(foo); + + sut.IsUnmatched("foo").ShouldBeFalse(); + } + + [Fact(DisplayName = "When a source is unmatched, IsUnmatched returns true")] + public void Test7() + { + var sut = ToSourceMap(@"

          "); + + sut.IsUnmatched("foo").ShouldBeTrue(); } } diff --git a/src/AngleSharp.Diffing.Tests/DiffBuilderTest.cs b/src/AngleSharp.Diffing.Tests/DiffBuilderTest.cs index be8914f..9287f03 100644 --- a/src/AngleSharp.Diffing.Tests/DiffBuilderTest.cs +++ b/src/AngleSharp.Diffing.Tests/DiffBuilderTest.cs @@ -1,129 +1,119 @@ -using System; -using System.Linq; +namespace AngleSharp.Diffing; -using AngleSharp.Diffing.Core; -using Shouldly; +public class DiffBuilderTest +{ + [Fact(DisplayName = "Control and test html are set correctly")] + public void Test001() + { + var control = "

          control

          "; + var test = "

          test

          "; -using Xunit; + var sut = DiffBuilder + .Compare(control) + .WithTest(test); -namespace AngleSharp.Diffing -{ + sut.Control.ShouldBe(control); + sut.Test.ShouldBe(test); + } + + [Fact(DisplayName = "Builder throws if null is passed to control and test")] + public void Test002() + { + Should.Throw(() => DiffBuilder.Compare(null!)).ParamName.ShouldBe(nameof(DiffBuilder.Control)); + Should.Throw(() => DiffBuilder.Compare("").WithTest(null!)).ParamName.ShouldBe(nameof(DiffBuilder.Test)); + } + + [Fact(DisplayName = "Calling Build() with DefaultOptions() returns expected diffs")] + public void Test003() + { + var control = @"

          hello world

          "; + var test = @"

          world says hello

          "; + + var diffs = DiffBuilder + .Compare(control) + .WithTest(test) + .Build() + .ToList(); + + diffs.Count.ShouldBe(6); + diffs.SingleOrDefault(x => x is AttrDiff).ShouldNotBeNull(); + diffs.SingleOrDefault(x => x is MissingAttrDiff).ShouldNotBeNull(); + diffs.SingleOrDefault(x => x is UnexpectedAttrDiff).ShouldNotBeNull(); + diffs.SingleOrDefault(x => x is NodeDiff).ShouldNotBeNull(); + diffs.SingleOrDefault(x => x is MissingNodeDiff).ShouldNotBeNull(); + diffs.SingleOrDefault(x => x is UnexpectedNodeDiff).ShouldNotBeNull(); + } - public class DiffBuilderTest + [Fact(DisplayName = "Setting options works")] + public void Test004() { - [Fact(DisplayName = "Control and test html are set correctly")] - public void Test001() - { - var control = "

          control

          "; - var test = "

          test

          "; - - var sut = DiffBuilder - .Compare(control) - .WithTest(test); - - sut.Control.ShouldBe(control); - sut.Test.ShouldBe(test); - } - - [Fact(DisplayName = "Builder throws if null is passed to control and test")] - public void Test002() - { - Should.Throw(() => DiffBuilder.Compare(null!)).ParamName.ShouldBe(nameof(DiffBuilder.Control)); - Should.Throw(() => DiffBuilder.Compare("").WithTest(null!)).ParamName.ShouldBe(nameof(DiffBuilder.Test)); - } - - [Fact(DisplayName = "Calling Build() with DefaultOptions() returns expected diffs")] - public void Test003() - { - var control = @"

          hello world

          "; - var test = @"

          world says hello

          "; - - var diffs = DiffBuilder - .Compare(control) - .WithTest(test) - .Build() - .ToList(); - - diffs.Count.ShouldBe(6); - diffs.SingleOrDefault(x => x is AttrDiff).ShouldNotBeNull(); - diffs.SingleOrDefault(x => x is MissingAttrDiff).ShouldNotBeNull(); - diffs.SingleOrDefault(x => x is UnexpectedAttrDiff).ShouldNotBeNull(); - diffs.SingleOrDefault(x => x is NodeDiff).ShouldNotBeNull(); - diffs.SingleOrDefault(x => x is MissingNodeDiff).ShouldNotBeNull(); - diffs.SingleOrDefault(x => x is UnexpectedNodeDiff).ShouldNotBeNull(); - } - - [Fact(DisplayName = "Setting options works")] - public void Test004() - { - var control = "

          hello world

          "; - var test = "

          hello world

          "; - - var nodeFilterCalled = false; - var attrFilterCalled = false; - var nodeMatcherCalled = false; - var attrMatcherCalled = false; - var nodeComparerCalled = false; - var attrComparerCalled = false; - - var diffs = DiffBuilder - .Compare(control) - .WithTest(test) - .WithOptions(options => options - .AddDefaultOptions() - .AddFilter((in ComparisonSource source, FilterDecision currentDecision) => { nodeFilterCalled = true; return currentDecision; }) - .AddFilter((in AttributeComparisonSource source, FilterDecision currentDecision) => { attrFilterCalled = true; return currentDecision; }) - .AddMatcher((ctx, ctrlSrc, testSrc) => { nodeMatcherCalled = true; return Array.Empty(); }) - .AddMatcher((ctx, ctrlSrc, testSrc) => { attrMatcherCalled = true; return Array.Empty(); }) - .AddComparer((in Comparison comparison, CompareResult currentDecision) => { nodeComparerCalled = true; return currentDecision; }) - .AddComparer((in AttributeComparison comparison, CompareResult currentDecision) => { attrComparerCalled = true; return currentDecision; }) - ) - .Build() - .ToList(); - - nodeFilterCalled.ShouldBeTrue(); - attrFilterCalled.ShouldBeTrue(); - nodeMatcherCalled.ShouldBeTrue(); - attrMatcherCalled.ShouldBeTrue(); - nodeComparerCalled.ShouldBeTrue(); - attrComparerCalled.ShouldBeTrue(); - } - - [Theory(DisplayName = "When a control element has 'diff:ignoreChildren', calling Build() with DefaultOptions() returns empty diffs")] - [InlineData(@"

          hello world

          ", - @"

          world says hello

          ")] - [InlineData(@"

          hello

          ", - @"

          world says hello

          ")] - [InlineData(@"

          hello world

          ", - @"

          world says

          ")] - public void Test005(string control, string test) - { - var diffs = DiffBuilder - .Compare(control) - .WithTest(test) - .Build() - .ToList(); - - diffs.ShouldBeEmpty(); - } - - [Theory(DisplayName = "When a control element has 'diff:ignoreAttributes', calling Build() with DefaultOptions() returns empty diffs")] - [InlineData(@"

          ", - @"

          ")] - [InlineData(@"

          ", - @"

          ")] - [InlineData(@"

          ", - @"

          ")] - public void Test006(string control, string test) - { - var diffs = DiffBuilder - .Compare(control) - .WithTest(test) - .Build() - .ToList(); - - diffs.ShouldBeEmpty(); - } + var control = "

          hello world

          "; + var test = "

          hello world

          "; + + var nodeFilterCalled = false; + var attrFilterCalled = false; + var nodeMatcherCalled = false; + var attrMatcherCalled = false; + var nodeComparerCalled = false; + var attrComparerCalled = false; + + var diffs = DiffBuilder + .Compare(control) + .WithTest(test) + .WithOptions(options => options + .AddDefaultOptions() + .AddFilter((in ComparisonSource source, FilterDecision currentDecision) => { nodeFilterCalled = true; return currentDecision; }) + .AddFilter((in AttributeComparisonSource source, FilterDecision currentDecision) => { attrFilterCalled = true; return currentDecision; }) + .AddMatcher((ctx, ctrlSrc, testSrc) => { nodeMatcherCalled = true; return Array.Empty(); }) + .AddMatcher((ctx, ctrlSrc, testSrc) => { attrMatcherCalled = true; return Array.Empty(); }) + .AddComparer((in Comparison comparison, CompareResult currentDecision) => { nodeComparerCalled = true; return currentDecision; }) + .AddComparer((in AttributeComparison comparison, CompareResult currentDecision) => { attrComparerCalled = true; return currentDecision; }) + ) + .Build() + .ToList(); + + nodeFilterCalled.ShouldBeTrue(); + attrFilterCalled.ShouldBeTrue(); + nodeMatcherCalled.ShouldBeTrue(); + attrMatcherCalled.ShouldBeTrue(); + nodeComparerCalled.ShouldBeTrue(); + attrComparerCalled.ShouldBeTrue(); + } + + [Theory(DisplayName = "When a control element has 'diff:ignoreChildren', calling Build() with DefaultOptions() returns empty diffs")] + [InlineData(@"

          hello world

          ", + @"

          world says hello

          ")] + [InlineData(@"

          hello

          ", + @"

          world says hello

          ")] + [InlineData(@"

          hello world

          ", + @"

          world says

          ")] + public void Test005(string control, string test) + { + var diffs = DiffBuilder + .Compare(control) + .WithTest(test) + .Build() + .ToList(); + + diffs.ShouldBeEmpty(); + } + + [Theory(DisplayName = "When a control element has 'diff:ignoreAttributes', calling Build() with DefaultOptions() returns empty diffs")] + [InlineData(@"

          ", + @"

          ")] + [InlineData(@"

          ", + @"

          ")] + [InlineData(@"

          ", + @"

          ")] + public void Test006(string control, string test) + { + var diffs = DiffBuilder + .Compare(control) + .WithTest(test) + .Build() + .ToList(); + + diffs.ShouldBeEmpty(); } } diff --git a/src/AngleSharp.Diffing.Tests/DiffingTestBase.cs b/src/AngleSharp.Diffing.Tests/DiffingTestBase.cs index 7c5150d..e463258 100644 --- a/src/AngleSharp.Diffing.Tests/DiffingTestBase.cs +++ b/src/AngleSharp.Diffing.Tests/DiffingTestBase.cs @@ -1,79 +1,71 @@ -using System.Collections.Generic; +namespace AngleSharp.Diffing; -using AngleSharp.Diffing.Core; -using AngleSharp.Dom; - -using Xunit; - -namespace AngleSharp.Diffing +public abstract class DiffingTestBase : IClassFixture { - public abstract class DiffingTestBase : IClassFixture - { - private readonly DiffingTestFixture _testFixture; + private readonly DiffingTestFixture _testFixture; - protected IDiffContext DummyContext { get; } = new DiffContext(default(IElement), default(IElement)); + protected IDiffContext DummyContext { get; } = new DiffContext(default(IElement), default(IElement)); - protected INodeList EmptyNodeList => ToNodeList(""); + protected INodeList EmptyNodeList => ToNodeList(""); - public DiffingTestBase(DiffingTestFixture fixture) - { - _testFixture = fixture; - } + public DiffingTestBase(DiffingTestFixture fixture) + { + _testFixture = fixture; + } - protected INodeList ToNodeList(string? htmlsnippet) - { - var fragment = _testFixture.Parse(htmlsnippet); - return fragment; - } + protected INodeList ToNodeList(string? htmlsnippet) + { + var fragment = _testFixture.Parse(htmlsnippet); + return fragment; + } - protected IEnumerable ToComparisonSourceList(string html) - { - return ToNodeList(html).ToComparisonSourceList(ComparisonSourceType.Control); - } + protected IEnumerable ToComparisonSourceList(string html) + { + return ToNodeList(html).ToComparisonSourceList(ComparisonSourceType.Control); + } - protected INode ToNode(string htmlsnippet) - { - var fragment = _testFixture.Parse(htmlsnippet); - return fragment[0]; - } + protected INode ToNode(string htmlsnippet) + { + var fragment = _testFixture.Parse(htmlsnippet); + return fragment[0]; + } - protected ComparisonSource ToComparisonSource(string html, ComparisonSourceType sourceType = ComparisonSourceType.Control) - { - return ToNode(html).ToComparisonSource(0, sourceType); - } + protected ComparisonSource ToComparisonSource(string html, ComparisonSourceType sourceType = ComparisonSourceType.Control) + { + return ToNode(html).ToComparisonSource(0, sourceType); + } - protected Comparison ToComparison(string controlHtml, string testHtml) - { - return new Comparison( - ToComparisonSource(controlHtml, ComparisonSourceType.Control), - ToComparisonSource(testHtml, ComparisonSourceType.Test) - ); - } + protected Comparison ToComparison(string controlHtml, string testHtml) + { + return new Comparison( + ToComparisonSource(controlHtml, ComparisonSourceType.Control), + ToComparisonSource(testHtml, ComparisonSourceType.Test) + ); + } - protected AttributeComparisonSource ToAttributeComparisonSource(string html, string attrName, ComparisonSourceType sourceType = ComparisonSourceType.Control) - { - var elementSource = ToComparisonSource(html, sourceType); - return new AttributeComparisonSource(attrName, elementSource); - } + protected AttributeComparisonSource ToAttributeComparisonSource(string html, string attrName, ComparisonSourceType sourceType = ComparisonSourceType.Control) + { + var elementSource = ToComparisonSource(html, sourceType); + return new AttributeComparisonSource(attrName, elementSource); + } - protected AttributeComparison ToAttributeComparison(string controlHtml, string controlAttrName, string testHtml, string testAttrName) - { - return new AttributeComparison( - ToAttributeComparisonSource(controlHtml, controlAttrName, ComparisonSourceType.Control), - ToAttributeComparisonSource(testHtml, testAttrName, ComparisonSourceType.Test) - ); - } + protected AttributeComparison ToAttributeComparison(string controlHtml, string controlAttrName, string testHtml, string testAttrName) + { + return new AttributeComparison( + ToAttributeComparisonSource(controlHtml, controlAttrName, ComparisonSourceType.Control), + ToAttributeComparisonSource(testHtml, testAttrName, ComparisonSourceType.Test) + ); + } - protected SourceCollection ToSourceCollection(string html, ComparisonSourceType sourceType = ComparisonSourceType.Control) - { - var sources = ToComparisonSourceList(html); - return new SourceCollection(sourceType, sources); - } + protected SourceCollection ToSourceCollection(string html, ComparisonSourceType sourceType = ComparisonSourceType.Control) + { + var sources = ToComparisonSourceList(html); + return new SourceCollection(sourceType, sources); + } - protected SourceMap ToSourceMap(string html, ComparisonSourceType sourceType = ComparisonSourceType.Control) - { - var source = ToComparisonSource(html, sourceType); - return new SourceMap(source); - } + protected SourceMap ToSourceMap(string html, ComparisonSourceType sourceType = ComparisonSourceType.Control) + { + var source = ToComparisonSource(html, sourceType); + return new SourceMap(source); } } \ No newline at end of file diff --git a/src/AngleSharp.Diffing.Tests/DiffingTestFixture.cs b/src/AngleSharp.Diffing.Tests/DiffingTestFixture.cs index 9cdaf9c..28f7ab1 100644 --- a/src/AngleSharp.Diffing.Tests/DiffingTestFixture.cs +++ b/src/AngleSharp.Diffing.Tests/DiffingTestFixture.cs @@ -1,29 +1,27 @@ -using AngleSharp.Dom; -using AngleSharp.Html.Parser; +using AngleSharp.Html.Parser; -namespace AngleSharp.Diffing +namespace AngleSharp.Diffing; + +public class DiffingTestFixture { - public class DiffingTestFixture - { - private readonly IBrowsingContext _context; - private readonly IHtmlParser _htmlParser; - private readonly IDocument _document; + private readonly IBrowsingContext _context; + private readonly IHtmlParser _htmlParser; + private readonly IDocument _document; - public DiffingTestFixture() - { - // Create a custom config with a parser to allow access to the source reference from the AST. - var config = Configuration.Default - .WithCss() - .With(ctx => new HtmlParser(new HtmlParserOptions { IsKeepingSourceReferences = true, IsScripting = ctx?.IsScripting() ?? false }, ctx)); + public DiffingTestFixture() + { + // Create a custom config with a parser to allow access to the source reference from the AST. + var config = Configuration.Default + .WithCss() + .With(ctx => new HtmlParser(new HtmlParserOptions { IsKeepingSourceReferences = true, IsScripting = ctx?.IsScripting() ?? false }, ctx)); - _context = BrowsingContext.New(config); - _htmlParser = _context.GetService(); - _document = _context.OpenNewAsync().Result; - } + _context = BrowsingContext.New(config); + _htmlParser = _context.GetService(); + _document = _context.OpenNewAsync().Result; + } - public INodeList Parse(string? html) - { - return _htmlParser.ParseFragment(html, _document.Body); - } + public INodeList Parse(string? html) + { + return _htmlParser.ParseFragment(html, _document.Body); } } \ No newline at end of file diff --git a/src/AngleSharp.Diffing.Tests/ShouldlyTestExtensions.cs b/src/AngleSharp.Diffing.Tests/ShouldlyTestExtensions.cs index 2fc8b11..be358b1 100644 --- a/src/AngleSharp.Diffing.Tests/ShouldlyTestExtensions.cs +++ b/src/AngleSharp.Diffing.Tests/ShouldlyTestExtensions.cs @@ -1,16 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Linq; +namespace AngleSharp.Diffing; -using Shouldly; - -namespace AngleSharp.Diffing -{ - public static class ShouldlyTestExtensions - { - public static void ShouldAllBe(this IEnumerable actual, Func elementPredicate) - { - actual.Select(elementPredicate).ShouldAllBe(x => x); - } +public static class ShouldlyTestExtensions +{ + public static void ShouldAllBe(this IEnumerable actual, Func elementPredicate) + { + actual.Select(elementPredicate).ShouldAllBe(x => x); } } diff --git a/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/AttributeComparerTest.cs b/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/AttributeComparerTest.cs index 92675ed..e281fb8 100644 --- a/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/AttributeComparerTest.cs +++ b/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/AttributeComparerTest.cs @@ -1,96 +1,91 @@ -using AngleSharp.Diffing.Core; -using Shouldly; -using Xunit; +namespace AngleSharp.Diffing.Strategies.AttributeStrategies; -namespace AngleSharp.Diffing.Strategies.AttributeStrategies + +public class AttributeComparerTest : DiffingTestBase { + public AttributeComparerTest(DiffingTestFixture fixture) : base(fixture) + { + } + + [Fact(DisplayName = "When compare is called with a current decision of Same or Skip, the current decision is returned")] + public void Test001() + { + var comparison = ToAttributeComparison(@"", "foo", + "", "bar"); + + AttributeComparer.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); + AttributeComparer.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); + } + + [Fact(DisplayName = "When two attributes has the same name and no value, the compare result is Same")] + public void Test002() + { + var comparison = ToAttributeComparison(@"", "foo", + "", "foo"); + + AttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } + + [Fact(DisplayName = "When two attributes does not have the same name, the compare result is Different")] + public void Test003() + { + var comparison = ToAttributeComparison(@"", "foo", + "", "bar"); + + AttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); + } + + [Fact(DisplayName = "When two attribute values are the same, the compare result is Same")] + public void Test004() + { + var comparison = ToAttributeComparison(@"", "foo", + @"", "foo"); + + AttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } + + [Fact(DisplayName = "When two attribute values are different, the compare result is Different")] + public void Test005() + { + var comparison = ToAttributeComparison(@"", "foo", + @"", "foo"); + + AttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); + } + + [Fact(DisplayName = "When the control attribute is postfixed with :ignoreCase, " + + "a case insensitive comparison between control and test attributes is performed")] + public void Test006() + { + var comparison = ToAttributeComparison(@"", "foo:ignorecase", + @"", "foo"); + + AttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } + + [Fact(DisplayName = "When the control attribute is postfixed with :regex, " + + "the control attributes value is assumed to be a regular expression and " + + "that is used to match against the test attributes value")] + public void Test007() + { + var comparison = ToAttributeComparison(@"", "foo:regex", + @"", "foo"); + + AttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } - public class AttributeComparerTest : DiffingTestBase + [Theory(DisplayName = "When the control attribute is postfixed with :regex:ignoreCase " + + "or :ignoreCase:regex, the control attributes value is assumed " + + "to be a regular expression and that is used to do a case insensitive " + + "match against the test attributes value")] + [InlineData(":regex:ignorecase")] + [InlineData(":ignorecase:regex")] + public void Test008(string attrNamePostfix) { - public AttributeComparerTest(DiffingTestFixture fixture) : base(fixture) - { - } - - [Fact(DisplayName = "When compare is called with a current decision of Same or Skip, the current decision is returned")] - public void Test001() - { - var comparison = ToAttributeComparison(@"", "foo", - "", "bar"); - - AttributeComparer.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); - AttributeComparer.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); - } - - [Fact(DisplayName = "When two attributes has the same name and no value, the compare result is Same")] - public void Test002() - { - var comparison = ToAttributeComparison(@"", "foo", - "", "foo"); - - AttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } - - [Fact(DisplayName = "When two attributes does not have the same name, the compare result is Different")] - public void Test003() - { - var comparison = ToAttributeComparison(@"", "foo", - "", "bar"); - - AttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); - } - - [Fact(DisplayName = "When two attribute values are the same, the compare result is Same")] - public void Test004() - { - var comparison = ToAttributeComparison(@"", "foo", - @"", "foo"); - - AttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } - - [Fact(DisplayName = "When two attribute values are different, the compare result is Different")] - public void Test005() - { - var comparison = ToAttributeComparison(@"", "foo", - @"", "foo"); - - AttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); - } - - [Fact(DisplayName = "When the control attribute is postfixed with :ignoreCase, " + - "a case insensitive comparison between control and test attributes is performed")] - public void Test006() - { - var comparison = ToAttributeComparison(@"", "foo:ignorecase", - @"", "foo"); - - AttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } - - [Fact(DisplayName = "When the control attribute is postfixed with :regex, " + - "the control attributes value is assumed to be a regular expression and " + - "that is used to match against the test attributes value")] - public void Test007() - { - var comparison = ToAttributeComparison(@"", "foo:regex", - @"", "foo"); - - AttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } - - [Theory(DisplayName = "When the control attribute is postfixed with :regex:ignoreCase " + - "or :ignoreCase:regex, the control attributes value is assumed " + - "to be a regular expression and that is used to do a case insensitive " + - "match against the test attributes value")] - [InlineData(":regex:ignorecase")] - [InlineData(":ignorecase:regex")] - public void Test008(string attrNamePostfix) - { - var controlAttrName = $"foo{attrNamePostfix}"; - var comparison = ToAttributeComparison($@"", controlAttrName, - @"", "foo"); - - AttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } + var controlAttrName = $"foo{attrNamePostfix}"; + var comparison = ToAttributeComparison($@"", controlAttrName, + @"", "foo"); + + AttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); } } diff --git a/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/AttributeNameMatcherTest.cs b/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/AttributeNameMatcherTest.cs index 1a12bdf..263c441 100644 --- a/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/AttributeNameMatcherTest.cs +++ b/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/AttributeNameMatcherTest.cs @@ -1,83 +1,75 @@ -using System.Linq; - using AngleSharp.Diffing; -using AngleSharp.Diffing.Core; - -using Shouldly; -using Xunit; +namespace AngleSharp.Diffing.Strategies.AttributeStrategies; -namespace AngleSharp.Diffing.Strategies.AttributeStrategies +public class AttributeNameMatcherTest : DiffingTestBase { - public class AttributeNameMatcherTest : DiffingTestBase + public AttributeNameMatcherTest(DiffingTestFixture fixture) : base(fixture) + { + } + + [Fact(DisplayName = "When one or both source maps is empty, no matches are returned")] + public void Test001() + { + var controls = ToSourceMap("

          ", ComparisonSourceType.Control); + var tests = ToSourceMap("

          ", ComparisonSourceType.Test); + + var actual = AttributeNameMatcher.Match(DummyContext, controls, tests).ToList(); + + actual.ShouldBeEmpty(); + } + + [Theory(DisplayName = "When control and test sources have the same number of attributes, all should be matched")] + [InlineData(@"

          ", @"

          ", 1)] + [InlineData(@"

          ", @"

          ", 2)] + [InlineData(@"

          ", @"

          ", 3)] + public void Test002(string controlHtml, string testHtml, int expectedMatches) { - public AttributeNameMatcherTest(DiffingTestFixture fixture) : base(fixture) - { - } - - [Fact(DisplayName = "When one or both source maps is empty, no matches are returned")] - public void Test001() - { - var controls = ToSourceMap("

          ", ComparisonSourceType.Control); - var tests = ToSourceMap("

          ", ComparisonSourceType.Test); - - var actual = AttributeNameMatcher.Match(DummyContext, controls, tests).ToList(); - - actual.ShouldBeEmpty(); - } - - [Theory(DisplayName = "When control and test sources have the same number of attributes, all should be matched")] - [InlineData(@"

          ", @"

          ", 1)] - [InlineData(@"

          ", @"

          ", 2)] - [InlineData(@"

          ", @"

          ", 3)] - public void Test002(string controlHtml, string testHtml, int expectedMatches) - { - var controls = ToSourceMap(controlHtml, ComparisonSourceType.Control); - var tests = ToSourceMap(testHtml, ComparisonSourceType.Test); - - var actual = AttributeNameMatcher.Match(DummyContext, controls, tests).ToList(); - - actual.Count.ShouldBe(expectedMatches); - actual.ShouldAllBe(c => c.Control.Attribute.Name == c.Test.Attribute.Name); - } - - [Theory(DisplayName = "When control and test sources have the different number of attributes, all that match should be matched")] - [InlineData(@"

          ", @"

          ", 0)] - [InlineData(@"

          ", @"

          ", 1)] - [InlineData(@"

          ", @"

          ", 1)] - public void Test003(string controlHtml, string testHtml, int expectedMatches) - { - var controls = ToSourceMap(controlHtml, ComparisonSourceType.Control); - var tests = ToSourceMap(testHtml, ComparisonSourceType.Test); - - var actual = AttributeNameMatcher.Match(DummyContext, controls, tests).ToList(); - - actual.Count.ShouldBe(expectedMatches); - actual.ShouldAllBe(c => c.Control.Attribute.Name == c.Test.Attribute.Name); - } - - [Fact(DisplayName = "WHen a control attribute has been marked as matched, it is not matched again")] - public void Test004() - { - var controls = ToSourceMap(@"

          ", ComparisonSourceType.Control); - var tests = ToSourceMap(@"

          ", ComparisonSourceType.Test); - controls.MarkAsMatched(controls["foo"]); - - var actual = AttributeNameMatcher.Match(DummyContext, controls, tests).ToList(); - - actual.ShouldBeEmpty(); - } - - [Fact(DisplayName = "WHen a test attribute has been marked as matched, it is not matched again")] - public void Test005() - { - var controls = ToSourceMap(@"

          ", ComparisonSourceType.Control); - var tests = ToSourceMap(@"

          ", ComparisonSourceType.Test); - tests.MarkAsMatched(tests["foo"]); - - var actual = AttributeNameMatcher.Match(DummyContext, controls, tests).ToList(); - - actual.ShouldBeEmpty(); - } + var controls = ToSourceMap(controlHtml, ComparisonSourceType.Control); + var tests = ToSourceMap(testHtml, ComparisonSourceType.Test); + + var actual = AttributeNameMatcher.Match(DummyContext, controls, tests).ToList(); + + actual.Count.ShouldBe(expectedMatches); + actual.ShouldAllBe(c => c.Control.Attribute.Name == c.Test.Attribute.Name); + } + + [Theory(DisplayName = "When control and test sources have the different number of attributes, all that match should be matched")] + [InlineData(@"

          ", @"

          ", 0)] + [InlineData(@"

          ", @"

          ", 1)] + [InlineData(@"

          ", @"

          ", 1)] + public void Test003(string controlHtml, string testHtml, int expectedMatches) + { + var controls = ToSourceMap(controlHtml, ComparisonSourceType.Control); + var tests = ToSourceMap(testHtml, ComparisonSourceType.Test); + + var actual = AttributeNameMatcher.Match(DummyContext, controls, tests).ToList(); + + actual.Count.ShouldBe(expectedMatches); + actual.ShouldAllBe(c => c.Control.Attribute.Name == c.Test.Attribute.Name); + } + + [Fact(DisplayName = "WHen a control attribute has been marked as matched, it is not matched again")] + public void Test004() + { + var controls = ToSourceMap(@"

          ", ComparisonSourceType.Control); + var tests = ToSourceMap(@"

          ", ComparisonSourceType.Test); + controls.MarkAsMatched(controls["foo"]); + + var actual = AttributeNameMatcher.Match(DummyContext, controls, tests).ToList(); + + actual.ShouldBeEmpty(); + } + + [Fact(DisplayName = "WHen a test attribute has been marked as matched, it is not matched again")] + public void Test005() + { + var controls = ToSourceMap(@"

          ", ComparisonSourceType.Control); + var tests = ToSourceMap(@"

          ", ComparisonSourceType.Test); + tests.MarkAsMatched(tests["foo"]); + + var actual = AttributeNameMatcher.Match(DummyContext, controls, tests).ToList(); + + actual.ShouldBeEmpty(); } } diff --git a/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/BooleanAttributeComparerTest.cs b/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/BooleanAttributeComparerTest.cs index 393eba3..05d3d98 100644 --- a/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/BooleanAttributeComparerTest.cs +++ b/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/BooleanAttributeComparerTest.cs @@ -1,76 +1,66 @@ -using System.Collections.Generic; -using System.Linq; +namespace AngleSharp.Diffing.Strategies.AttributeStrategies; -using AngleSharp.Diffing.Core; - -using Shouldly; - -using Xunit; - -namespace AngleSharp.Diffing.Strategies.AttributeStrategies +public class BooleanAttributeComparerTest : DiffingTestBase { - public class BooleanAttributeComparerTest : DiffingTestBase - { - public static readonly IEnumerable BooleanAttributes = BooleanAttributeComparer.BooleanAttributes.Select(x => new string[] { x }).ToArray(); + public static readonly IEnumerable BooleanAttributes = BooleanAttributeComparer.BooleanAttributes.Select(x => new string[] { x }).ToArray(); - public BooleanAttributeComparerTest(DiffingTestFixture fixture) : base(fixture) - { - } + public BooleanAttributeComparerTest(DiffingTestFixture fixture) : base(fixture) + { + } - [Fact(DisplayName = "When attribute names are not the same comparer returns different")] - public void Test001() - { - var sut = new BooleanAttributeComparer(BooleanAttributeComparision.Strict); - var comparison = ToAttributeComparison("", "foo", "", "bar"); + [Fact(DisplayName = "When attribute names are not the same comparer returns different")] + public void Test001() + { + var sut = new BooleanAttributeComparer(BooleanAttributeComparision.Strict); + var comparison = ToAttributeComparison("", "foo", "", "bar"); - sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); - } + sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); + } - [Fact(DisplayName = "When attribute name is not an boolean attribute, its current result is returned")] - public void Test002() - { - var sut = new BooleanAttributeComparer(BooleanAttributeComparision.Strict); - var comparison = ToAttributeComparison(@"", "class", @"", "class"); + [Fact(DisplayName = "When attribute name is not an boolean attribute, its current result is returned")] + public void Test002() + { + var sut = new BooleanAttributeComparer(BooleanAttributeComparision.Strict); + var comparison = ToAttributeComparison(@"", "class", @"", "class"); - sut.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); - } + sut.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); + } - [Theory(DisplayName = "When attributes is boolean and mode is strict, " + - "the attribute is considered truthy if conforms to the html5 spec and" + - "the result is Same if both control and test attribute are truthy")] - [MemberData(nameof(BooleanAttributes))] - public void Test003(string attrName) - { - var sut = new BooleanAttributeComparer(BooleanAttributeComparision.Strict); - var c1 = ToAttributeComparison($@"", attrName, $@"", attrName); - var c2 = ToAttributeComparison($@"", attrName, $@"", attrName); - var c3 = ToAttributeComparison($@"", attrName, $@"", attrName); - var c4 = ToAttributeComparison($@"", attrName, $@"", attrName); - var c5 = ToAttributeComparison($@"", attrName, $@"", attrName); - var c6 = ToAttributeComparison($@"", attrName, $@"", attrName); + [Theory(DisplayName = "When attributes is boolean and mode is strict, " + + "the attribute is considered truthy if conforms to the html5 spec and" + + "the result is Same if both control and test attribute are truthy")] + [MemberData(nameof(BooleanAttributes))] + public void Test003(string attrName) + { + var sut = new BooleanAttributeComparer(BooleanAttributeComparision.Strict); + var c1 = ToAttributeComparison($@"", attrName, $@"", attrName); + var c2 = ToAttributeComparison($@"", attrName, $@"", attrName); + var c3 = ToAttributeComparison($@"", attrName, $@"", attrName); + var c4 = ToAttributeComparison($@"", attrName, $@"", attrName); + var c5 = ToAttributeComparison($@"", attrName, $@"", attrName); + var c6 = ToAttributeComparison($@"", attrName, $@"", attrName); - sut.Compare(c1, CompareResult.Unknown).ShouldBe(CompareResult.Same); - sut.Compare(c2, CompareResult.Unknown).ShouldBe(CompareResult.Same); - sut.Compare(c3, CompareResult.Unknown).ShouldBe(CompareResult.Same); - sut.Compare(c4, CompareResult.Unknown).ShouldBe(CompareResult.Same); - sut.Compare(c5, CompareResult.Unknown).ShouldBe(CompareResult.Same); - sut.Compare(c6, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } + sut.Compare(c1, CompareResult.Unknown).ShouldBe(CompareResult.Same); + sut.Compare(c2, CompareResult.Unknown).ShouldBe(CompareResult.Same); + sut.Compare(c3, CompareResult.Unknown).ShouldBe(CompareResult.Same); + sut.Compare(c4, CompareResult.Unknown).ShouldBe(CompareResult.Same); + sut.Compare(c5, CompareResult.Unknown).ShouldBe(CompareResult.Same); + sut.Compare(c6, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } - [Theory(DisplayName = "When attributes is boolean and mode is loose, the presence of " + - "two attributes with the same name returns compare result Same, no matter what their value is")] - [MemberData(nameof(BooleanAttributes))] - public void Test004(string attrName) - { - var sut = new BooleanAttributeComparer(BooleanAttributeComparision.Loose); - var c1 = ToAttributeComparison($@"", attrName, $@"", attrName); - var c2 = ToAttributeComparison($@"", attrName, $@"", attrName); - var c3 = ToAttributeComparison($@"", attrName, $@"", attrName); + [Theory(DisplayName = "When attributes is boolean and mode is loose, the presence of " + + "two attributes with the same name returns compare result Same, no matter what their value is")] + [MemberData(nameof(BooleanAttributes))] + public void Test004(string attrName) + { + var sut = new BooleanAttributeComparer(BooleanAttributeComparision.Loose); + var c1 = ToAttributeComparison($@"", attrName, $@"", attrName); + var c2 = ToAttributeComparison($@"", attrName, $@"", attrName); + var c3 = ToAttributeComparison($@"", attrName, $@"", attrName); - sut.Compare(c1, CompareResult.Unknown).ShouldBe(CompareResult.Same); - sut.Compare(c2, CompareResult.Unknown).ShouldBe(CompareResult.Same); - sut.Compare(c3, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } + sut.Compare(c1, CompareResult.Unknown).ShouldBe(CompareResult.Same); + sut.Compare(c2, CompareResult.Unknown).ShouldBe(CompareResult.Same); + sut.Compare(c3, CompareResult.Unknown).ShouldBe(CompareResult.Same); } } diff --git a/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/ClassAttributeComparerTest.cs b/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/ClassAttributeComparerTest.cs index 6444341..a9eb44f 100644 --- a/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/ClassAttributeComparerTest.cs +++ b/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/ClassAttributeComparerTest.cs @@ -1,63 +1,56 @@ -using AngleSharp.Diffing.Core; +namespace AngleSharp.Diffing.Strategies.AttributeStrategies; -using Shouldly; +public class ClassAttributeComparerTest : DiffingTestBase +{ + public ClassAttributeComparerTest(DiffingTestFixture fixture) : base(fixture) + { + } + + [Theory(DisplayName = "When a class attribute is compared, the order of individual " + + "classes and multiple whitespace is ignored")] + [InlineData("", "")] + [InlineData(" foo", "foo ")] + [InlineData("foo bar", " foo bar ")] + [InlineData("foo bar", "bar foo ")] + [InlineData("foo bar baz", "bar foo baz ")] + public void Test009(string controlClasses, string testClasses) + { + var comparison = ToAttributeComparison($@"

          ", "class", + $@"

          ", "class"); -using Xunit; + ClassAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } -namespace AngleSharp.Diffing.Strategies.AttributeStrategies -{ - public class ClassAttributeComparerTest : DiffingTestBase + [Fact(DisplayName = "When a class attribute is matched up with another attribute, the result is different")] + public void Test010() + { + var comparison = ToAttributeComparison(@"

          ", "class", + @"

          ", "bar"); + + ClassAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); + } + + [Theory(DisplayName = "When there are different number of classes in the class attributes the result is different")] + [InlineData("foo bar baz", "baz foo")] + [InlineData("bar baz", "bar baz foo")] + public void Test011(string controlClasses, string testClasses) + { + var comparison = ToAttributeComparison($@"

          ", "class", + $@"

          ", "class"); + + ClassAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); + } + + [Theory(DisplayName = "When the classes in the class attributes are different the result is different")] + [InlineData("foo", "bar")] + [InlineData("foo bar", "baz bin")] + [InlineData("foo bar", "foo bin")] + [InlineData("foo bar", "baz bar")] + public void Test012(string controlClasses, string testClasses) { - public ClassAttributeComparerTest(DiffingTestFixture fixture) : base(fixture) - { - } - - [Theory(DisplayName = "When a class attribute is compared, the order of individual " + - "classes and multiple whitespace is ignored")] - [InlineData("", "")] - [InlineData(" foo", "foo ")] - [InlineData("foo bar", " foo bar ")] - [InlineData("foo bar", "bar foo ")] - [InlineData("foo bar baz", "bar foo baz ")] - public void Test009(string controlClasses, string testClasses) - { - var comparison = ToAttributeComparison($@"

          ", "class", - $@"

          ", "class"); - - ClassAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } - - [Fact(DisplayName = "When a class attribute is matched up with another attribute, the result is different")] - public void Test010() - { - var comparison = ToAttributeComparison(@"

          ", "class", - @"

          ", "bar"); - - ClassAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); - } - - [Theory(DisplayName = "When there are different number of classes in the class attributes the result is different")] - [InlineData("foo bar baz", "baz foo")] - [InlineData("bar baz", "bar baz foo")] - public void Test011(string controlClasses, string testClasses) - { - var comparison = ToAttributeComparison($@"

          ", "class", - $@"

          ", "class"); - - ClassAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); - } - - [Theory(DisplayName = "When the classes in the class attributes are different the result is different")] - [InlineData("foo", "bar")] - [InlineData("foo bar", "baz bin")] - [InlineData("foo bar", "foo bin")] - [InlineData("foo bar", "baz bar")] - public void Test012(string controlClasses, string testClasses) - { - var comparison = ToAttributeComparison($@"

          ", "class", - $@"

          ", "class"); - - ClassAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); - } + var comparison = ToAttributeComparison($@"

          ", "class", + $@"

          ", "class"); + + ClassAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); } } diff --git a/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/IgnoreAttributeComparerTest.cs b/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/IgnoreAttributeComparerTest.cs index 78141eb..06cd19d 100644 --- a/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/IgnoreAttributeComparerTest.cs +++ b/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/IgnoreAttributeComparerTest.cs @@ -1,39 +1,33 @@ -using AngleSharp.Diffing.Core; -using AngleSharp.Diffing.Strategies.AttributeStrategies; +using AngleSharp.Diffing.Strategies.AttributeStrategies; -using Shouldly; +namespace AngleSharp.Diffing.Strategies.IgnoreStrategies; -using Xunit; - -namespace AngleSharp.Diffing.Strategies.IgnoreStrategies +public class IgnoreAttributeComparerTest : DiffingTestBase { - public class IgnoreAttributeComparerTest : DiffingTestBase + public IgnoreAttributeComparerTest(DiffingTestFixture fixture) : base(fixture) { - public IgnoreAttributeComparerTest(DiffingTestFixture fixture) : base(fixture) - { - } + } - [Fact(DisplayName = "When a attribute does not contain have the ':ignore' postfix, the current decision is returned")] - public void Test003() - { - var comparison = ToAttributeComparison( - @"

          ", "foo", - @"

          ", "foo" - ); + [Fact(DisplayName = "When a attribute does not contain have the ':ignore' postfix, the current decision is returned")] + public void Test003() + { + var comparison = ToAttributeComparison( + @"

          ", "foo", + @"

          ", "foo" + ); - IgnoreAttributeComparer.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); - IgnoreAttributeComparer.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); - } + IgnoreAttributeComparer.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); + IgnoreAttributeComparer.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); + } - [Fact(DisplayName = "When a attribute does contain have the ':ignore' postfix, Same is returned")] - public void Test004() - { - var comparison = ToAttributeComparison( - @"

          ", "foo:ignore", - @"

          ", "foo" - ); + [Fact(DisplayName = "When a attribute does contain have the ':ignore' postfix, Same is returned")] + public void Test004() + { + var comparison = ToAttributeComparison( + @"

          ", "foo:ignore", + @"

          ", "foo" + ); - IgnoreAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } + IgnoreAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); } } diff --git a/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/IgnoreDiffAttributesFilterTest.cs b/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/IgnoreDiffAttributesFilterTest.cs index 209d9f2..55bf899 100644 --- a/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/IgnoreDiffAttributesFilterTest.cs +++ b/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/IgnoreDiffAttributesFilterTest.cs @@ -1,36 +1,29 @@ -using AngleSharp.Diffing.Core; +namespace AngleSharp.Diffing.Strategies.AttributeStrategies; -using Shouldly; - -using Xunit; - -namespace AngleSharp.Diffing.Strategies.AttributeStrategies +public class IgnoreDiffAttributesFilterTest : DiffingTestBase { - public class IgnoreDiffAttributesFilterTest : DiffingTestBase + public IgnoreDiffAttributesFilterTest(DiffingTestFixture fixture) : base(fixture) { - public IgnoreDiffAttributesFilterTest(DiffingTestFixture fixture) : base(fixture) - { - } + } - [Theory(DisplayName = "When an attribute starts with 'diff:' it is filtered out")] - [InlineData(@"

          ", "diff:whitespace")] - [InlineData(@"

          ", "diff:ignore")] - public void Test1(string elementHtml, string diffAttrName) - { - var source = ToAttributeComparisonSource(elementHtml, diffAttrName); + [Theory(DisplayName = "When an attribute starts with 'diff:' it is filtered out")] + [InlineData(@"

          ", "diff:whitespace")] + [InlineData(@"

          ", "diff:ignore")] + public void Test1(string elementHtml, string diffAttrName) + { + var source = ToAttributeComparisonSource(elementHtml, diffAttrName); - IgnoreDiffAttributesFilter.Filter(source, FilterDecision.Keep).ShouldBe(FilterDecision.Exclude); - } + IgnoreDiffAttributesFilter.Filter(source, FilterDecision.Keep).ShouldBe(FilterDecision.Exclude); + } - [Theory(DisplayName = "When an attribute does not starts with 'diff:' its current decision is used")] - [InlineData(@"

          ", "lang")] - [InlineData(@"

          ", "diff")] - [InlineData(@"

          ", "diffx")] - public void Test2(string elementHtml, string diffAttrName) - { - var source = ToAttributeComparisonSource(elementHtml, diffAttrName); + [Theory(DisplayName = "When an attribute does not starts with 'diff:' its current decision is used")] + [InlineData(@"

          ", "lang")] + [InlineData(@"

          ", "diff")] + [InlineData(@"

          ", "diffx")] + public void Test2(string elementHtml, string diffAttrName) + { + var source = ToAttributeComparisonSource(elementHtml, diffAttrName); - IgnoreDiffAttributesFilter.Filter(source, FilterDecision.Keep).ShouldBe(FilterDecision.Keep); - } + IgnoreDiffAttributesFilter.Filter(source, FilterDecision.Keep).ShouldBe(FilterDecision.Keep); } } diff --git a/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/OrderingStyleAttributeComparerTest.cs b/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/OrderingStyleAttributeComparerTest.cs index a027047..2b06a0f 100644 --- a/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/OrderingStyleAttributeComparerTest.cs +++ b/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/OrderingStyleAttributeComparerTest.cs @@ -1,66 +1,61 @@ -using AngleSharp.Diffing.Core; -using Shouldly; -using Xunit; +namespace AngleSharp.Diffing.Strategies.AttributeStrategies; -namespace AngleSharp.Diffing.Strategies.AttributeStrategies +public class OrderingStyleAttributeComparerTest : DiffingTestBase { - public class OrderingStyleAttributeComparerTest : DiffingTestBase + public OrderingStyleAttributeComparerTest(DiffingTestFixture fixture) : base(fixture) { - public OrderingStyleAttributeComparerTest(DiffingTestFixture fixture) : base(fixture) - { - } + } - [Fact(DisplayName = "When attribute is not style the current decision is used")] - public void Test001() - { - var comparison = ToAttributeComparison(@"

          ", "foo", @"

          ", "foo"); - StyleAttributeComparer.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); - StyleAttributeComparer.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); - StyleAttributeComparer.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); - } + [Fact(DisplayName = "When attribute is not style the current decision is used")] + public void Test001() + { + var comparison = ToAttributeComparison(@"

          ", "foo", @"

          ", "foo"); + StyleAttributeComparer.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); + StyleAttributeComparer.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); + StyleAttributeComparer.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); + } - [Theory(DisplayName = "When style attributes has different values then Different is returned")] - [InlineData(@"

          ", @"

          ")] - [InlineData(@"

          ", @"

          ")] - [InlineData(@"

          ", @"

          ")] - [InlineData(@"

          ", @"

          ")] - public void Test002(string control, string test) - { - var comparison = ToAttributeComparison(control, "style", test, "style"); - OrderingStyleAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); - } + [Theory(DisplayName = "When style attributes has different values then Different is returned")] + [InlineData(@"

          ", @"

          ")] + [InlineData(@"

          ", @"

          ")] + [InlineData(@"

          ", @"

          ")] + [InlineData(@"

          ", @"

          ")] + public void Test002(string control, string test) + { + var comparison = ToAttributeComparison(control, "style", test, "style"); + OrderingStyleAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); + } - [Fact(DisplayName = "Comparer should correctly ignore insignificant whitespace")] - public void Test003() - { - var comparison = ToAttributeComparison(@"

          ", "style", @"

          ", "style"); - OrderingStyleAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } + [Fact(DisplayName = "Comparer should correctly ignore insignificant whitespace")] + public void Test003() + { + var comparison = ToAttributeComparison(@"

          ", "style", @"

          ", "style"); + OrderingStyleAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } - [Theory(DisplayName = "Comparer should ignore trailing semi colons")] - [InlineData(@"

          ", @"

          ")] - [InlineData(@"

          ", @"

          ")] - public void Test004(string control, string test) - { - var comparison = ToAttributeComparison(control, "style", test, "style"); - OrderingStyleAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } + [Theory(DisplayName = "Comparer should ignore trailing semi colons")] + [InlineData(@"

          ", @"

          ")] + [InlineData(@"

          ", @"

          ")] + public void Test004(string control, string test) + { + var comparison = ToAttributeComparison(control, "style", test, "style"); + OrderingStyleAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } - [Theory(DisplayName = "Comparer should ignore different order")] - [InlineData(@"

          ", @"

          ")] - [InlineData(@"

          ", @"

          ")] - public void Test005(string control, string test) - { - var comparison = ToAttributeComparison(control, "style", test, "style"); - OrderingStyleAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } + [Theory(DisplayName = "Comparer should ignore different order")] + [InlineData(@"

          ", @"

          ")] + [InlineData(@"

          ", @"

          ")] + public void Test005(string control, string test) + { + var comparison = ToAttributeComparison(control, "style", test, "style"); + OrderingStyleAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } - [Theory(DisplayName = "Comparer should ignore different order inside style")] - [InlineData(@"

          ", @"

          ")] - public void Test006(string control, string test) - { - var comparison = ToAttributeComparison(control, "style", test, "style"); - OrderingStyleAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } + [Theory(DisplayName = "Comparer should ignore different order inside style")] + [InlineData(@"

          ", @"

          ")] + public void Test006(string control, string test) + { + var comparison = ToAttributeComparison(control, "style", test, "style"); + OrderingStyleAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); } } diff --git a/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/PostfixedAttributeMatcherTest.cs b/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/PostfixedAttributeMatcherTest.cs index f5eed79..ca34ae8 100644 --- a/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/PostfixedAttributeMatcherTest.cs +++ b/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/PostfixedAttributeMatcherTest.cs @@ -1,80 +1,70 @@ -using System.Collections.Generic; -using System.Linq; +namespace AngleSharp.Diffing.Strategies.AttributeStrategies; -using AngleSharp.Diffing.Core; - -using Shouldly; - -using Xunit; - -namespace AngleSharp.Diffing.Strategies.AttributeStrategies +public class PostfixedAttributeMatcherTest : DiffingTestBase { - public class PostfixedAttributeMatcherTest : DiffingTestBase + public PostfixedAttributeMatcherTest(DiffingTestFixture fixture) : base(fixture) { - public PostfixedAttributeMatcherTest(DiffingTestFixture fixture) : base(fixture) - { - } - - public static IEnumerable AttributeDiffPostfixesCombinations { get; } = new List - { - new []{":ignore"}, - new []{":regex"}, - new []{":ignorecase"}, - new []{":ignorecase:regex"}, - new []{":regex:ignorecase"}, - }; + } - [Fact(DisplayName = "When a attribute does not have a diff postfix, no matching is performed")] - public void Test001() - { - var controls = ToSourceMap(@"

          ", ComparisonSourceType.Control); - var tests = ToSourceMap(@"

          ", ComparisonSourceType.Test); + public static IEnumerable AttributeDiffPostfixesCombinations { get; } = new List + { + new []{":ignore"}, + new []{":regex"}, + new []{":ignorecase"}, + new []{":ignorecase:regex"}, + new []{":regex:ignorecase"}, + }; + + [Fact(DisplayName = "When a attribute does not have a diff postfix, no matching is performed")] + public void Test001() + { + var controls = ToSourceMap(@"

          ", ComparisonSourceType.Control); + var tests = ToSourceMap(@"

          ", ComparisonSourceType.Test); - var actual = PostfixedAttributeMatcher.Match(DummyContext, controls, tests).ToList(); + var actual = PostfixedAttributeMatcher.Match(DummyContext, controls, tests).ToList(); - actual.ShouldBeEmpty(); - } + actual.ShouldBeEmpty(); + } - [Theory(DisplayName = "When a control attribute does have a diff postfix, but has already been matched, no new match is made")] - [MemberData(nameof(AttributeDiffPostfixesCombinations))] - public void Test002(string diffPostfix) - { - var controls = ToSourceMap($@"

          ", ComparisonSourceType.Control); - var tests = ToSourceMap(@"

          ", ComparisonSourceType.Test); - controls.MarkAsMatched(controls[$"foo{diffPostfix}"]); + [Theory(DisplayName = "When a control attribute does have a diff postfix, but has already been matched, no new match is made")] + [MemberData(nameof(AttributeDiffPostfixesCombinations))] + public void Test002(string diffPostfix) + { + var controls = ToSourceMap($@"

          ", ComparisonSourceType.Control); + var tests = ToSourceMap(@"

          ", ComparisonSourceType.Test); + controls.MarkAsMatched(controls[$"foo{diffPostfix}"]); - var actual = PostfixedAttributeMatcher.Match(DummyContext, controls, tests).ToList(); + var actual = PostfixedAttributeMatcher.Match(DummyContext, controls, tests).ToList(); - actual.ShouldBeEmpty(); - } + actual.ShouldBeEmpty(); + } - [Theory(DisplayName = "When a control attribute does have a diff postfix, but the test attribute has already been matched, no new match is made")] - [MemberData(nameof(AttributeDiffPostfixesCombinations))] - public void Test003(string diffPostfix) - { - var controls = ToSourceMap($@"

          ", ComparisonSourceType.Control); - var tests = ToSourceMap(@"

          ", ComparisonSourceType.Test); - tests.MarkAsMatched(tests["foo"]); + [Theory(DisplayName = "When a control attribute does have a diff postfix, but the test attribute has already been matched, no new match is made")] + [MemberData(nameof(AttributeDiffPostfixesCombinations))] + public void Test003(string diffPostfix) + { + var controls = ToSourceMap($@"

          ", ComparisonSourceType.Control); + var tests = ToSourceMap(@"

          ", ComparisonSourceType.Test); + tests.MarkAsMatched(tests["foo"]); - var actual = PostfixedAttributeMatcher.Match(DummyContext, controls, tests).ToList(); + var actual = PostfixedAttributeMatcher.Match(DummyContext, controls, tests).ToList(); - actual.ShouldBeEmpty(); - } + actual.ShouldBeEmpty(); + } - [Theory(DisplayName = "When a attribute does have a diff postfix, it is matched with a attribute with the same suffix")] - [MemberData(nameof(AttributeDiffPostfixesCombinations))] - public void Test004(string diffPostfix) - { - var controls = ToSourceMap($@"

          ", ComparisonSourceType.Control); - var tests = ToSourceMap(@"

          ", ComparisonSourceType.Test); + [Theory(DisplayName = "When a attribute does have a diff postfix, it is matched with a attribute with the same suffix")] + [MemberData(nameof(AttributeDiffPostfixesCombinations))] + public void Test004(string diffPostfix) + { + var controls = ToSourceMap($@"

          ", ComparisonSourceType.Control); + var tests = ToSourceMap(@"

          ", ComparisonSourceType.Test); - var actual = PostfixedAttributeMatcher.Match(DummyContext, controls, tests).ToList(); + var actual = PostfixedAttributeMatcher.Match(DummyContext, controls, tests).ToList(); - actual.Count.ShouldBe(1); - actual[0].ShouldSatisfyAllConditions( - c => c.Control.Attribute.Name.ShouldBe($"foo{diffPostfix}"), - c => c.Test.Attribute.Name.ShouldBe("foo") - ); - } + actual.Count.ShouldBe(1); + actual[0].ShouldSatisfyAllConditions( + c => c.Control.Attribute.Name.ShouldBe($"foo{diffPostfix}"), + c => c.Test.Attribute.Name.ShouldBe("foo") + ); } } diff --git a/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/StyleAttributeComparerTest.cs b/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/StyleAttributeComparerTest.cs index 76f9976..b2e617c 100644 --- a/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/StyleAttributeComparerTest.cs +++ b/src/AngleSharp.Diffing.Tests/Strategies/AttributeStrategies/StyleAttributeComparerTest.cs @@ -1,57 +1,52 @@ -using AngleSharp.Diffing.Core; -using Shouldly; -using Xunit; +namespace AngleSharp.Diffing.Strategies.AttributeStrategies; -namespace AngleSharp.Diffing.Strategies.AttributeStrategies +public class StyleAttributeComparerTest : DiffingTestBase { - public class StyleAttributeComparerTest : DiffingTestBase + public StyleAttributeComparerTest(DiffingTestFixture fixture) : base(fixture) { - public StyleAttributeComparerTest(DiffingTestFixture fixture) : base(fixture) - { - } + } - [Fact(DisplayName = "When attribute is not style the current decision is used")] - public void Test001() - { - var comparison = ToAttributeComparison(@"

          ", "foo", @"

          ", "foo"); - StyleAttributeComparer.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); - StyleAttributeComparer.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); - StyleAttributeComparer.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); - } + [Fact(DisplayName = "When attribute is not style the current decision is used")] + public void Test001() + { + var comparison = ToAttributeComparison(@"

          ", "foo", @"

          ", "foo"); + StyleAttributeComparer.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); + StyleAttributeComparer.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); + StyleAttributeComparer.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); + } - [Theory(DisplayName = "When style attributes has different values then Different is returned")] - [InlineData(@"

          ", @"

          ")] - [InlineData(@"

          ", @"

          ")] - [InlineData(@"

          ", @"

          ")] - [InlineData(@"

          ", @"

          ")] - public void Test002(string control, string test) - { - var comparison = ToAttributeComparison(control, "style", test, "style"); - StyleAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); - } + [Theory(DisplayName = "When style attributes has different values then Different is returned")] + [InlineData(@"

          ", @"

          ")] + [InlineData(@"

          ", @"

          ")] + [InlineData(@"

          ", @"

          ")] + [InlineData(@"

          ", @"

          ")] + public void Test002(string control, string test) + { + var comparison = ToAttributeComparison(control, "style", test, "style"); + StyleAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); + } - [Fact(DisplayName = "Comparer should correctly ignore insignificant whitespace")] - public void Test003() - { - var comparison = ToAttributeComparison(@"

          ", "style", @"

          ", "style"); - StyleAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } + [Fact(DisplayName = "Comparer should correctly ignore insignificant whitespace")] + public void Test003() + { + var comparison = ToAttributeComparison(@"

          ", "style", @"

          ", "style"); + StyleAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } - [Theory(DisplayName = "Comparer should ignore trailing semi colons")] - [InlineData(@"

          ", @"

          ")] - [InlineData(@"

          ", @"

          ")] - public void Test004(string control, string test) - { - var comparison = ToAttributeComparison(control, "style", test, "style"); - StyleAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } + [Theory(DisplayName = "Comparer should ignore trailing semi colons")] + [InlineData(@"

          ", @"

          ")] + [InlineData(@"

          ", @"

          ")] + public void Test004(string control, string test) + { + var comparison = ToAttributeComparison(control, "style", test, "style"); + StyleAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } - [Theory(DisplayName = "Comparer should ignore different order inside style")] - [InlineData(@"

          ", @"

          ")] - public void Test005(string control, string test) - { - var comparison = ToAttributeComparison(control, "style", test, "style"); - StyleAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } + [Theory(DisplayName = "Comparer should ignore different order inside style")] + [InlineData(@"

          ", @"

          ")] + public void Test005(string control, string test) + { + var comparison = ToAttributeComparison(control, "style", test, "style"); + StyleAttributeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); } } diff --git a/src/AngleSharp.Diffing.Tests/Strategies/CommentStrategies/IgnoreCommentsFilterTest.cs b/src/AngleSharp.Diffing.Tests/Strategies/CommentStrategies/IgnoreCommentsFilterTest.cs index c35ccef..0955e30 100644 --- a/src/AngleSharp.Diffing.Tests/Strategies/CommentStrategies/IgnoreCommentsFilterTest.cs +++ b/src/AngleSharp.Diffing.Tests/Strategies/CommentStrategies/IgnoreCommentsFilterTest.cs @@ -1,35 +1,28 @@ -using AngleSharp.Diffing.Core; +namespace AngleSharp.Diffing.Strategies.CommentStrategies; -using Shouldly; - -using Xunit; - -namespace AngleSharp.Diffing.Strategies.CommentStrategies +public class IgnoreCommentsFilterTest : DiffingTestBase { - public class IgnoreCommentsFilterTest : DiffingTestBase + public IgnoreCommentsFilterTest(DiffingTestFixture fixture) : base(fixture) { - public IgnoreCommentsFilterTest(DiffingTestFixture fixture) : base(fixture) - { - } + } - [Theory(DisplayName = "Comment nodes and their child node are filtered out")] - [InlineData("")] - [InlineData("")] - public void Test1(string html) - { - var commentSource = ToComparisonSource(html); + [Theory(DisplayName = "Comment nodes and their child node are filtered out")] + [InlineData("")] + [InlineData("")] + public void Test1(string html) + { + var commentSource = ToComparisonSource(html); - IgnoreCommentsFilter.Filter(commentSource, FilterDecision.Keep).ShouldBe(FilterDecision.Exclude); - } + IgnoreCommentsFilter.Filter(commentSource, FilterDecision.Keep).ShouldBe(FilterDecision.Exclude); + } - [Theory(DisplayName = "When called with a none-comment node, the current decision is returned")] - [InlineData("Textnode")] - [InlineData("

          ")] - public void Test2(string html) - { - var source = ToComparisonSource(html); + [Theory(DisplayName = "When called with a none-comment node, the current decision is returned")] + [InlineData("Textnode")] + [InlineData("

          ")] + public void Test2(string html) + { + var source = ToComparisonSource(html); - IgnoreCommentsFilter.Filter(source, FilterDecision.Keep).ShouldBe(FilterDecision.Keep); - } + IgnoreCommentsFilter.Filter(source, FilterDecision.Keep).ShouldBe(FilterDecision.Keep); } } diff --git a/src/AngleSharp.Diffing.Tests/Strategies/ElementStrategies/CssSelectorElementMatcherTest.cs b/src/AngleSharp.Diffing.Tests/Strategies/ElementStrategies/CssSelectorElementMatcherTest.cs index d700701..b8679a0 100644 --- a/src/AngleSharp.Diffing.Tests/Strategies/ElementStrategies/CssSelectorElementMatcherTest.cs +++ b/src/AngleSharp.Diffing.Tests/Strategies/ElementStrategies/CssSelectorElementMatcherTest.cs @@ -1,86 +1,76 @@ -using System.Linq; +namespace AngleSharp.Diffing.Strategies.ElementStrategies; -using AngleSharp.Diffing.Core; -using AngleSharp.Dom; - -using Shouldly; - -using Xunit; - -namespace AngleSharp.Diffing.Strategies.ElementStrategies +public class CssSelectorElementMatcherTest : DiffingTestBase { - public class CssSelectorElementMatcherTest : DiffingTestBase + public CssSelectorElementMatcherTest(DiffingTestFixture fixture) : base(fixture) { - public CssSelectorElementMatcherTest(DiffingTestFixture fixture) : base(fixture) - { - } + } - [Theory(DisplayName = "When a node is not an element and does not have the diff:match attribute, " + - "no match is attempted nor returned")] - [InlineData("textnode")] - [InlineData("")] - [InlineData("

          ")] - public void Test001(string html) - { - var controls = ToSourceCollection(html, ComparisonSourceType.Control); - var tests = ToSourceCollection(html, ComparisonSourceType.Test); + [Theory(DisplayName = "When a node is not an element and does not have the diff:match attribute, " + + "no match is attempted nor returned")] + [InlineData("textnode")] + [InlineData("")] + [InlineData("

          ")] + public void Test001(string html) + { + var controls = ToSourceCollection(html, ComparisonSourceType.Control); + var tests = ToSourceCollection(html, ComparisonSourceType.Test); - var actual = CssSelectorElementMatcher.Match(DummyContext, controls, tests).ToList(); + var actual = CssSelectorElementMatcher.Match(DummyContext, controls, tests).ToList(); - actual.ShouldBeEmpty(); - } + actual.ShouldBeEmpty(); + } - [Fact(DisplayName = "When a control element contains the diff:match attribute, " + - "its value is expected to be a CSS selector string, that can be used to search " + - "the test node tree for a matching node")] - public void Test002() - { - var controls = ToSourceCollection(@"

          p:first-child"">

          ", ComparisonSourceType.Control); - var tests = ToSourceCollection("

          ", ComparisonSourceType.Test); - var context = new DiffContext(controls[0].Node.GetRoot() as IElement, tests[0].Node.GetRoot() as IElement); + [Fact(DisplayName = "When a control element contains the diff:match attribute, " + + "its value is expected to be a CSS selector string, that can be used to search " + + "the test node tree for a matching node")] + public void Test002() + { + var controls = ToSourceCollection(@"

          p:first-child"">

          ", ComparisonSourceType.Control); + var tests = ToSourceCollection("

          ", ComparisonSourceType.Test); + var context = new DiffContext(controls[0].Node.GetRoot() as IElement, tests[0].Node.GetRoot() as IElement); - var actual = CssSelectorElementMatcher.Match(context, controls, tests).ToList(); + var actual = CssSelectorElementMatcher.Match(context, controls, tests).ToList(); - actual.Count.ShouldBe(1); - actual[0].ShouldSatisfyAllConditions( - c => c.Control.Node.ShouldBe(controls[0].Node), - c => c.Test.Node.ShouldBe(tests[1].Node.FirstChild) - ); - } + actual.Count.ShouldBe(1); + actual[0].ShouldSatisfyAllConditions( + c => c.Control.Node.ShouldBe(controls[0].Node), + c => c.Test.Node.ShouldBe(tests[1].Node.FirstChild) + ); + } - [Fact(DisplayName = "When a diff:match css selector finds more than one element and exception is thrown")] - public void Test003() - { - var controls = ToSourceCollection(@"

          ", ComparisonSourceType.Control); - var tests = ToSourceCollection("

          ", ComparisonSourceType.Test); - var context = new DiffContext(controls[0].Node.GetRoot() as IElement, tests[0].Node.GetRoot() as IElement); + [Fact(DisplayName = "When a diff:match css selector finds more than one element and exception is thrown")] + public void Test003() + { + var controls = ToSourceCollection(@"

          ", ComparisonSourceType.Control); + var tests = ToSourceCollection("

          ", ComparisonSourceType.Test); + var context = new DiffContext(controls[0].Node.GetRoot() as IElement, tests[0].Node.GetRoot() as IElement); - Should.Throw(() => CssSelectorElementMatcher.Match(context, controls, tests).ToList()); - } + Should.Throw(() => CssSelectorElementMatcher.Match(context, controls, tests).ToList()); + } - [Fact(DisplayName = "When a diff:match css selector finds zero element no matches are created")] - public void Test004() - { - var controls = ToSourceCollection(@"

          ", ComparisonSourceType.Control); - var tests = ToSourceCollection("

          ", ComparisonSourceType.Test); - var context = new DiffContext(controls[0].Node.GetRoot() as IElement, tests[0].Node.GetRoot() as IElement); + [Fact(DisplayName = "When a diff:match css selector finds zero element no matches are created")] + public void Test004() + { + var controls = ToSourceCollection(@"

          ", ComparisonSourceType.Control); + var tests = ToSourceCollection("

          ", ComparisonSourceType.Test); + var context = new DiffContext(controls[0].Node.GetRoot() as IElement, tests[0].Node.GetRoot() as IElement); - var actual = CssSelectorElementMatcher.Match(context, controls, tests).ToList(); + var actual = CssSelectorElementMatcher.Match(context, controls, tests).ToList(); - actual.ShouldBeEmpty(); - } + actual.ShouldBeEmpty(); + } - [Fact(DisplayName = "The matcher does not try to match control elements that are marked as matched already")] - public void Test005() - { - var controls = ToSourceCollection(@"

          ", ComparisonSourceType.Control); - var tests = ToSourceCollection("

          ", ComparisonSourceType.Test); - var context = new DiffContext(controls[0].Node.GetRoot() as IElement, tests[0].Node.GetRoot() as IElement); - controls.MarkAsMatched(controls[0]); + [Fact(DisplayName = "The matcher does not try to match control elements that are marked as matched already")] + public void Test005() + { + var controls = ToSourceCollection(@"

          ", ComparisonSourceType.Control); + var tests = ToSourceCollection("

          ", ComparisonSourceType.Test); + var context = new DiffContext(controls[0].Node.GetRoot() as IElement, tests[0].Node.GetRoot() as IElement); + controls.MarkAsMatched(controls[0]); - var actual = CssSelectorElementMatcher.Match(context, controls, tests).ToList(); + var actual = CssSelectorElementMatcher.Match(context, controls, tests).ToList(); - actual.ShouldBeEmpty(); - } + actual.ShouldBeEmpty(); } } diff --git a/src/AngleSharp.Diffing.Tests/Strategies/ElementStrategies/IgnoreAttributesElementComparerTest.cs b/src/AngleSharp.Diffing.Tests/Strategies/ElementStrategies/IgnoreAttributesElementComparerTest.cs index c1883ec..67bcd96 100644 --- a/src/AngleSharp.Diffing.Tests/Strategies/ElementStrategies/IgnoreAttributesElementComparerTest.cs +++ b/src/AngleSharp.Diffing.Tests/Strategies/ElementStrategies/IgnoreAttributesElementComparerTest.cs @@ -1,44 +1,35 @@ -using System.Linq; +namespace AngleSharp.Diffing.Strategies.ElementStrategies; -using AngleSharp.Diffing.Core; - -using Shouldly; - -using Xunit; - -namespace AngleSharp.Diffing.Strategies.ElementStrategies +public class IgnoreAttributesElementComparerTest : DiffingTestBase { - public class IgnoreAttributesElementComparerTest : DiffingTestBase + public IgnoreAttributesElementComparerTest(DiffingTestFixture fixture) : base(fixture) { - public IgnoreAttributesElementComparerTest(DiffingTestFixture fixture) : base(fixture) - { - } + } - [Theory(DisplayName = "When a control element does not contain the 'diff:ignoreAttributes' attribute or it is 'diff:ignoreAttributes=false', the current decision is returned")] - [InlineData(@"

          ")] - [InlineData(@"

          ")] - [InlineData(@"

          ")] - [InlineData(@"

          ")] - public void Test001(string controlHtml) - { - var comparison = ToComparison(controlHtml, "

          "); + [Theory(DisplayName = "When a control element does not contain the 'diff:ignoreAttributes' attribute or it is 'diff:ignoreAttributes=false', the current decision is returned")] + [InlineData(@"

          ")] + [InlineData(@"

          ")] + [InlineData(@"

          ")] + [InlineData(@"

          ")] + public void Test001(string controlHtml) + { + var comparison = ToComparison(controlHtml, "

          "); - IgnoreAttributesElementComparer.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); - IgnoreAttributesElementComparer.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); - IgnoreAttributesElementComparer.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); - } + IgnoreAttributesElementComparer.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); + IgnoreAttributesElementComparer.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); + IgnoreAttributesElementComparer.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); + } - [Theory(DisplayName = "When a control element has 'diff:ignoreAttributes' attribute, CompareResult.SkipAttributes flag is returned")] - [InlineData(@"

          ")] - [InlineData(@"

          ")] - [InlineData(@"

          ")] - [InlineData(@"

          ")] - public void Test002(string controlHtml) - { - var comparison = ToComparison(controlHtml, "

          "); + [Theory(DisplayName = "When a control element has 'diff:ignoreAttributes' attribute, CompareResult.SkipAttributes flag is returned")] + [InlineData(@"

          ")] + [InlineData(@"

          ")] + [InlineData(@"

          ")] + [InlineData(@"

          ")] + public void Test002(string controlHtml) + { + var comparison = ToComparison(controlHtml, "

          "); - IgnoreAttributesElementComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.SkipAttributes); - IgnoreAttributesElementComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.SkipAttributes); - } + IgnoreAttributesElementComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.SkipAttributes); + IgnoreAttributesElementComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.SkipAttributes); } } diff --git a/src/AngleSharp.Diffing.Tests/Strategies/ElementStrategies/IgnoreChildrenElementComparerTest.cs b/src/AngleSharp.Diffing.Tests/Strategies/ElementStrategies/IgnoreChildrenElementComparerTest.cs index ab8149c..0fa89b9 100644 --- a/src/AngleSharp.Diffing.Tests/Strategies/ElementStrategies/IgnoreChildrenElementComparerTest.cs +++ b/src/AngleSharp.Diffing.Tests/Strategies/ElementStrategies/IgnoreChildrenElementComparerTest.cs @@ -1,44 +1,35 @@ -using System.Linq; +namespace AngleSharp.Diffing.Strategies.ElementStrategies; -using AngleSharp.Diffing.Core; - -using Shouldly; - -using Xunit; - -namespace AngleSharp.Diffing.Strategies.ElementStrategies +public class IgnoreChildrenElementComparerTest : DiffingTestBase { - public class IgnoreChildrenElementComparerTest : DiffingTestBase + public IgnoreChildrenElementComparerTest(DiffingTestFixture fixture) : base(fixture) { - public IgnoreChildrenElementComparerTest(DiffingTestFixture fixture) : base(fixture) - { - } + } - [Theory(DisplayName = "When a control element does not contain the 'diff:ignoreChildren' attribute or it is 'diff:ignoreChildren=false', the current decision is returned")] - [InlineData(@"

          ")] - [InlineData(@"

          ")] - [InlineData(@"

          ")] - [InlineData(@"

          ")] - public void Test001(string controlHtml) - { - var comparison = ToComparison(controlHtml, "

          "); + [Theory(DisplayName = "When a control element does not contain the 'diff:ignoreChildren' attribute or it is 'diff:ignoreChildren=false', the current decision is returned")] + [InlineData(@"

          ")] + [InlineData(@"

          ")] + [InlineData(@"

          ")] + [InlineData(@"

          ")] + public void Test001(string controlHtml) + { + var comparison = ToComparison(controlHtml, "

          "); - IgnoreChildrenElementComparer.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); - IgnoreChildrenElementComparer.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); - IgnoreChildrenElementComparer.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); - } + IgnoreChildrenElementComparer.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); + IgnoreChildrenElementComparer.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); + IgnoreChildrenElementComparer.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); + } - [Theory(DisplayName = "When a control element has 'diff:ignoreChildren' attribute, CompareResult.SkipChildren flag is returned")] - [InlineData(@"

          ")] - [InlineData(@"

          ")] - [InlineData(@"

          ")] - [InlineData(@"

          ")] - public void Test002(string controlHtml) - { - var comparison = ToComparison(controlHtml, "

          "); + [Theory(DisplayName = "When a control element has 'diff:ignoreChildren' attribute, CompareResult.SkipChildren flag is returned")] + [InlineData(@"

          ")] + [InlineData(@"

          ")] + [InlineData(@"

          ")] + [InlineData(@"

          ")] + public void Test002(string controlHtml) + { + var comparison = ToComparison(controlHtml, "

          "); - IgnoreChildrenElementComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.SkipChildren); - IgnoreChildrenElementComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.SkipChildren); - } + IgnoreChildrenElementComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.SkipChildren); + IgnoreChildrenElementComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.SkipChildren); } } diff --git a/src/AngleSharp.Diffing.Tests/Strategies/ElementStrategies/IgnoreElementComparerTest.cs b/src/AngleSharp.Diffing.Tests/Strategies/ElementStrategies/IgnoreElementComparerTest.cs index 03e12a0..959f056 100644 --- a/src/AngleSharp.Diffing.Tests/Strategies/ElementStrategies/IgnoreElementComparerTest.cs +++ b/src/AngleSharp.Diffing.Tests/Strategies/ElementStrategies/IgnoreElementComparerTest.cs @@ -1,42 +1,35 @@ -using AngleSharp.Diffing.Core; +namespace AngleSharp.Diffing.Strategies.ElementStrategies; -using Shouldly; - -using Xunit; - -namespace AngleSharp.Diffing.Strategies.ElementStrategies +public class IgnoreElementComparerTest : DiffingTestBase { - public class IgnoreElementComparerTest : DiffingTestBase + public IgnoreElementComparerTest(DiffingTestFixture fixture) : base(fixture) { - public IgnoreElementComparerTest(DiffingTestFixture fixture) : base(fixture) - { - } + } - [Theory(DisplayName = "When a control element does not contain the 'diff:ignore' attribute or it is 'diff:ignore=false', the current decision is returned")] - [InlineData(@"

          ")] - [InlineData(@"

          ")] - [InlineData(@"

          ")] - [InlineData(@"

          ")] - public void Test001(string controlHtml) - { - var comparison = ToComparison(controlHtml, "

          "); + [Theory(DisplayName = "When a control element does not contain the 'diff:ignore' attribute or it is 'diff:ignore=false', the current decision is returned")] + [InlineData(@"

          ")] + [InlineData(@"

          ")] + [InlineData(@"

          ")] + [InlineData(@"

          ")] + public void Test001(string controlHtml) + { + var comparison = ToComparison(controlHtml, "

          "); - IgnoreElementComparer.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); - IgnoreElementComparer.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); - IgnoreElementComparer.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); - } + IgnoreElementComparer.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); + IgnoreElementComparer.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); + IgnoreElementComparer.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); + } - [Theory(DisplayName = "When a control element has 'diff:ignore' attribute, SameAndBreak is returned")] - [InlineData(@"

          ")] - [InlineData(@"

          ")] - [InlineData(@"

          ")] - [InlineData(@"

          ")] - public void Test002(string controlHtml) - { - var comparison = ToComparison(controlHtml, "

          "); + [Theory(DisplayName = "When a control element has 'diff:ignore' attribute, SameAndBreak is returned")] + [InlineData(@"

          ")] + [InlineData(@"

          ")] + [InlineData(@"

          ")] + [InlineData(@"

          ")] + public void Test002(string controlHtml) + { + var comparison = ToComparison(controlHtml, "

          "); - IgnoreElementComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Skip); - IgnoreElementComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Skip); - } + IgnoreElementComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Skip); + IgnoreElementComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Skip); } } diff --git a/src/AngleSharp.Diffing.Tests/Strategies/NodeStrategies/ForwardSearchingNodeMatcherTest.cs b/src/AngleSharp.Diffing.Tests/Strategies/NodeStrategies/ForwardSearchingNodeMatcherTest.cs index 5cc6626..5722471 100644 --- a/src/AngleSharp.Diffing.Tests/Strategies/NodeStrategies/ForwardSearchingNodeMatcherTest.cs +++ b/src/AngleSharp.Diffing.Tests/Strategies/NodeStrategies/ForwardSearchingNodeMatcherTest.cs @@ -1,122 +1,112 @@ -using System.Linq; +namespace AngleSharp.Diffing.Strategies.NodeStrategies; -using AngleSharp.Diffing.Core; -using AngleSharp.Dom; +public class ForwardSearchingNodeMatcherTest : DiffingTestBase +{ + public ForwardSearchingNodeMatcherTest(DiffingTestFixture fixture) : base(fixture) + { + } -using Shouldly; + [Theory(DisplayName = "The matcher matches two nodes with of the same type")] + [InlineData("textnode", "textnode")] + [InlineData("

          ", "

          ")] + [InlineData("", "")] + [InlineData("", "")] + [InlineData("", "")] + [InlineData("", "")] + public void Test001(string controlHtml, string testHtml) + { + var controls = ToSourceCollection(controlHtml, ComparisonSourceType.Control); + var tests = ToSourceCollection(testHtml, ComparisonSourceType.Test); -using Xunit; + var actual = ForwardSearchingNodeMatcher.Match(DummyContext, controls, tests).ToList(); -namespace AngleSharp.Diffing.Strategies.NodeStrategies -{ - public class ForwardSearchingNodeMatcherTest : DiffingTestBase + actual.Count.ShouldBe(1); + actual.ShouldAllBe((c, idx) => c.Control == controls[idx] && c.Test == tests[idx]); + } + + [Theory(DisplayName = "The matcher matches two nodes of the same type skipping excluded")] + [InlineData("asdf

          Hello world

          asdf

          Hello world

          ", "asdf

          Hello world

          asdf

          Hello world

          ")] + public void Test0011(string controlHtml, string testHtml) + { + var controls = ToSourceCollection(controlHtml, ComparisonSourceType.Control); + var tests = ToSourceCollection(testHtml, ComparisonSourceType.Test); + controls.Remove((in ComparisonSource x) => x.Node is IElement ? FilterDecision.Keep : FilterDecision.Exclude); + tests.Remove((in ComparisonSource x) => x.Node is IElement ? FilterDecision.Keep : FilterDecision.Exclude); + + var actual = ForwardSearchingNodeMatcher.Match(DummyContext, controls, tests).ToList(); + + actual.Count.ShouldBe(2); + actual.ShouldAllBe(c => c.Control == controls[c.Control.Index] && c.Test == tests[c.Test.Index]); + } + + [Theory(DisplayName = "The matcher does not matches two nodes with the different node names")] + [InlineData("textnode", "")] + [InlineData("textnode", "

          ")] + [InlineData("", "textnode")] + [InlineData("", "

          ")] + [InlineData("

          ", "textnode")] + [InlineData("

          ", "")] + public void Test002(string controlHtml, string testHtml) + { + var controls = ToSourceCollection(controlHtml, ComparisonSourceType.Control); + var tests = ToSourceCollection(testHtml, ComparisonSourceType.Test); + + var actual = ForwardSearchingNodeMatcher.Match(DummyContext, controls, tests).ToList(); + + actual.ShouldBeEmpty(); + } + + [Fact(DisplayName = "The matcher searches the test nodes for matches for each control node, " + + "starting after the last matched test node")] + public void Test003() + { + var controls = ToSourceCollection("

          ", ComparisonSourceType.Control); + var tests = ToSourceCollection("

          ", ComparisonSourceType.Test); + + var actual = ForwardSearchingNodeMatcher.Match(DummyContext, controls, tests).ToList(); + + actual.Count.ShouldBe(2); + actual[0].ShouldSatisfyAllConditions( + c => c.Control.Index.ShouldBe(0), + c => c.Test.Index.ShouldBe(1) + ); + actual[1].ShouldSatisfyAllConditions( + c => c.Control.Index.ShouldBe(1), + c => c.Test.Index.ShouldBe(2) + ); + } + + [Fact(DisplayName = "When the matcher does not find a match for a control node, " + + "it continues with the next control node and searches for a test node, " + + "starting after the last matched test node")] + public void Test004() + { + var controls = ToSourceCollection("
          ", ComparisonSourceType.Control); + var tests = ToSourceCollection("
          ", ComparisonSourceType.Test); + + var actual = ForwardSearchingNodeMatcher.Match(DummyContext, controls, tests).ToList(); + + actual.Count.ShouldBe(1); + actual[0].ShouldSatisfyAllConditions( + c => c.Control.Index.ShouldBe(1), + c => c.Test.Index.ShouldBe(0) + ); + } + + [Fact(DisplayName = "When a test node has previous been matched by another matcher, it is not matched again")] + public void Test005() { - public ForwardSearchingNodeMatcherTest(DiffingTestFixture fixture) : base(fixture) - { - } - - [Theory(DisplayName = "The matcher matches two nodes with of the same type")] - [InlineData("textnode", "textnode")] - [InlineData("

          ", "

          ")] - [InlineData("", "")] - [InlineData("", "")] - [InlineData("", "")] - [InlineData("", "")] - public void Test001(string controlHtml, string testHtml) - { - var controls = ToSourceCollection(controlHtml, ComparisonSourceType.Control); - var tests = ToSourceCollection(testHtml, ComparisonSourceType.Test); - - var actual = ForwardSearchingNodeMatcher.Match(DummyContext, controls, tests).ToList(); - - actual.Count.ShouldBe(1); - actual.ShouldAllBe((c, idx) => c.Control == controls[idx] && c.Test == tests[idx]); - } - - [Theory(DisplayName = "The matcher matches two nodes of the same type skipping excluded")] - [InlineData("asdf

          Hello world

          asdf

          Hello world

          ", "asdf

          Hello world

          asdf

          Hello world

          ")] - public void Test0011(string controlHtml, string testHtml) - { - var controls = ToSourceCollection(controlHtml, ComparisonSourceType.Control); - var tests = ToSourceCollection(testHtml, ComparisonSourceType.Test); - controls.Remove((in ComparisonSource x) => x.Node is IElement ? FilterDecision.Keep : FilterDecision.Exclude); - tests.Remove((in ComparisonSource x) => x.Node is IElement ? FilterDecision.Keep : FilterDecision.Exclude); - - var actual = ForwardSearchingNodeMatcher.Match(DummyContext, controls, tests).ToList(); - - actual.Count.ShouldBe(2); - actual.ShouldAllBe(c => c.Control == controls[c.Control.Index] && c.Test == tests[c.Test.Index]); - } - - [Theory(DisplayName = "The matcher does not matches two nodes with the different node names")] - [InlineData("textnode", "")] - [InlineData("textnode", "

          ")] - [InlineData("", "textnode")] - [InlineData("", "

          ")] - [InlineData("

          ", "textnode")] - [InlineData("

          ", "")] - public void Test002(string controlHtml, string testHtml) - { - var controls = ToSourceCollection(controlHtml, ComparisonSourceType.Control); - var tests = ToSourceCollection(testHtml, ComparisonSourceType.Test); - - var actual = ForwardSearchingNodeMatcher.Match(DummyContext, controls, tests).ToList(); - - actual.ShouldBeEmpty(); - } - - [Fact(DisplayName = "The matcher searches the test nodes for matches for each control node, " + - "starting after the last matched test node")] - public void Test003() - { - var controls = ToSourceCollection("

          ", ComparisonSourceType.Control); - var tests = ToSourceCollection("

          ", ComparisonSourceType.Test); - - var actual = ForwardSearchingNodeMatcher.Match(DummyContext, controls, tests).ToList(); - - actual.Count.ShouldBe(2); - actual[0].ShouldSatisfyAllConditions( - c => c.Control.Index.ShouldBe(0), - c => c.Test.Index.ShouldBe(1) - ); - actual[1].ShouldSatisfyAllConditions( - c => c.Control.Index.ShouldBe(1), - c => c.Test.Index.ShouldBe(2) - ); - } - - [Fact(DisplayName = "When the matcher does not find a match for a control node, " + - "it continues with the next control node and searches for a test node, " + - "starting after the last matched test node")] - public void Test004() - { - var controls = ToSourceCollection("
          ", ComparisonSourceType.Control); - var tests = ToSourceCollection("
          ", ComparisonSourceType.Test); - - var actual = ForwardSearchingNodeMatcher.Match(DummyContext, controls, tests).ToList(); - - actual.Count.ShouldBe(1); - actual[0].ShouldSatisfyAllConditions( - c => c.Control.Index.ShouldBe(1), - c => c.Test.Index.ShouldBe(0) - ); - } - - [Fact(DisplayName = "When a test node has previous been matched by another matcher, it is not matched again")] - public void Test005() - { - var controls = ToSourceCollection("

          text", ComparisonSourceType.Control); - var tests = ToSourceCollection("

          text", ComparisonSourceType.Test); - controls.MarkAsMatched(controls[0]); // mark

          as matched - tests.MarkAsMatched(tests[2]); // mark text as matched - - var actual = ForwardSearchingNodeMatcher.Match(DummyContext, controls, tests).ToList(); - - actual.Count.ShouldBe(1); - actual[0].ShouldSatisfyAllConditions( - c => c.Control.Index.ShouldBe(2), - c => c.Test.Index.ShouldBe(0) - ); - } + var controls = ToSourceCollection("

          text", ComparisonSourceType.Control); + var tests = ToSourceCollection("

          text", ComparisonSourceType.Test); + controls.MarkAsMatched(controls[0]); // mark

          as matched + tests.MarkAsMatched(tests[2]); // mark text as matched + + var actual = ForwardSearchingNodeMatcher.Match(DummyContext, controls, tests).ToList(); + + actual.Count.ShouldBe(1); + actual[0].ShouldSatisfyAllConditions( + c => c.Control.Index.ShouldBe(2), + c => c.Test.Index.ShouldBe(0) + ); } } diff --git a/src/AngleSharp.Diffing.Tests/Strategies/NodeStrategies/OneToOneNodeMatcherTest.cs b/src/AngleSharp.Diffing.Tests/Strategies/NodeStrategies/OneToOneNodeMatcherTest.cs index 2dc8148..25a8eb3 100644 --- a/src/AngleSharp.Diffing.Tests/Strategies/NodeStrategies/OneToOneNodeMatcherTest.cs +++ b/src/AngleSharp.Diffing.Tests/Strategies/NodeStrategies/OneToOneNodeMatcherTest.cs @@ -1,101 +1,92 @@ -using System.Linq; +namespace AngleSharp.Diffing.Strategies.NodeStrategies; -using AngleSharp.Diffing.Core; - -using Shouldly; - -using Xunit; - -namespace AngleSharp.Diffing.Strategies.NodeStrategies +public class OneToOneNodeMatcherTest : DiffingTestBase { - public class OneToOneNodeMatcherTest : DiffingTestBase + public OneToOneNodeMatcherTest(DiffingTestFixture fixture) : base(fixture) { - public OneToOneNodeMatcherTest(DiffingTestFixture fixture) : base(fixture) - { - } - - [Fact(DisplayName = "With two equal length node lists, " + - "all control and test nodes are matched based on the order they are in the lists")] - public void Test001() - { - var controls = ToSourceCollection("

          text", ComparisonSourceType.Control); - var tests = ToSourceCollection("

          text", ComparisonSourceType.Test); - - var actual = OneToOneNodeMatcher.Match(DummyContext, controls, tests).ToList(); - - actual.Count.ShouldBe(3); - actual[0].ShouldSatisfyAllConditions( - c => c.Control.ShouldBe(controls[0]), - c => c.Test.ShouldBe(tests[0]) - ); - actual[1].ShouldSatisfyAllConditions( - c => c.Control.ShouldBe(controls[1]), - c => c.Test.ShouldBe(tests[1]) - ); - actual[2].ShouldSatisfyAllConditions( - c => c.Control.ShouldBe(controls[2]), - c => c.Test.ShouldBe(tests[2]) - ); - } - - [Theory(DisplayName = "With two unequal length node lists, " + - "as many control and test nodes are matched as the shortest list allow, " + - "based on the order they are in the lists")] - [InlineData("

          text", "

          text", 2)] - [InlineData("

          text", "

          text", 2)] - [InlineData("

          ", "

          ", 1)] - [InlineData("

          ", "

          ", 1)] - [InlineData("

          ", "", 0)] - [InlineData("", "

          ", 0)] - public void Test002(string controlHtml, string testHtml, int matchCount) - { - var controls = ToSourceCollection(controlHtml, ComparisonSourceType.Control); - var tests = ToSourceCollection(testHtml, ComparisonSourceType.Test); - - var actual = OneToOneNodeMatcher.Match(DummyContext, controls, tests).ToList(); - - actual.Count.ShouldBe(matchCount); - actual.ShouldAllBe((c, idx) => c.Control == controls[idx] && c.Test == tests[idx]); - } + } - [Fact(DisplayName = "When a control node has previous been matched, it is not matched again")] - public void Test003() - { - var controls = ToSourceCollection("

          text", ComparisonSourceType.Control); - var tests = ToSourceCollection("

          text", ComparisonSourceType.Test); - controls.MarkAsMatched(controls[1]); + [Fact(DisplayName = "With two equal length node lists, " + + "all control and test nodes are matched based on the order they are in the lists")] + public void Test001() + { + var controls = ToSourceCollection("

          text", ComparisonSourceType.Control); + var tests = ToSourceCollection("

          text", ComparisonSourceType.Test); + + var actual = OneToOneNodeMatcher.Match(DummyContext, controls, tests).ToList(); + + actual.Count.ShouldBe(3); + actual[0].ShouldSatisfyAllConditions( + c => c.Control.ShouldBe(controls[0]), + c => c.Test.ShouldBe(tests[0]) + ); + actual[1].ShouldSatisfyAllConditions( + c => c.Control.ShouldBe(controls[1]), + c => c.Test.ShouldBe(tests[1]) + ); + actual[2].ShouldSatisfyAllConditions( + c => c.Control.ShouldBe(controls[2]), + c => c.Test.ShouldBe(tests[2]) + ); + } - var actual = OneToOneNodeMatcher.Match(DummyContext, controls, tests).ToList(); + [Theory(DisplayName = "With two unequal length node lists, " + + "as many control and test nodes are matched as the shortest list allow, " + + "based on the order they are in the lists")] + [InlineData("

          text", "

          text", 2)] + [InlineData("

          text", "

          text", 2)] + [InlineData("

          ", "

          ", 1)] + [InlineData("

          ", "

          ", 1)] + [InlineData("

          ", "", 0)] + [InlineData("", "

          ", 0)] + public void Test002(string controlHtml, string testHtml, int matchCount) + { + var controls = ToSourceCollection(controlHtml, ComparisonSourceType.Control); + var tests = ToSourceCollection(testHtml, ComparisonSourceType.Test); - actual.Count.ShouldBe(2); - actual[0].ShouldSatisfyAllConditions( - c => c.Control.ShouldBe(controls[0]), - c => c.Test.ShouldBe(tests[0]) - ); - actual[1].ShouldSatisfyAllConditions( - c => c.Control.ShouldBe(controls[2]), - c => c.Test.ShouldBe(tests[1]) - ); - } + var actual = OneToOneNodeMatcher.Match(DummyContext, controls, tests).ToList(); - [Fact(DisplayName = "When a test node has previous been matched by another matcher, it is not matched again")] - public void Test004() - { - var controls = ToSourceCollection("

          text", ComparisonSourceType.Control); - var tests = ToSourceCollection("

          text", ComparisonSourceType.Test); - tests.MarkAsMatched(tests[1]); + actual.Count.ShouldBe(matchCount); + actual.ShouldAllBe((c, idx) => c.Control == controls[idx] && c.Test == tests[idx]); + } - var actual = OneToOneNodeMatcher.Match(DummyContext, controls, tests).ToList(); + [Fact(DisplayName = "When a control node has previous been matched, it is not matched again")] + public void Test003() + { + var controls = ToSourceCollection("

          text", ComparisonSourceType.Control); + var tests = ToSourceCollection("

          text", ComparisonSourceType.Test); + controls.MarkAsMatched(controls[1]); + + var actual = OneToOneNodeMatcher.Match(DummyContext, controls, tests).ToList(); + + actual.Count.ShouldBe(2); + actual[0].ShouldSatisfyAllConditions( + c => c.Control.ShouldBe(controls[0]), + c => c.Test.ShouldBe(tests[0]) + ); + actual[1].ShouldSatisfyAllConditions( + c => c.Control.ShouldBe(controls[2]), + c => c.Test.ShouldBe(tests[1]) + ); + } - actual.Count.ShouldBe(2); - actual[0].ShouldSatisfyAllConditions( - c => c.Control.ShouldBe(controls[0]), - c => c.Test.ShouldBe(tests[0]) - ); - actual[1].ShouldSatisfyAllConditions( - c => c.Control.ShouldBe(controls[1]), - c => c.Test.ShouldBe(tests[2]) - ); - } + [Fact(DisplayName = "When a test node has previous been matched by another matcher, it is not matched again")] + public void Test004() + { + var controls = ToSourceCollection("

          text", ComparisonSourceType.Control); + var tests = ToSourceCollection("

          text", ComparisonSourceType.Test); + tests.MarkAsMatched(tests[1]); + + var actual = OneToOneNodeMatcher.Match(DummyContext, controls, tests).ToList(); + + actual.Count.ShouldBe(2); + actual[0].ShouldSatisfyAllConditions( + c => c.Control.ShouldBe(controls[0]), + c => c.Test.ShouldBe(tests[0]) + ); + actual[1].ShouldSatisfyAllConditions( + c => c.Control.ShouldBe(controls[1]), + c => c.Test.ShouldBe(tests[2]) + ); } } diff --git a/src/AngleSharp.Diffing.Tests/Strategies/TextNodeStrategies/StyleSheetTextNodeComparerTest.cs b/src/AngleSharp.Diffing.Tests/Strategies/TextNodeStrategies/StyleSheetTextNodeComparerTest.cs index 981ac04..e37e669 100644 --- a/src/AngleSharp.Diffing.Tests/Strategies/TextNodeStrategies/StyleSheetTextNodeComparerTest.cs +++ b/src/AngleSharp.Diffing.Tests/Strategies/TextNodeStrategies/StyleSheetTextNodeComparerTest.cs @@ -1,66 +1,59 @@ -using AngleSharp.Diffing.Core; +namespace AngleSharp.Diffing.Strategies.TextNodeStrategies; -using Shouldly; - -using Xunit; - -namespace AngleSharp.Diffing.Strategies.TextNodeStrategies +public class StyleSheetTextNodeComparerTest : TextNodeTestBase { - public class StyleSheetTextNodeComparerTest : TextNodeTestBase + public StyleSheetTextNodeComparerTest(DiffingTestFixture fixture) : base(fixture) { - public StyleSheetTextNodeComparerTest(DiffingTestFixture fixture) : base(fixture) - { - } + } - [Fact(DisplayName = "When input node is not a IText node, comparer does not run nor change the current decision")] - public void Test000() - { - var comparison = ToComparison("

          ", "

          "); + [Fact(DisplayName = "When input node is not a IText node, comparer does not run nor change the current decision")] + public void Test000() + { + var comparison = ToComparison("

          ", "

          "); - StyleSheetTextNodeComparer.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); - StyleSheetTextNodeComparer.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); - StyleSheetTextNodeComparer.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); - } + StyleSheetTextNodeComparer.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); + StyleSheetTextNodeComparer.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); + StyleSheetTextNodeComparer.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); + } - [Fact(DisplayName = "When input node is a IText node inside an element that is NOT a style tag, comparer does not run nor change the current decision")] - public void Test0001() - { - var comparison = ToComparison("

          h1{background:#000;}

          ", "

          h1{background:#000;}

          "); + [Fact(DisplayName = "When input node is a IText node inside an element that is NOT a style tag, comparer does not run nor change the current decision")] + public void Test0001() + { + var comparison = ToComparison("

          h1{background:#000;}

          ", "

          h1{background:#000;}

          "); - StyleSheetTextNodeComparer.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); - StyleSheetTextNodeComparer.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); - StyleSheetTextNodeComparer.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); - } + StyleSheetTextNodeComparer.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); + StyleSheetTextNodeComparer.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); + StyleSheetTextNodeComparer.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); + } - [Fact(DisplayName = "The comparer responds with Different when style information is different")] - public void Test001() - { - var comparison = ToStyleComparison(@"h1{background:#000;}", @"h1{color:#000;}"); + [Fact(DisplayName = "The comparer responds with Different when style information is different")] + public void Test001() + { + var comparison = ToStyleComparison(@"h1{background:#000;}", @"h1{color:#000;}"); - StyleSheetTextNodeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); - } + StyleSheetTextNodeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); + } - [Theory(DisplayName = "The comparer ignores insignificant whitespace")] - [InlineData(" ")] - [InlineData(" ")] - [InlineData("\t")] - [InlineData("\n")] - [InlineData("\n\r")] - public void Test003(string whitespace) - { - var comparison = ToStyleComparison($@"h1{whitespace}{{{whitespace}color:{whitespace}#000;{whitespace}}}", @"h1{color:#000;}"); + [Theory(DisplayName = "The comparer ignores insignificant whitespace")] + [InlineData(" ")] + [InlineData(" ")] + [InlineData("\t")] + [InlineData("\n")] + [InlineData("\n\r")] + public void Test003(string whitespace) + { + var comparison = ToStyleComparison($@"h1{whitespace}{{{whitespace}color:{whitespace}#000;{whitespace}}}", @"h1{color:#000;}"); - StyleSheetTextNodeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } + StyleSheetTextNodeComparer.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } - private Comparison ToStyleComparison(string controlStyleText, string testStyleText) - { - var controlStyle = ToComparisonSource($@""); - var controlSource = new ComparisonSource(controlStyle.Node.FirstChild, 0, controlStyle.Path, ComparisonSourceType.Control); - var testStyle = ToComparisonSource($@""); - var testSource = new ComparisonSource(testStyle.Node.FirstChild, 0, testStyle.Path, ComparisonSourceType.Test); - return new Comparison(controlSource, testSource); - } + private Comparison ToStyleComparison(string controlStyleText, string testStyleText) + { + var controlStyle = ToComparisonSource($@""); + var controlSource = new ComparisonSource(controlStyle.Node.FirstChild, 0, controlStyle.Path, ComparisonSourceType.Control); + var testStyle = ToComparisonSource($@""); + var testSource = new ComparisonSource(testStyle.Node.FirstChild, 0, testStyle.Path, ComparisonSourceType.Test); + return new Comparison(controlSource, testSource); } } diff --git a/src/AngleSharp.Diffing.Tests/Strategies/TextNodeStrategies/TextNodeComparerTest.cs b/src/AngleSharp.Diffing.Tests/Strategies/TextNodeStrategies/TextNodeComparerTest.cs index 575a487..85d6e2b 100644 --- a/src/AngleSharp.Diffing.Tests/Strategies/TextNodeStrategies/TextNodeComparerTest.cs +++ b/src/AngleSharp.Diffing.Tests/Strategies/TextNodeStrategies/TextNodeComparerTest.cs @@ -1,239 +1,232 @@ -using AngleSharp.Diffing.Core; +namespace AngleSharp.Diffing.Strategies.TextNodeStrategies; -using Shouldly; +public class TextNodeComparerTest : TextNodeTestBase +{ + public TextNodeComparerTest(DiffingTestFixture fixture) : base(fixture) + { + } + + [Fact(DisplayName = "When input node is not a IText node, comparer does not run nor change the current decision")] + public void Test2() + { + var comparison = ToComparison("

          ", "

          "); + var sut = new TextNodeComparer(); -using Xunit; + sut.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); + sut.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); + sut.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); + } -namespace AngleSharp.Diffing.Strategies.TextNodeStrategies -{ - public class TextNodeComparerTest : TextNodeTestBase - { - public TextNodeComparerTest(DiffingTestFixture fixture) : base(fixture) - { - } - - [Fact(DisplayName = "When input node is not a IText node, comparer does not run nor change the current decision")] - public void Test2() - { - var comparison = ToComparison("

          ", "

          "); - var sut = new TextNodeComparer(); - - sut.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); - sut.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); - sut.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); - } - - [Theory(DisplayName = "When option is Preserve or RemoveWhitespaceNodes, comparer does not run nor change the current decision")] - [InlineData(WhitespaceOption.Preserve)] - [InlineData(WhitespaceOption.RemoveWhitespaceNodes)] - public void Test5(WhitespaceOption whitespaceOption) - { - var comparison = ToComparison("hello world", " hello world "); - var sut = new TextNodeComparer(whitespaceOption); - - sut.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); - sut.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); - sut.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); - } - - [Fact(DisplayName = "When option is Normalize and current decision is Same or Skip, compare uses the current decision")] - public void Test55() - { - var comparison = new Comparison(); - var sut = new TextNodeComparer(WhitespaceOption.Normalize); - - sut.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); - sut.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); - } - - [Theory(DisplayName = "When option is Normalize, any whitespace before and after a text node is removed before comparison")] - [MemberData(nameof(WhitespaceCharStrings))] - public void Test7(string whitespace) - { - var sut = new TextNodeComparer(WhitespaceOption.Normalize); - var normalText = "text"; - var whitespaceText = $"{whitespace} text {whitespace}"; - var c1 = ToComparison(normalText, normalText); - var c2 = ToComparison(normalText, whitespaceText); - var c3 = ToComparison(whitespaceText, normalText); - var c4 = ToComparison(whitespaceText, whitespaceText); - - sut.Compare(c1, CompareResult.Unknown).ShouldBe(CompareResult.Same); - sut.Compare(c2, CompareResult.Unknown).ShouldBe(CompareResult.Same); - sut.Compare(c3, CompareResult.Unknown).ShouldBe(CompareResult.Same); - sut.Compare(c4, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } - - [Theory(DisplayName = "When option is Normalize, any consecutive whitespace characters are collapsed into one before comparison")] - [MemberData(nameof(WhitespaceCharStrings))] - public void Test9(string whitespace) - { - var sut = new TextNodeComparer(WhitespaceOption.Normalize); - var normalText = "hello world"; - var whitespaceText = $" {whitespace} hello {whitespace} {whitespace} world {whitespace} "; - var c1 = ToComparison(normalText, normalText); - var c2 = ToComparison(normalText, whitespaceText); - var c3 = ToComparison(whitespaceText, normalText); - var c4 = ToComparison(whitespaceText, whitespaceText); - - sut.Compare(c1, CompareResult.Unknown).ShouldBe(CompareResult.Same); - sut.Compare(c2, CompareResult.Unknown).ShouldBe(CompareResult.Same); - sut.Compare(c3, CompareResult.Unknown).ShouldBe(CompareResult.Same); - sut.Compare(c4, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } - - [Theory(DisplayName = "When a parent node has a inline whitespace option, that overrides the global whitespace option")] - [InlineData(@"

          foo bar

          ", @"

          foo bar

          ")] - [InlineData(@"

          foo bar

          ", @"

          foo bar

          ")] - [InlineData(@"

          foo bar

          ", @"

          foo bar

          ")] - public void Test001(string controlHtml, string testHtml) - { - var sut = new TextNodeComparer(WhitespaceOption.Preserve); - var controlSource = new ComparisonSource(ToNode(controlHtml).FirstChild.FirstChild.FirstChild, 0, "dummypath", ComparisonSourceType.Control); - var testSource = new ComparisonSource(ToNode(testHtml).FirstChild.FirstChild.FirstChild, 0, "dummypath", ComparisonSourceType.Test); - var comparison = new Comparison(controlSource, testSource); - - sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } - - [Theory(DisplayName = "When whitespace option is Preserve or RemoveWhitespaceNodes, a string ordinal comparison is performed")] - [InlineData(WhitespaceOption.Preserve)] - [InlineData(WhitespaceOption.RemoveWhitespaceNodes)] - public void Test003(WhitespaceOption whitespaceOption) - { - var sut = new TextNodeComparer(whitespaceOption); - var comparison = ToComparison(" hello\n\nworld ", " hello\n\nworld "); - - sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } - - [Fact(DisplayName = "When IgnoreCase is true, a string ordinal ignore case comparison is performed")] - public void Test004() - { - var sut = new TextNodeComparer(ignoreCase: true); - var comparison = ToComparison("HELLO WoRlD", "hello world"); - - sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } - - [Theory(DisplayName = "When the parent element is
          , the is implicitly set to Preserve")]
          -        [InlineData("pre")]
          -        [InlineData("script")]
          -        [InlineData("style")]
          -        public void Test005(string tag)
          -        {
          -            var sut = new TextNodeComparer(WhitespaceOption.Normalize);
          -            var elm = ToComparisonSource($"<{tag}>foo   bar");
          -            var controlSource = new ComparisonSource(elm.Node.FirstChild, 0, elm.Path, ComparisonSourceType.Control);
          -            var testSource = ToComparisonSource("foo bar", ComparisonSourceType.Test);
          -            var comparison = new Comparison(controlSource, testSource);
          -
          -            sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different);
          -        }
          -
          -        [Theory(DisplayName = "When the parent element is 
           and the whitespace option is set " +
          -                              "inline to Normalize, the inline option is used instead of Preserve")]
          -        [InlineData("pre")]
          -        [InlineData("script")]
          -        [InlineData("style")]
          -        public void Test006(string tag)
          -        {
          -            var sut = new TextNodeComparer(WhitespaceOption.Normalize);
          -            var controlNode = ToNode($@"<{tag} diff:whitespace=""{nameof(WhitespaceOption.Normalize)}"">foo bar");
          -            var testNode = ToNode($@"<{tag}>  foo    bar   ");
          -            var controlSource = controlNode.FirstChild.ToComparisonSource(0, ComparisonSourceType.Control);
          -            var testSource = testNode.FirstChild.ToComparisonSource(0, ComparisonSourceType.Test);
          -            var comparison = new Comparison(controlSource, testSource);
          -
          -            sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same);
          -        }
          -
          -        [Theory(DisplayName = "When the parent element is 
           and the whitespace option is set " +
          -                      "inline to RemoveWhitespaceNodes, the inline option is used instead of Preserve")]
          -        [InlineData("pre")]
          -        [InlineData("script")]
          -        [InlineData("style")]
          -        public void Test007(string tag)
          -        {
          -            var sut = new TextNodeComparer(WhitespaceOption.Normalize);
          -            var controlNode = ToNode($@"<{tag} diff:whitespace=""{nameof(WhitespaceOption.RemoveWhitespaceNodes)}"">foo bar");
          -            var testNode = ToNode($@"<{tag}>  foo bar   ");
          -            var controlSource = controlNode.FirstChild.ToComparisonSource(0, ComparisonSourceType.Control);
          -            var testSource = testNode.FirstChild.ToComparisonSource(0, ComparisonSourceType.Test);
          -            var comparison = new Comparison(controlSource, testSource);
          -
          -            sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same);
          -        }
          -
          -        [Theory(DisplayName = "When IgnoreCase='true' inline attribute is present in a parent element, a string " +
          -                              "ordinal ignore case comparison is performed")]
          -        [InlineData(@"

          HELLO WoRlD

          ")] - [InlineData(@"

          HELLO WoRlD

          ")] - [InlineData(@"

          HELLO WoRlD

          ")] - public void Test008(string controlHtml) - { - var sut = new TextNodeComparer(ignoreCase: false); - var rootSource = ToComparisonSource(controlHtml); - var controlSource = new ComparisonSource(rootSource.Node.FirstChild.FirstChild.FirstChild, 0, rootSource.Path, ComparisonSourceType.Control); - var testSource = ToComparisonSource("hello world", ComparisonSourceType.Test); - var comparison = new Comparison(controlSource, testSource); - - sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } - - [Theory(DisplayName = "When IgnoreCase='false' inline attribute is present in a parent element, a string ordinal case comparison is performed")] - [InlineData(@"

          HELLO WoRlD

          ")] - [InlineData(@"

          HELLO WoRlD

          ")] - [InlineData(@"

          HELLO WoRlD

          ")] - public void Test009(string controlHtml) - { - var sut = new TextNodeComparer(ignoreCase: true); - var rootSource = ToComparisonSource(controlHtml); - var controlSource = new ComparisonSource(rootSource.Node.FirstChild.FirstChild.FirstChild, 0, rootSource.Path, ComparisonSourceType.Control); - var testSource = ToComparisonSource("hello world", ComparisonSourceType.Test); - var comparison = new Comparison(controlSource, testSource); - - sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); - } - - [Theory(DisplayName = "When diff:regex attribute is found on the immediate parent element, the control text is expected to a regex and that used when comparing to the test text node.")] - [InlineData(@"

          \d{4}

          ")] - [InlineData(@"

          \d{4}

          ")] - public void Test010(string controlHtml) - { - var sut = new TextNodeComparer(); - var paragraphSource = ToComparisonSource(controlHtml); - var controlSource = new ComparisonSource(paragraphSource.Node.FirstChild, 0, paragraphSource.Path, ComparisonSourceType.Control); - var testSource = ToComparisonSource("1234", ComparisonSourceType.Test); - var comparison = new Comparison(controlSource, testSource); - - sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } - - [Fact(DisplayName = "When diff:regex attribute is found on the immediate parent element and ignoreCase is true, the regex compare is done as case insensitive.")] - public void Test011() - { - var sut = new TextNodeComparer(ignoreCase: true); - var paragraphSource = ToComparisonSource(@"

          FOO\d{4}

          "); - var controlSource = new ComparisonSource(paragraphSource.Node.FirstChild, 0, paragraphSource.Path, ComparisonSourceType.Control); - var testSource = ToComparisonSource("foo1234", ComparisonSourceType.Test); - var comparison = new Comparison(controlSource, testSource); - - sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } - - [Theory(DisplayName = "When diff:regex='false' attribute is found on the immediate parent element, a string ordinal case comparison is performed.")] - [InlineData(@"

          1234

          ")] - public void Test012(string controlHtml) - { - var sut = new TextNodeComparer(); - var paragraphSource = ToComparisonSource(controlHtml); - var controlSource = new ComparisonSource(paragraphSource.Node.FirstChild, 0, paragraphSource.Path, ComparisonSourceType.Control); - var testSource = ToComparisonSource("1234", ComparisonSourceType.Test); - var comparison = new Comparison(controlSource, testSource); - - sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); - } + [Theory(DisplayName = "When option is Preserve or RemoveWhitespaceNodes, comparer does not run nor change the current decision")] + [InlineData(WhitespaceOption.Preserve)] + [InlineData(WhitespaceOption.RemoveWhitespaceNodes)] + public void Test5(WhitespaceOption whitespaceOption) + { + var comparison = ToComparison("hello world", " hello world "); + var sut = new TextNodeComparer(whitespaceOption); + + sut.Compare(comparison, CompareResult.Different).ShouldBe(CompareResult.Different); + sut.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); + sut.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); + } + + [Fact(DisplayName = "When option is Normalize and current decision is Same or Skip, compare uses the current decision")] + public void Test55() + { + var comparison = new Comparison(); + var sut = new TextNodeComparer(WhitespaceOption.Normalize); + + sut.Compare(comparison, CompareResult.Same).ShouldBe(CompareResult.Same); + sut.Compare(comparison, CompareResult.Skip).ShouldBe(CompareResult.Skip); + } + + [Theory(DisplayName = "When option is Normalize, any whitespace before and after a text node is removed before comparison")] + [MemberData(nameof(WhitespaceCharStrings))] + public void Test7(string whitespace) + { + var sut = new TextNodeComparer(WhitespaceOption.Normalize); + var normalText = "text"; + var whitespaceText = $"{whitespace} text {whitespace}"; + var c1 = ToComparison(normalText, normalText); + var c2 = ToComparison(normalText, whitespaceText); + var c3 = ToComparison(whitespaceText, normalText); + var c4 = ToComparison(whitespaceText, whitespaceText); + + sut.Compare(c1, CompareResult.Unknown).ShouldBe(CompareResult.Same); + sut.Compare(c2, CompareResult.Unknown).ShouldBe(CompareResult.Same); + sut.Compare(c3, CompareResult.Unknown).ShouldBe(CompareResult.Same); + sut.Compare(c4, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } + + [Theory(DisplayName = "When option is Normalize, any consecutive whitespace characters are collapsed into one before comparison")] + [MemberData(nameof(WhitespaceCharStrings))] + public void Test9(string whitespace) + { + var sut = new TextNodeComparer(WhitespaceOption.Normalize); + var normalText = "hello world"; + var whitespaceText = $" {whitespace} hello {whitespace} {whitespace} world {whitespace} "; + var c1 = ToComparison(normalText, normalText); + var c2 = ToComparison(normalText, whitespaceText); + var c3 = ToComparison(whitespaceText, normalText); + var c4 = ToComparison(whitespaceText, whitespaceText); + + sut.Compare(c1, CompareResult.Unknown).ShouldBe(CompareResult.Same); + sut.Compare(c2, CompareResult.Unknown).ShouldBe(CompareResult.Same); + sut.Compare(c3, CompareResult.Unknown).ShouldBe(CompareResult.Same); + sut.Compare(c4, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } + + [Theory(DisplayName = "When a parent node has a inline whitespace option, that overrides the global whitespace option")] + [InlineData(@"

          foo bar

          ", @"

          foo bar

          ")] + [InlineData(@"

          foo bar

          ", @"

          foo bar

          ")] + [InlineData(@"

          foo bar

          ", @"

          foo bar

          ")] + public void Test001(string controlHtml, string testHtml) + { + var sut = new TextNodeComparer(WhitespaceOption.Preserve); + var controlSource = new ComparisonSource(ToNode(controlHtml).FirstChild.FirstChild.FirstChild, 0, "dummypath", ComparisonSourceType.Control); + var testSource = new ComparisonSource(ToNode(testHtml).FirstChild.FirstChild.FirstChild, 0, "dummypath", ComparisonSourceType.Test); + var comparison = new Comparison(controlSource, testSource); + + sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } + + [Theory(DisplayName = "When whitespace option is Preserve or RemoveWhitespaceNodes, a string ordinal comparison is performed")] + [InlineData(WhitespaceOption.Preserve)] + [InlineData(WhitespaceOption.RemoveWhitespaceNodes)] + public void Test003(WhitespaceOption whitespaceOption) + { + var sut = new TextNodeComparer(whitespaceOption); + var comparison = ToComparison(" hello\n\nworld ", " hello\n\nworld "); + + sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } + + [Fact(DisplayName = "When IgnoreCase is true, a string ordinal ignore case comparison is performed")] + public void Test004() + { + var sut = new TextNodeComparer(ignoreCase: true); + var comparison = ToComparison("HELLO WoRlD", "hello world"); + + sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } + + [Theory(DisplayName = "When the parent element is
          , the is implicitly set to Preserve")]
          +    [InlineData("pre")]
          +    [InlineData("script")]
          +    [InlineData("style")]
          +    public void Test005(string tag)
          +    {
          +        var sut = new TextNodeComparer(WhitespaceOption.Normalize);
          +        var elm = ToComparisonSource($"<{tag}>foo   bar");
          +        var controlSource = new ComparisonSource(elm.Node.FirstChild, 0, elm.Path, ComparisonSourceType.Control);
          +        var testSource = ToComparisonSource("foo bar", ComparisonSourceType.Test);
          +        var comparison = new Comparison(controlSource, testSource);
          +
          +        sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different);
          +    }
          +
          +    [Theory(DisplayName = "When the parent element is 
           and the whitespace option is set " +
          +                          "inline to Normalize, the inline option is used instead of Preserve")]
          +    [InlineData("pre")]
          +    [InlineData("script")]
          +    [InlineData("style")]
          +    public void Test006(string tag)
          +    {
          +        var sut = new TextNodeComparer(WhitespaceOption.Normalize);
          +        var controlNode = ToNode($@"<{tag} diff:whitespace=""{nameof(WhitespaceOption.Normalize)}"">foo bar");
          +        var testNode = ToNode($@"<{tag}>  foo    bar   ");
          +        var controlSource = controlNode.FirstChild.ToComparisonSource(0, ComparisonSourceType.Control);
          +        var testSource = testNode.FirstChild.ToComparisonSource(0, ComparisonSourceType.Test);
          +        var comparison = new Comparison(controlSource, testSource);
          +
          +        sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same);
          +    }
          +
          +    [Theory(DisplayName = "When the parent element is 
           and the whitespace option is set " +
          +                  "inline to RemoveWhitespaceNodes, the inline option is used instead of Preserve")]
          +    [InlineData("pre")]
          +    [InlineData("script")]
          +    [InlineData("style")]
          +    public void Test007(string tag)
          +    {
          +        var sut = new TextNodeComparer(WhitespaceOption.Normalize);
          +        var controlNode = ToNode($@"<{tag} diff:whitespace=""{nameof(WhitespaceOption.RemoveWhitespaceNodes)}"">foo bar");
          +        var testNode = ToNode($@"<{tag}>  foo bar   ");
          +        var controlSource = controlNode.FirstChild.ToComparisonSource(0, ComparisonSourceType.Control);
          +        var testSource = testNode.FirstChild.ToComparisonSource(0, ComparisonSourceType.Test);
          +        var comparison = new Comparison(controlSource, testSource);
          +
          +        sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same);
          +    }
          +
          +    [Theory(DisplayName = "When IgnoreCase='true' inline attribute is present in a parent element, a string " +
          +                          "ordinal ignore case comparison is performed")]
          +    [InlineData(@"

          HELLO WoRlD

          ")] + [InlineData(@"

          HELLO WoRlD

          ")] + [InlineData(@"

          HELLO WoRlD

          ")] + public void Test008(string controlHtml) + { + var sut = new TextNodeComparer(ignoreCase: false); + var rootSource = ToComparisonSource(controlHtml); + var controlSource = new ComparisonSource(rootSource.Node.FirstChild.FirstChild.FirstChild, 0, rootSource.Path, ComparisonSourceType.Control); + var testSource = ToComparisonSource("hello world", ComparisonSourceType.Test); + var comparison = new Comparison(controlSource, testSource); + + sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } + + [Theory(DisplayName = "When IgnoreCase='false' inline attribute is present in a parent element, a string ordinal case comparison is performed")] + [InlineData(@"

          HELLO WoRlD

          ")] + [InlineData(@"

          HELLO WoRlD

          ")] + [InlineData(@"

          HELLO WoRlD

          ")] + public void Test009(string controlHtml) + { + var sut = new TextNodeComparer(ignoreCase: true); + var rootSource = ToComparisonSource(controlHtml); + var controlSource = new ComparisonSource(rootSource.Node.FirstChild.FirstChild.FirstChild, 0, rootSource.Path, ComparisonSourceType.Control); + var testSource = ToComparisonSource("hello world", ComparisonSourceType.Test); + var comparison = new Comparison(controlSource, testSource); + + sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Different); + } + + [Theory(DisplayName = "When diff:regex attribute is found on the immediate parent element, the control text is expected to a regex and that used when comparing to the test text node.")] + [InlineData(@"

          \d{4}

          ")] + [InlineData(@"

          \d{4}

          ")] + public void Test010(string controlHtml) + { + var sut = new TextNodeComparer(); + var paragraphSource = ToComparisonSource(controlHtml); + var controlSource = new ComparisonSource(paragraphSource.Node.FirstChild, 0, paragraphSource.Path, ComparisonSourceType.Control); + var testSource = ToComparisonSource("1234", ComparisonSourceType.Test); + var comparison = new Comparison(controlSource, testSource); + + sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } + + [Fact(DisplayName = "When diff:regex attribute is found on the immediate parent element and ignoreCase is true, the regex compare is done as case insensitive.")] + public void Test011() + { + var sut = new TextNodeComparer(ignoreCase: true); + var paragraphSource = ToComparisonSource(@"

          FOO\d{4}

          "); + var controlSource = new ComparisonSource(paragraphSource.Node.FirstChild, 0, paragraphSource.Path, ComparisonSourceType.Control); + var testSource = ToComparisonSource("foo1234", ComparisonSourceType.Test); + var comparison = new Comparison(controlSource, testSource); + + sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); + } + + [Theory(DisplayName = "When diff:regex='false' attribute is found on the immediate parent element, a string ordinal case comparison is performed.")] + [InlineData(@"

          1234

          ")] + public void Test012(string controlHtml) + { + var sut = new TextNodeComparer(); + var paragraphSource = ToComparisonSource(controlHtml); + var controlSource = new ComparisonSource(paragraphSource.Node.FirstChild, 0, paragraphSource.Path, ComparisonSourceType.Control); + var testSource = ToComparisonSource("1234", ComparisonSourceType.Test); + var comparison = new Comparison(controlSource, testSource); + + sut.Compare(comparison, CompareResult.Unknown).ShouldBe(CompareResult.Same); } } diff --git a/src/AngleSharp.Diffing.Tests/Strategies/TextNodeStrategies/TextNodeFilterTest.cs b/src/AngleSharp.Diffing.Tests/Strategies/TextNodeStrategies/TextNodeFilterTest.cs index cac3037..d620d62 100644 --- a/src/AngleSharp.Diffing.Tests/Strategies/TextNodeStrategies/TextNodeFilterTest.cs +++ b/src/AngleSharp.Diffing.Tests/Strategies/TextNodeStrategies/TextNodeFilterTest.cs @@ -1,101 +1,94 @@ -using AngleSharp.Diffing.Core; +namespace AngleSharp.Diffing.Strategies.TextNodeStrategies; -using Shouldly; +public class TextNodeFilterTest : TextNodeTestBase +{ + public TextNodeFilterTest(DiffingTestFixture fixture) : base(fixture) + { + } -using Xunit; + [Theory(DisplayName = "When whitespace option is Preserve, the provided decision is not changed by the filter for whitespace only text nodes")] + [MemberData(nameof(WhitespaceCharStrings))] + public void Test1(string whitespace) + { + var sut = new TextNodeFilter(WhitespaceOption.Preserve); + var source = ToComparisonSource(whitespace); -namespace AngleSharp.Diffing.Strategies.TextNodeStrategies -{ - public class TextNodeFilterTest : TextNodeTestBase + sut.Filter(source, FilterDecision.Keep).ShouldBe(FilterDecision.Keep); + sut.Filter(source, FilterDecision.Exclude).ShouldBe(FilterDecision.Exclude); + } + + [Theory(DisplayName = "When whitespace option is RemoveWhitespaceNodes, whitespace only text nodes are excluded during filtering")] + [MemberData(nameof(WhitespaceCharStrings))] + public void Test2(string whitespace) + { + var sut = new TextNodeFilter(WhitespaceOption.RemoveWhitespaceNodes); + var source = ToComparisonSource(whitespace); + + sut.Filter(source, FilterDecision.Keep).ShouldBe(FilterDecision.Exclude); + } + + [Theory(DisplayName = "When whitespace option is Normalize, whitespace only text nodes are excluded during filtering")] + [MemberData(nameof(WhitespaceCharStrings))] + public void Test3(string whitespace) + { + var sut = new TextNodeFilter(WhitespaceOption.Normalize); + var source = ToComparisonSource(whitespace); + + sut.Filter(source, FilterDecision.Keep).ShouldBe(FilterDecision.Exclude); + } + + [Theory(DisplayName = "Filter method doesn't change the decision of non-whitespace nodes or non-text nodes")] + [InlineData("hello world")] + [InlineData("

          hello world

          ")] + public void Test4x(string html) + { + var sut = new TextNodeFilter(WhitespaceOption.Normalize); + var source = ToComparisonSource(html); + + sut.Filter(source, FilterDecision.Keep).ShouldBe(FilterDecision.Keep); + sut.Filter(source, FilterDecision.Exclude).ShouldBe(FilterDecision.Exclude); + } + + [Theory(DisplayName = "If parent node is
          ,