< Summary

Information
Class: AspxLint.Core.Rules.Tag001VoidElementsXhtml
Assembly: AspxLint.Core
File(s): D:\a\claude-aspx-lint\claude-aspx-lint\src\AspxLint.Core\Rules\Tag001VoidElementsXhtml.cs
Line coverage
100%
Covered lines: 12
Uncovered lines: 0
Coverable lines: 12
Total lines: 45
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Id()100%11100%
get_Name()100%11100%
get_Severity()100%11100%
get_Description()100%11100%
get_HasFix()100%11100%
.cctor()100%11100%
Fix(...)100%11100%

File(s)

D:\a\claude-aspx-lint\claude-aspx-lint\src\AspxLint.Core\Rules\Tag001VoidElementsXhtml.cs

#LineLine coverage
 1using System.Text.RegularExpressions;
 2
 3namespace AspxLint.Core.Rules;
 4
 5public sealed class Tag001VoidElementsXhtml : IRule
 6{
 2377    public string Id => "TAG-001";
 528    public string Name => "Balise auto-fermante non conforme XHTML";
 499    public Severity Severity => Severity.Warning;
 10    public string Description =>
 2511        "Les balises vides comme <br>, <hr>, <img>, <input>, <meta>, <link> doivent s'ecrire en auto-fermantes (ex: <br 
 4612    public bool HasFix => true;
 13
 14    private const string VoidTagAlternation =
 15        "br|hr|img|input|meta|link|area|base|col|embed|source|track|wbr";
 16
 17    // Detection : balises void sans / avant le >.
 518    private static readonly Regex DetectRegex = new(
 519        $@"<({VoidTagAlternation})(\s[^>]*?)?(?<!/)>",
 520        RegexOptions.IgnoreCase | RegexOptions.Compiled);
 21
 22    // Fix : meme chose mais on capture aussi un eventuel whitespace avant > pour le re-emettre proprement.
 523    private static readonly Regex FixRegex = new(
 524        $@"<({VoidTagAlternation})((?:\s[^>]*?)?)(?<!/)\s*>",
 525        RegexOptions.IgnoreCase | RegexOptions.Compiled);
 26
 27    public IEnumerable<Issue> Detect(string content, string[] lines, RuleContext ctx)
 28    {
 29        for (int i = 0; i < lines.Length; i++)
 30        {
 31            foreach (Match m in DetectRegex.Matches(lines[i]))
 32            {
 33                if (m.Value.EndsWith("/>")) continue; // garde-fou
 34                var fixedTag = m.Value[..^1].TrimEnd() + " />";
 35                yield return new Issue(Id, Name, Severity,
 36                    i + 1, m.Index + 1,
 37                    m.Value,
 38                    $"Remplacer par \"{fixedTag}\".");
 39            }
 40        }
 41    }
 42
 43    public string? Fix(string content, RuleContext ctx) =>
 2744        FixRegex.Replace(content, m => $"<{m.Groups[1].Value}{m.Groups[2].Value} />");
 45}