Files
jiapuapp/tests/document-flow-position-contract.ps1
T
2026-07-20 17:23:13 +08:00

35 lines
1.7 KiB
PowerShell

$ErrorActionPreference = 'Stop'
$root = Split-Path $PSScriptRoot -Parent
$allowlistPath = Join-Path $PSScriptRoot 'document-flow-position-allowlist.json'
$allowlist = Get-Content -LiteralPath $allowlistPath -Raw -Encoding UTF8 | ConvertFrom-Json
$allowed = @{}
foreach ($entry in $allowlist) {
$allowed["$($entry.file)::$($entry.selector)"] = $entry.reason
}
$violations = New-Object System.Collections.Generic.List[string]
$files = Get-ChildItem -LiteralPath (Join-Path $root 'pages'), (Join-Path $root 'components') -Recurse -File -Filter '*.vue'
foreach ($file in $files) {
$relative = $file.FullName.Substring($root.Length + 1).Replace('\', '/')
$source = [System.IO.File]::ReadAllText($file.FullName, [System.Text.Encoding]::UTF8)
foreach ($styleMatch in [regex]::Matches($source, '(?s)<style\b[^>]*>(?<css>.*?)</style>')) {
$css = $styleMatch.Groups['css'].Value
foreach ($rule in [regex]::Matches($css, '(?s)(?<selector>[^{}]+)\{(?<body>[^{}]*)\}')) {
$body = $rule.Groups['body'].Value
if ($body -notmatch '(?m)position\s*:\s*(absolute|fixed|sticky)\s*;') { continue }
$selector = (($rule.Groups['selector'].Value -replace '(?s)^.*@media[^\{]*', '') -replace '\s+', ' ').Trim()
$key = "$relative::$selector"
if (-not $allowed.ContainsKey($key)) {
$position = [regex]::Match($body, '(?m)position\s*:\s*(absolute|fixed|sticky)\s*;').Groups[1].Value
$violations.Add("$relative :: $selector :: position:$position")
}
}
}
}
if ($violations.Count -gt 0) {
$violations | Sort-Object | ForEach-Object { Write-Output $_ }
throw "DOCUMENT-FLOW-POSITION-CONTRACT found $($violations.Count) non-overlay positioning rules."
}
Write-Output 'DOCUMENT-FLOW-POSITION-CONTRACT PASS'