Skip to content

Commit 1394e16

Browse files
author
Per Kops
committed
fix(providers): update XunitProvider for xunit.net page structure
- Update HTML table selectors for new page layout - Select from all tables instead of single article table
1 parent dce54b4 commit 1394e16

File tree

3 files changed

+49
-41
lines changed

3 files changed

+49
-41
lines changed

src/Atc.CodingRules.AnalyzerProviders/GlobalUsings.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
global using System.Text.Encodings.Web;
66
global using System.Text.Json;
77
global using System.Text.Json.Serialization;
8+
global using System.Text.RegularExpressions;
89
global using System.Xml;
910

1011
global using Atc.CodingRules.AnalyzerProviders.Models;

src/Atc.CodingRules.AnalyzerProviders/Providers/XunitProvider.cs

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ namespace Atc.CodingRules.AnalyzerProviders.Providers;
22

33
public class XunitProvider : AnalyzerProviderBase
44
{
5-
private const int TableThColumnId = 0;
6-
private const int TableTdColumnTitle = 0;
5+
private const int TableColumnId = 0;
6+
private const int TableColumnTitle = 3;
77

88
public XunitProvider(
99
ILogger logger,
@@ -30,51 +30,53 @@ protected override async Task ReCollect(AnalyzerProviderBaseRuleData data)
3030
.LoadFromWebAsync(DocumentationLink!.AbsoluteUri)
3131
.ConfigureAwait(false);
3232

33-
var articleNode = htmlDoc.DocumentNode.SelectNodes("//table[@class='table']")[0];
34-
var articleTableRows = articleNode
35-
.SelectNodes("//*//tr")
36-
.ToList();
33+
var tables = htmlDoc.DocumentNode.SelectNodes("//table");
34+
if (tables is null || tables.Count == 0)
35+
{
36+
return;
37+
}
3738

38-
foreach (var row in articleTableRows)
39+
var articleTableRows = new List<HtmlNode>();
40+
foreach (var table in tables)
3941
{
40-
if (row.SelectNodes("th") is null ||
41-
row.SelectNodes("td") is null)
42+
var rows = table.SelectNodes(".//tr");
43+
if (rows is not null)
4244
{
43-
continue;
45+
articleTableRows.AddRange(rows);
4446
}
47+
}
4548

46-
var cellsTh = row
47-
.SelectNodes("th")
48-
.ToList();
49-
50-
var cellsTd = row
51-
.SelectNodes("td")
52-
.ToList();
53-
54-
if (cellsTh.Count <= 0 || cellsTd.Count <= 0)
49+
foreach (var row in articleTableRows)
50+
{
51+
var rule = TryParseRuleFromRow(row);
52+
if (rule is not null)
5553
{
56-
continue;
54+
data.Rules.Add(rule);
5755
}
56+
}
57+
}
5858

59-
var aHrefNode = cellsTh[TableThColumnId].SelectSingleNode("a");
60-
if (aHrefNode is null)
61-
{
62-
continue;
63-
}
59+
private Rule? TryParseRuleFromRow(HtmlNode row)
60+
{
61+
var cells = row.SelectNodes("td");
62+
if (cells is null || cells.Count <= TableColumnTitle)
63+
{
64+
return null;
65+
}
6466

65-
var code = aHrefNode.InnerText
66-
.RemoveNewLines()
67-
.Trim();
67+
var cellsList = cells.ToList();
68+
var aHrefNode = cellsList[TableColumnId].SelectSingleNode("a");
69+
if (aHrefNode is null)
70+
{
71+
return null;
72+
}
6873

69-
var title = HtmlEntity.DeEntitize(cellsTd[TableTdColumnTitle].InnerText);
70-
var link = $"{DocumentationLink}/{code}";
74+
var code = aHrefNode.InnerText
75+
.RemoveNewLines()
76+
.Trim();
77+
var title = HtmlEntity.DeEntitize(cellsList[TableColumnTitle].InnerText);
78+
var link = $"{DocumentationLink}/{code}";
7179

72-
data.Rules.Add(
73-
new Rule(
74-
code,
75-
title,
76-
link,
77-
category: null));
78-
}
80+
return new Rule(code, title, link, category: null);
7981
}
8082
}

test/Atc.CodingRules.AnalyzerProviders.Tests/Providers/XunitProviderTests.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,16 @@ public sealed class XunitProviderTests
1111
public async Task CollectBaseRules(
1212
ProviderCollectingMode providerCollectingMode)
1313
{
14-
// Arrange
15-
var provider = new XunitProvider(NullLogger.Instance);
14+
AnalyzerProviderBaseRuleData? actual = null;
1615

17-
// Act
18-
var actual = await provider.CollectBaseRules(providerCollectingMode);
16+
await RetryHelper.ExecuteWithRetryAsync(async () =>
17+
{
18+
// Arrange
19+
var provider = new XunitProvider(NullLogger.Instance);
20+
21+
// Act
22+
actual = await provider.CollectBaseRules(providerCollectingMode);
23+
});
1924

2025
// Assert
2126
Assert.NotNull(actual);

0 commit comments

Comments
 (0)