using System.Text.RegularExpressions;
namespace SQLInsight.Community.Tests;
///
/// A table cell must stay a table cell. A class that sets display: flex or grid turns a <td>/<th> into a flex box,
/// so it gets its own height and border and the row's divider jumps (the severity badges on the overviews did that).
/// Such classes belong on an element inside the cell. Checked for every site's stylesheet against its own pages.
///
public sealed partial class TableMarkupTests
{
[Theory]
[InlineData("SQLInsight.Web")]
[InlineData("SQLInsight.Hub")]
[InlineData("SQLInsight.Community")]
public void No_table_cell_has_a_flex_or_grid_class(string project)
{
var folder = Path.Combine(RepositoryRoot(), "src", project);
var layoutClasses = Directory.EnumerateFiles(Path.Combine(folder, "wwwroot"), "*.css", SearchOption.AllDirectories)
.SelectMany(css => FlexOrGridRule().Matches(File.ReadAllText(css)))
.SelectMany(rule => ClassName().Matches(rule.Groups["selectors"].Value).Select(c => c.Groups[1].Value))
.ToHashSet(StringComparer.Ordinal);
var offenders = Directory.EnumerateFiles(folder, "*.razor", SearchOption.AllDirectories)
.Where(file => !file.Contains($"{Path.DirectorySeparatorChar}bin{Path.DirectorySeparatorChar}", StringComparison.Ordinal)
&& !file.Contains($"{Path.DirectorySeparatorChar}obj{Path.DirectorySeparatorChar}", StringComparison.Ordinal))
.SelectMany(file => CellClass().Matches(File.ReadAllText(file))
.SelectMany(cell => cell.Groups["classes"].Value.Split(' ', StringSplitOptions.RemoveEmptyEntries))
.Where(layoutClasses.Contains)
.Select(c => $"{Path.GetFileName(file)}:
"))
.ToList();
Assert.True(offenders.Count == 0, "Flyt klassen ind på et element i cellen: " + string.Join(", ", offenders));
}
private static string RepositoryRoot()
{
var root = AppContext.BaseDirectory;
while (!File.Exists(Path.Combine(root, "SQLInsight.slnx")))
{
root = Path.GetDirectoryName(root) ?? throw new InvalidOperationException("SQLInsight.slnx ikke fundet.");
}
return root;
}
// A rule whose declarations set display to (inline-)flex or (inline-)grid; media queries are fine, their inner rules match.
[GeneratedRegex(@"(?[^{}]+)\{[^{}]*\bdisplay\s*:\s*(inline-)?(flex|grid)\b")]
private static partial Regex FlexOrGridRule();
[GeneratedRegex(@"\.([A-Za-z][\w-]*)")]
private static partial Regex ClassName();
// Literal class names only; Razor expressions (@…) in the attribute are skipped by splitting on spaces.
[GeneratedRegex(@"]*\bclass=""(?[^""]*)""")]
private static partial Regex CellClass();
}
|