AngleSharp / AngleSharp.Diffing

A library that makes it possible to compare two AngleSharp node lists and get a list of differences between them.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

After update to AngleSharp 1.1.0: 'No source reference attached to test element, cannot determine element tag closing style.'

SebastianStehle opened this issue · comments

Bug Report

Prerequisites

  • Can you reproduce the problem in a MWE?
  • Are you running the latest version of AngleSharp?
  • Did you check the FAQs to see if that helps you?
  • Are you reporting to the correct repository? (there are multiple AngleSharp libraries, e.g., AngleSharp.Css for CSS support)
  • Did you perform a search in the issues?

For more information, see the CONTRIBUTING guide.

Description

I have updated to AngleSharp 1.1.0 from 1.0.7 and now I get the following error.

Message: 
System.InvalidOperationException : No source reference attached to test element, cannot determine element tag closing style.

  Stack Trace: 
ElementComparer.Compare(Comparison& comparison, CompareResult currentDecision)
DiffingStrategyPipeline.Compare[TComparison](TComparison& comparison, List`1 compareStrategies, CompareResult initialResult)
DiffingStrategyPipeline.Compare(Comparison& comparison)
IDiffingStrategy.Compare(Comparison& comparison)
HtmlDifferenceEngine.CompareElement(Comparison& comparison)
HtmlDifferenceEngine.CompareNode(Comparison& comparison)
HtmlDifferenceEngine.<CompareNodes>b__11_0(Comparison comparison)
SelectManySingleSelectorIterator`2.MoveNext()

Steps to Reproduce

Very simple example:

            var actual = "<div></div>";
            var expected = "<div></div>";

            var diffs =
                DiffBuilder
                    .Compare(actual)
                    .WithTest(expected)
                    .WithOptions(options =>
                    {
                        options.AddElementComparer(true);
                        options.AddSearchingNodeMatcher();
                    })
                    .Build().ToList();

Expected behavior: No error.

Actual behavior: [What actually happened]

Environment details: [OS, .NET Runtime, ...]

AngleSharp.Diffing: 0.18.2

Possible Solution

[Optionally, share your idea to fix the issue]

I am not sure what has changed with the latest AngleSharp to cause this. The DiffBuilder's parser has IsKeepingSourceReferences = true set, so that should take care of that exception.

The part of the code that causes the expectation to be thrown is this: if (testElement.SourceReference is not HtmlTagToken testTag).

@FlorianRappl do you have some insights here?

Yes, I have expected that there would have been a bug with this property, so I tested it and the source reference is actually there. At least in my test

Yes, I think this is a problem (not that it's null - it is not - but the test fails as its no longer an HtmlTagToken).

It was introduced here: AngleSharp/AngleSharp#1159

Actually I am not sure if its a breaking change (in my eyes it kind of is, but then again the ISourceReference has not reflected what type is underneath - so it should not be used like that). Overall it seemed I did not pay close enough attention to this detail when accepting the PR.

I need to investigate if this new SourceReference type is really needed. I think this was an optimization to remove the tokens - thus lower the pressure.

Question to you @egil - is this (HtmlTagToken) fully required? Is the text position information enough?

@FlorianRappl it is only needed to determine if a tag is self-closing or not:

if (EnforceTagClosing && result == CompareResult.Same)
{
if (testElement.SourceReference is not HtmlTagToken testTag)
throw new InvalidOperationException("No source reference attached to test element, cannot determine element tag closing style.");
if (controlElement.SourceReference is not HtmlTagToken controlTag)
throw new InvalidOperationException("No source reference attached to test element, cannot determine element tag closing style.");
return testTag.IsSelfClosing == controlTag.IsSelfClosing
? result
: CompareResult.FromDiff(new ElementDiff(comparison, ElementDiffKind.ClosingStyle));
}

If there is another way to get that information without a HtmlTagToken I'm fine with removing the need for source references.

@SebastianStehle if you do not need the differ to tell you if tags using different closing styles, you can disable that check by calling .AddElementComparer(enforceTagClosing: false).

Unfortunately I need that.

If there is another way to get that information without a HtmlTagToken I'm fine with removing the need for source references.

I don't think so. Just to be clear: You need to know if it's <foo></foo> or <foo />?

Effectively, there should be no difference (from the parsing perspective there is a lot of difference - in real / official HTML5 only a few elements can be self-closed - and all of them should actually be self-closed without the trailing slash - for example <img> is OK and <img /> is just "tolerated" and not good).

I've pushed an update. With this latest preview it should work again.

@SebastianStehle can you try to upgrade AngleSharp to 1.1.1-beta.387. Once I have confirmation that this solves the issue I'd make a full release of AngleSharp 1.1.1.

If there is another way to get that information without a HtmlTagToken I'm fine with removing the need for source references.

I don't think so. Just to be clear: You need to know if it's <foo></foo> or <foo />?

Effectively, there should be no difference (from the parsing perspective there is a lot of difference - in real / official HTML5 only a few elements can be self-closed - and all of them should actually be self-closed without the trailing slash - for example <img> is OK and <img /> is just "tolerated" and not good).

I understand that. The challenge is that some users want to know if two HTML snippets are the same, down to whether or not tags are self-closing or not. By default AngleSharp.Diffing do not consider the self-closingness of elements when it compares them.

I will test it out today.

I think we can close this - this is fixed with AngleSharp 1.1.1.

Closing now - if this is not true please let us know. Thanks!