< Summary

Information
Class: AspxLint.Core.Rules.Dir001PageDirective
Assembly: AspxLint.Core
File(s): D:\a\claude-aspx-lint\claude-aspx-lint\src\AspxLint.Core\Rules\Dir001PageDirective.cs
Line coverage
100%
Covered lines: 29
Uncovered lines: 0
Coverable lines: 29
Total lines: 82
Line coverage: 100%
Branch coverage
90%
Covered branches: 18
Total branches: 20
Branch coverage: 90%
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%
Expected(...)100%66100%
Fix(...)85.71%1414100%

File(s)

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

#LineLine coverage
 1using System.Text.RegularExpressions;
 2
 3namespace AspxLint.Core.Rules;
 4
 5public sealed class Dir001PageDirective : IRule
 6{
 2557    public string Id => "DIR-001";
 708    public string Name => "Directive de page absente ou mal placee";
 679    public Severity Severity => Severity.Error;
 10    public string Description =>
 2511        "Un fichier ASPX doit commencer par <%@ Page ... %>, un ASCX par <%@ Control ... %>, un MASTER par <%@ Master ..
 4612    public bool HasFix => true;
 13
 15214    private static string? Expected(string ext) => ext switch
 15215    {
 13216        "aspx" => "Page",
 1017        "ascx" => "Control",
 618        "master" => "Master",
 419        _ => null
 15220    };
 21
 22    public IEnumerable<Issue> Detect(string content, string[] lines, RuleContext ctx)
 23    {
 24        var expected = Expected(ctx.Ext);
 25        if (expected is null) yield break;
 26
 27        int firstNonEmpty = -1;
 28        for (int i = 0; i < lines.Length; i++)
 29        {
 30            if (!string.IsNullOrWhiteSpace(lines[i])) { firstNonEmpty = i; break; }
 31        }
 32        if (firstNonEmpty < 0) yield break;
 33
 34        var re = new Regex(@"<%@\s*" + expected + @"\b", RegexOptions.IgnoreCase);
 35        var hasDirective = lines.Any(l => re.IsMatch(l));
 36
 37        if (!hasDirective)
 38        {
 39            yield return new Issue(Id, Name, Severity, 1, 1,
 40                lines[firstNonEmpty],
 41                $"Directive @{expected} manquante. Ajoutez-la en premiere ligne.");
 42        }
 43        else if (firstNonEmpty > 0 && !re.IsMatch(lines[firstNonEmpty]))
 44        {
 45            int dirLine = -1;
 46            for (int i = 0; i < lines.Length; i++)
 47                if (re.IsMatch(lines[i])) { dirLine = i; break; }
 48
 49            if (dirLine != firstNonEmpty && dirLine >= 0)
 50                yield return new Issue(Id, Name, Severity, dirLine + 1, 1,
 51                    lines[dirLine],
 52                    $"La directive @{expected} doit etre la premiere ligne non vide du fichier.");
 53        }
 54    }
 55
 56    public string? Fix(string content, RuleContext ctx)
 57    {
 3358        var expected = Expected(ctx.Ext);
 3359        if (expected is null) return content;
 60
 3361        var re = new Regex(@"<%@\s*" + expected + @"\b", RegexOptions.IgnoreCase);
 3362        var lines = content.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None).ToList();
 3363        int dirIndex = -1;
 18864        for (int i = 0; i < lines.Count; i++)
 9765            if (re.IsMatch(lines[i])) { dirIndex = i; break; }
 66
 3367        if (dirIndex < 0)
 68        {
 2169            var stub = $"<%@ {expected} Language=\"C#\" AutoEventWireup=\"true\" %>";
 2170            return stub + "\n" + content;
 71        }
 1272        if (dirIndex > 0)
 73        {
 274            var dirLine = lines[dirIndex];
 275            lines.RemoveAt(dirIndex);
 276            while (lines.Count > 0 && string.IsNullOrWhiteSpace(lines[0])) lines.RemoveAt(0);
 277            lines.Insert(0, dirLine);
 278            return string.Join("\n", lines);
 79        }
 1080        return content;
 81    }
 82}