Files
jiapuapp/tests/project-responsive-layout-contract.ps1
T
2026-07-23 08:24:07 +08:00

72 lines
2.8 KiB
PowerShell

$ErrorActionPreference = 'Stop'
$root = Split-Path -Parent $PSScriptRoot
$coveragePath = Join-Path $PSScriptRoot 'responsive-layout-coverage.json'
$allowlistPath = Join-Path $PSScriptRoot 'responsive-layout-allowlist.json'
if (-not (Test-Path -LiteralPath $coveragePath)) { throw 'Missing responsive layout coverage owner' }
if (-not (Test-Path -LiteralPath $allowlistPath)) { throw 'Missing responsive layout allowlist owner' }
$coverage = Get-Content -LiteralPath $coveragePath -Raw -Encoding UTF8 | ConvertFrom-Json
$allowlist = Get-Content -LiteralPath $allowlistPath -Raw -Encoding UTF8 | ConvertFrom-Json
$requiredFoundation = @(
'components/AppButton.vue',
'components/AppDialog.vue'
)
foreach ($required in $requiredFoundation) {
if ($coverage.covered -notcontains $required) {
throw "Responsive coverage cannot remove migrated foundation file: $required"
}
}
function Normalize-Selector([string]$selector) {
return (($selector -replace '\s+', ' ').Trim())
}
function Test-Allowlisted([string]$path, [string]$selector, [string]$property) {
$normalizedSelector = Normalize-Selector $selector
foreach ($entry in $allowlist.exceptions) {
if ($entry.path -eq $path -and
(Normalize-Selector $entry.selector) -eq $normalizedSelector -and
$entry.property -eq $property) {
return $true
}
}
return $false
}
$violations = [System.Collections.Generic.List[string]]::new()
foreach ($relativePath in $coverage.covered) {
$fullPath = Join-Path $root $relativePath
if (-not (Test-Path -LiteralPath $fullPath)) {
$violations.Add("missing covered file: $relativePath")
continue
}
$source = Get-Content -LiteralPath $fullPath -Raw -Encoding UTF8
$styleMatches = [regex]::Matches($source, '(?is)<style\b[^>]*>(?<css>.*?)</style>')
foreach ($styleMatch in $styleMatches) {
$css = $styleMatch.Groups['css'].Value
$ruleMatches = [regex]::Matches($css, '(?ms)(?<selector>[^{}]+)\{(?<body>[^{}]*)\}')
foreach ($rule in $ruleMatches) {
$selector = Normalize-Selector $rule.Groups['selector'].Value
$body = $rule.Groups['body'].Value
$checks = @(
@{ Name = 'fixed-height'; Pattern = '(?im)(?<![-\w])height\s*:\s*\d+(?:\.\d+)?rpx\b' },
@{ Name = 'background-stretch'; Pattern = '(?im)background\s*:[^;\r\n]*100%\s+100%[^;\r\n]*;' },
@{ Name = 'direct-border-image-slice'; Pattern = '(?im)border-image-slice\s*:' }
)
foreach ($check in $checks) {
if ($body -match $check.Pattern -and -not (Test-Allowlisted $relativePath $selector $check.Name)) {
$violations.Add("$relativePath :: $selector :: $($check.Name)")
}
}
}
}
}
if ($violations.Count -gt 0) {
throw ("Responsive layout contract violations:`n - " + ($violations -join "`n - "))
}
Write-Output 'PROJECT-RESPONSIVE-LAYOUT-CONTRACT PASS'