< Summary

Information
Class: AspxLint.Core.Rules.Tag002TagCase
Assembly: AspxLint.Core
File(s): D:\a\claude-aspx-lint\claude-aspx-lint\src\AspxLint.Core\Rules\Tag002TagCase.cs
Line coverage
100%
Covered lines: 24
Uncovered lines: 0
Coverable lines: 24
Total lines: 62
Line coverage: 100%
Branch coverage
100%
Covered branches: 2
Total branches: 2
Branch coverage: 100%
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%22100%

File(s)

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

#LineLine coverage
 1using System.Text.RegularExpressions;
 2
 3namespace AspxLint.Core.Rules;
 4
 5public sealed class Tag002TagCase : IRule
 6{
 2157    public string Id => "TAG-002";
 348    public string Name => "Casse incoherente des balises HTML";
 319    public Severity Severity => Severity.Warning;
 10    public string Description =>
 2511        "Les balises HTML doivent etre en minuscules pour respecter HTML5/XHTML. Une casse mixte (<DIV>, <Div>) nuit a l
 4612    public bool HasFix => true;
 13
 14    // Detection : tags HTML standard avec une majuscule (hors controles namespaced asp:Foo, uc:Foo, ...).
 515    private static readonly Regex DetectRegex =
 516        new(@"<\/?([A-Z][a-zA-Z0-9]*)\b", RegexOptions.Compiled);
 17
 518    private static readonly Regex NamespacedTag =
 519        new(@"^<\/?[a-zA-Z]+:", RegexOptions.Compiled);
 20
 21    // Whitelist des tags HTML qu'on ose remettre en minuscules (le fix JS limite aussi a une whitelist).
 522    private static readonly string[] HtmlTags =
 523    {
 524        "html","head","body","div","span","p","a","img","br","hr",
 525        "ul","ol","li","table","tr","td","th","thead","tbody","tfoot",
 526        "form","input","button","select","option","textarea","label",
 527        "h1","h2","h3","h4","h5","h6","section","article","header","footer",
 528        "nav","main","aside","meta","link","title","script","style",
 529        "strong","em","b","i","u","small","code","pre","blockquote",
 530        "iframe","canvas","svg"
 531    };
 32
 33    public IEnumerable<Issue> Detect(string content, string[] lines, RuleContext ctx)
 34    {
 35        for (int i = 0; i < lines.Length; i++)
 36        {
 37            var line = lines[i];
 38            foreach (Match m in DetectRegex.Matches(line))
 39            {
 40                // Skip controles namespaced : asp:Label, uc:Header, etc.
 41                if (NamespacedTag.IsMatch(line[m.Index..])) continue;
 42                yield return new Issue(Id, Name, Severity,
 43                    i + 1, m.Index + 1, m.Value,
 44                    $"Convertir \"{m.Groups[1].Value}\" en minuscules.");
 45            }
 46        }
 47    }
 48
 49    public string? Fix(string content, RuleContext ctx)
 50    {
 51        // Pour chaque tag de la whitelist, remplace toutes les occurences case-insensitive
 52        // par sa forme minuscule. Ne touche que les chevrons d'ouverture (`<` ou `</`),
 53        // donc les valeurs d'attributs ne sont jamais affectees.
 2354        var fixedContent = content;
 266855        foreach (var tag in HtmlTags)
 56        {
 131157            var re = new Regex(@"<(\/?)(" + tag + @")\b", RegexOptions.IgnoreCase);
 131158            fixedContent = re.Replace(fixedContent, m => "<" + m.Groups[1].Value + tag);
 59        }
 2360        return fixedContent;
 61    }
 62}