mirror of
https://github.com/Dictionarry-Hub/database.git
synced 2025-12-10 15:57:00 +00:00
ci(validation): add testing workflow
This commit is contained in:
6
.github/workflows/regex.yml
vendored
6
.github/workflows/regex.yml
vendored
@@ -1,4 +1,4 @@
|
|||||||
name: Validate Regex Patterns
|
name: Regular Expressions
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -26,6 +26,4 @@ jobs:
|
|||||||
run: pwsh scripts/validateAllPatterns.ps1
|
run: pwsh scripts/validateAllPatterns.ps1
|
||||||
|
|
||||||
- name: test
|
- name: test
|
||||||
run: |
|
run: pwsh scripts/testPatterns.ps1
|
||||||
echo "TODO: Implement unit tests for all patterns"
|
|
||||||
# TODO: Add test runner command here
|
|
||||||
|
|||||||
183
scripts/testPatterns.ps1
Normal file
183
scripts/testPatterns.ps1
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
param(
|
||||||
|
[string]$YamlFilePath
|
||||||
|
)
|
||||||
|
|
||||||
|
# Function to run tests for a single file
|
||||||
|
function Test-Pattern {
|
||||||
|
param([string]$FilePath)
|
||||||
|
|
||||||
|
$fileName = (Get-Item $FilePath).BaseName
|
||||||
|
|
||||||
|
try {
|
||||||
|
# Read YAML content
|
||||||
|
$yamlContent = Get-Content -Path $FilePath -Raw
|
||||||
|
|
||||||
|
# Extract pattern
|
||||||
|
$patternMatch = [regex]::Match($yamlContent, 'pattern:\s*(.+)')
|
||||||
|
$pattern = $patternMatch.Groups[1].Value.Trim()
|
||||||
|
|
||||||
|
# Create regex object with case-insensitive and multiline options
|
||||||
|
$regexOptions = [System.Text.RegularExpressions.RegexOptions]::IgnoreCase -bor [System.Text.RegularExpressions.RegexOptions]::Multiline
|
||||||
|
$regex = New-Object System.Text.RegularExpressions.Regex($pattern, $regexOptions)
|
||||||
|
|
||||||
|
# Extract tests
|
||||||
|
$testsSection = [regex]::Match($yamlContent, '(?s)tests:(.*?)(?:\n\w|\z)').Groups[1].Value
|
||||||
|
|
||||||
|
if ([string]::IsNullOrWhiteSpace($testsSection)) {
|
||||||
|
return @{
|
||||||
|
File = $fileName
|
||||||
|
Passed = 0
|
||||||
|
Failed = 0
|
||||||
|
Total = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse each test
|
||||||
|
$tests = [regex]::Matches($testsSection, '(?s)- expected:\s*(true|false).*?input:\s*(.+?)(?=\n\s*\w|\n-|\z)')
|
||||||
|
|
||||||
|
$passed = 0
|
||||||
|
$failed = 0
|
||||||
|
$failureDetails = @()
|
||||||
|
|
||||||
|
foreach ($test in $tests) {
|
||||||
|
$expected = $test.Groups[1].Value -eq 'true'
|
||||||
|
$input = $test.Groups[2].Value.Trim()
|
||||||
|
|
||||||
|
# Run the test
|
||||||
|
$matches = $regex.IsMatch($input)
|
||||||
|
|
||||||
|
if ($matches -eq $expected) {
|
||||||
|
$passed++
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$failed++
|
||||||
|
$failureDetails += " Input: '$input' - Expected: $expected, Got: $matches"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return @{
|
||||||
|
File = $fileName
|
||||||
|
Passed = $passed
|
||||||
|
Failed = $failed
|
||||||
|
Total = $tests.Count
|
||||||
|
Failures = $failureDetails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return @{
|
||||||
|
File = $fileName
|
||||||
|
Error = $_.Exception.Message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
if ($YamlFilePath) {
|
||||||
|
# Test single file
|
||||||
|
$result = Test-Pattern -FilePath $YamlFilePath
|
||||||
|
|
||||||
|
if ($result.Error) {
|
||||||
|
Write-Host "ERROR: $($result.File): $($result.Error)" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($result.Failed -gt 0) {
|
||||||
|
Write-Host "$($result.File): $($result.Failed)/$($result.Total) tests failed" -ForegroundColor Red
|
||||||
|
foreach ($failure in $result.Failures) {
|
||||||
|
Write-Host $failure
|
||||||
|
}
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Host "$($result.File): All $($result.Total) tests passed"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Test all files
|
||||||
|
$patternFiles = @()
|
||||||
|
$patternFiles += Get-ChildItem -Path "regex_patterns" -Filter "*.yml" -File
|
||||||
|
$patternFiles += Get-ChildItem -Path "regex_patterns" -Filter "*.yaml" -File
|
||||||
|
|
||||||
|
if ($patternFiles.Count -eq 0) {
|
||||||
|
Write-Host "No pattern files found"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$results = @()
|
||||||
|
$totalFiles = $patternFiles.Count
|
||||||
|
$filesWithFailures = @()
|
||||||
|
|
||||||
|
foreach ($file in $patternFiles) {
|
||||||
|
$result = Test-Pattern -FilePath $file.FullName
|
||||||
|
$results += $result
|
||||||
|
|
||||||
|
if ($result.Error) {
|
||||||
|
$filesWithFailures += $result
|
||||||
|
}
|
||||||
|
elseif ($result.Failed -gt 0) {
|
||||||
|
$filesWithFailures += $result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Report failures
|
||||||
|
if ($filesWithFailures.Count -gt 0) {
|
||||||
|
Write-Host "ERRORS:"
|
||||||
|
|
||||||
|
# Find global max input length across all failures
|
||||||
|
$globalMaxInputLength = 0
|
||||||
|
foreach ($failure in $filesWithFailures) {
|
||||||
|
if (-not $failure.Error) {
|
||||||
|
foreach ($detail in $failure.Failures) {
|
||||||
|
if ($detail -match "Input: '(.+?)' -") {
|
||||||
|
$inputLength = $matches[1].Length
|
||||||
|
if ($inputLength -gt $globalMaxInputLength) {
|
||||||
|
$globalMaxInputLength = $inputLength
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Limit padding to 150 characters
|
||||||
|
if ($globalMaxInputLength -gt 150) {
|
||||||
|
$globalMaxInputLength = 150
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($failure in $filesWithFailures) {
|
||||||
|
Write-Host " $($failure.File):"
|
||||||
|
|
||||||
|
if ($failure.Error) {
|
||||||
|
# Extract cleaner error message
|
||||||
|
$errorMsg = $failure.Error
|
||||||
|
if ($errorMsg -match "at offset (\d+)\. (.+?)\.?`"") {
|
||||||
|
$errorMsg = "offset $($matches[1]): $($matches[2])"
|
||||||
|
}
|
||||||
|
Write-Host " $errorMsg"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
foreach ($detail in $failure.Failures) {
|
||||||
|
if ($detail -match "Input: '(.+?)' - Expected: (\w+), Got: (\w+)") {
|
||||||
|
$input = $matches[1]
|
||||||
|
$expected = $matches[2]
|
||||||
|
$got = $matches[3]
|
||||||
|
|
||||||
|
# Truncate only if longer than 150
|
||||||
|
if ($input.Length -gt 150) {
|
||||||
|
$input = $input.Substring(0, 147) + "..."
|
||||||
|
}
|
||||||
|
|
||||||
|
$paddedInput = $input.PadRight($globalMaxInputLength)
|
||||||
|
Write-Host " $paddedInput | Expected: $expected | Got: $got"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Host "All tests passed"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
# TODO: Run a single unit test given a regular expression and unit test. A unit test includes the input string and whether it should match or not.
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
param(
|
|
||||||
[Parameter(Mandatory=$true)]
|
|
||||||
[string]$YamlFilePath
|
|
||||||
)
|
|
||||||
|
|
||||||
$moduleName = "regex"
|
|
||||||
|
|
||||||
function Write-Log {
|
|
||||||
param(
|
|
||||||
[Parameter(Mandatory=$true)]
|
|
||||||
[string]$Level,
|
|
||||||
[Parameter(Mandatory=$true)]
|
|
||||||
[string]$Message
|
|
||||||
)
|
|
||||||
|
|
||||||
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
|
||||||
$levelPadded = $Level.ToUpper().PadRight(7)
|
|
||||||
$modulePadded = $moduleName.PadRight(0)
|
|
||||||
|
|
||||||
# Write colored level
|
|
||||||
Write-Host -NoNewline "["
|
|
||||||
if ($Level -eq "ERROR") {
|
|
||||||
Write-Host -NoNewline $levelPadded -ForegroundColor Red
|
|
||||||
}
|
|
||||||
elseif ($Level -eq "SUCCESS") {
|
|
||||||
Write-Host -NoNewline $levelPadded -ForegroundColor Green
|
|
||||||
}
|
|
||||||
elseif ($Level -eq "INFO") {
|
|
||||||
Write-Host -NoNewline $levelPadded -ForegroundColor Cyan
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Write-Host -NoNewline $levelPadded
|
|
||||||
}
|
|
||||||
Write-Host -NoNewline "] "
|
|
||||||
|
|
||||||
# Write grey timestamp
|
|
||||||
Write-Host -NoNewline "[$timestamp] " -ForegroundColor DarkGray
|
|
||||||
|
|
||||||
# Write module and message in normal color
|
|
||||||
Write-Host "[$modulePadded] $Message"
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
# Check if file exists
|
|
||||||
if (-not (Test-Path $YamlFilePath)) {
|
|
||||||
Write-Log -Level "ERROR" -Message "YAML file not found: $YamlFilePath"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Read YAML content
|
|
||||||
$yamlContent = Get-Content -Path $YamlFilePath -Raw
|
|
||||||
|
|
||||||
# Extract pattern field from YAML
|
|
||||||
$patternMatch = [regex]::Match($yamlContent, 'pattern:\s*(.+)')
|
|
||||||
$pattern = $patternMatch.Groups[1].Value.Trim()
|
|
||||||
|
|
||||||
Write-Log -Level "INFO" -Message "Found pattern: $pattern"
|
|
||||||
|
|
||||||
# Validate the pattern against .NET regex engine
|
|
||||||
try {
|
|
||||||
$regex = New-Object System.Text.RegularExpressions.Regex($pattern)
|
|
||||||
Write-Log -Level "SUCCESS" -Message "Valid regex pattern"
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
Write-Log -Level "ERROR" -Message "Pattern validation failed: $_"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
Write-Log -Level "ERROR" -Message "Script execution failed: $_"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user