< Summary

Information
Class: AspxLint.Core.Rules.Attr003DuplicateAttribute
Assembly: AspxLint.Core
File(s): D:\a\claude-aspx-lint\claude-aspx-lint\src\AspxLint.Core\Rules\Attr003DuplicateAttribute.cs
Line coverage
100%
Covered lines: 10
Uncovered lines: 0
Coverable lines: 10
Total lines: 46
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\Attr003DuplicateAttribute.cs

#LineLine coverage
 1using System.Text.RegularExpressions;
 2
 3namespace AspxLint.Core.Rules;
 4
 5public sealed class Attr003DuplicateAttribute : IRule
 6{
 2037    public string Id => "ATTR-003";
 268    public string Name => "Attributs en double dans une balise";
 239    public Severity Severity => Severity.Error;
 10    public string Description =>
 2511        "Une meme balise ne doit pas contenir deux fois le meme attribut. Le navigateur ne conserve generalement que le 
 4612    public bool HasFix => false;
 13
 514    private static readonly Regex TagRegex =
 515        new(@"<([a-zA-Z][a-zA-Z0-9:_\-]*)\b([^>]*?)>", RegexOptions.Compiled);
 16
 517    private static readonly Regex AttrNameRegex =
 518        new(@"\s([a-zA-Z][a-zA-Z0-9\-:_]*)\s*=", RegexOptions.Compiled);
 19
 20    public IEnumerable<Issue> Detect(string content, string[] lines, RuleContext ctx)
 21    {
 22        for (int i = 0; i < lines.Length; i++)
 23        {
 24            foreach (Match m in TagRegex.Matches(lines[i]))
 25            {
 26                var attrs = m.Groups[2].Value;
 27                var seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
 28
 29                foreach (Match am in AttrNameRegex.Matches(attrs))
 30                {
 31                    var name = am.Groups[1].Value;
 32                    if (!seen.Add(name))
 33                    {
 34                        var snippet = m.Value.Length > 80 ? m.Value[..80] + "…" : m.Value;
 35                        yield return new Issue(Id, Name, Severity,
 36                            i + 1, m.Index + 1, snippet,
 37                            $"L'attribut \"{name}\" apparait plusieurs fois dans cette balise.");
 38                        break; // un par balise suffit
 39                    }
 40                }
 41            }
 42        }
 43    }
 44
 445    public string? Fix(string content, RuleContext ctx) => null;
 46}