|
| 1 | +$ErrorActionPreference = 'Stop' |
| 2 | + |
| 3 | +function New-TempDir { |
| 4 | + $path = Join-Path ([System.IO.Path]::GetTempPath()) ("cli-fp-codegen-" + [System.Guid]::NewGuid().ToString("N")) |
| 5 | + New-Item -ItemType Directory -Path $path | Out-Null |
| 6 | + return $path |
| 7 | +} |
| 8 | + |
| 9 | +function Normalize-Content([string]$Path) { |
| 10 | + return (Get-Content -Raw $Path) -replace "`r`n", "`n" |
| 11 | +} |
| 12 | + |
| 13 | +function Assert-True([bool]$Condition, [string]$Message) { |
| 14 | + if (-not $Condition) { |
| 15 | + throw $Message |
| 16 | + } |
| 17 | +} |
| 18 | + |
| 19 | +function Write-JsonFile([string]$Path, $Object) { |
| 20 | + $Object | ConvertTo-Json -Depth 20 | Set-Content -Path $Path |
| 21 | +} |
| 22 | + |
| 23 | +$RootDir = (Resolve-Path (Join-Path $PSScriptRoot "..\..")).Path |
| 24 | +$GenSrc = Join-Path $RootDir "tools\cli-fp-gen\cli_fp_gen.lpr" |
| 25 | +$GenExe = Join-Path $RootDir "tools\cli-fp-gen\cli_fp_gen.exe" |
| 26 | +$FixtureDir = Join-Path $RootDir "tests\codegen-fixtures\golden-basic" |
| 27 | +$GoldenDir = Join-Path $RootDir "tests\codegen-golden\golden-basic" |
| 28 | +$TmpDir = New-TempDir |
| 29 | + |
| 30 | +try { |
| 31 | + fpc "-Fu$RootDir\tools\cli-fp-gen\src" $GenSrc | Out-Null |
| 32 | + |
| 33 | + # Golden output check |
| 34 | + $GoldenProject = Join-Path $TmpDir "golden" |
| 35 | + New-Item -ItemType Directory -Force -Path $GoldenProject | Out-Null |
| 36 | + Copy-Item -Force (Join-Path $FixtureDir "clifp.json") (Join-Path $GoldenProject "clifp.json") |
| 37 | + & $GenExe generate --project $GoldenProject | Out-Null |
| 38 | + |
| 39 | + $GoldenFiles = @( |
| 40 | + "src\GoldenDemo.lpr", |
| 41 | + "src\generated\GoldenDemo_CommandRegistry_Generated.pas", |
| 42 | + "src\generated\.clifp-manifest.json", |
| 43 | + "src\commands\GoldenDemo_Command_Greet.pas", |
| 44 | + "src\commands\GoldenDemo_Command_Repo.pas", |
| 45 | + "src\commands\GoldenDemo_Command_RepoClone.pas", |
| 46 | + "src\commands\GoldenDemo_Command_Types.pas" |
| 47 | + ) |
| 48 | + |
| 49 | + foreach ($RelativePath in $GoldenFiles) { |
| 50 | + $Expected = Normalize-Content (Join-Path $GoldenDir $RelativePath) |
| 51 | + $Actual = Normalize-Content (Join-Path $GoldenProject $RelativePath) |
| 52 | + Assert-True ($Expected -eq $Actual) "Golden mismatch: $RelativePath" |
| 53 | + } |
| 54 | + |
| 55 | + Write-Host "Golden test passed" |
| 56 | + |
| 57 | + # Compile smoke check |
| 58 | + fpc ` |
| 59 | + "-Fu$RootDir\src" ` |
| 60 | + "-Fu$GoldenProject\src" ` |
| 61 | + "-Fu$GoldenProject\src\generated" ` |
| 62 | + "-Fu$GoldenProject\src\commands" ` |
| 63 | + (Join-Path $GoldenProject "src\GoldenDemo.lpr") | Out-Null |
| 64 | + |
| 65 | + & (Join-Path $GoldenProject "src\GoldenDemo.exe") --help | Out-Null |
| 66 | + & (Join-Path $GoldenProject "src\GoldenDemo.exe") repo | Out-Null |
| 67 | + |
| 68 | + Write-Host "Compile smoke test passed" |
| 69 | + |
| 70 | + # Operations and path guard check |
| 71 | + $DemoProject = Join-Path $TmpDir "demo" |
| 72 | + & $GenExe init $DemoProject --force | Out-Null |
| 73 | + |
| 74 | + $DryRunOutput = (& $GenExe add command repo --project $DemoProject --description "Repo tools" --dry-run) | Out-String |
| 75 | + Assert-True ($DryRunOutput -match "Demo_Command_Repo\.pas") "Dry-run add did not preview the new command stub" |
| 76 | + Assert-True (-not ((Get-Content -Raw (Join-Path $DemoProject "clifp.json")) -match '"name"\s*:\s*"repo"')) "Dry-run add modified clifp.json" |
| 77 | + Assert-True (-not (Test-Path (Join-Path $DemoProject "src\commands\Demo_Command_Repo.pas"))) "Dry-run add created a command stub" |
| 78 | + |
| 79 | + & $GenExe add command repo --project $DemoProject --description "Repo tools" | Out-Null |
| 80 | + & $GenExe add command clone --parent repo --project $DemoProject --description "Clone repo" | Out-Null |
| 81 | + |
| 82 | + $null = (& $GenExe remove command repo --project $DemoProject 2>&1 | Out-String) |
| 83 | + Assert-True ($LASTEXITCODE -ne 0) "Expected remove command without --cascade to fail" |
| 84 | + |
| 85 | + & $GenExe remove command repo --cascade --project $DemoProject | Out-Null |
| 86 | + Assert-True (-not ((Get-Content -Raw (Join-Path $DemoProject "clifp.json")) -match '"name"\s*:\s*"repo"')) "repo command still present after cascade remove" |
| 87 | + |
| 88 | + $DemoSpec = Get-Content -Raw (Join-Path $DemoProject "clifp.json") | ConvertFrom-Json |
| 89 | + $OldProgramPath = Join-Path $DemoProject $DemoSpec.app.programFile |
| 90 | + Assert-True (Test-Path $OldProgramPath) "Expected original program file to exist after init" |
| 91 | + |
| 92 | + $DemoSpec.app.programFile = "src/DemoRenamed.lpr" |
| 93 | + Write-JsonFile (Join-Path $DemoProject "clifp.json") $DemoSpec |
| 94 | + & $GenExe generate --project $DemoProject | Out-Null |
| 95 | + |
| 96 | + Assert-True (Test-Path (Join-Path $DemoProject "src\DemoRenamed.lpr")) "Renamed program file was not generated" |
| 97 | + Assert-True (-not (Test-Path $OldProgramPath)) "Old generated program file was not removed by manifest cleanup" |
| 98 | + Assert-True ((Get-Content -Raw (Join-Path $DemoProject "src\generated\.clifp-manifest.json")) -match "src/DemoRenamed\.lpr") "Manifest did not track renamed program file" |
| 99 | + |
| 100 | + $DescriptionsProject = Join-Path $TmpDir "descriptions" |
| 101 | + & $GenExe init $DescriptionsProject --force | Out-Null |
| 102 | + & $GenExe add command repo --project $DescriptionsProject --description "Owner's tools" | Out-Null |
| 103 | + |
| 104 | + $DescriptionsSpec = Get-Content -Raw (Join-Path $DescriptionsProject "clifp.json") | ConvertFrom-Json |
| 105 | + foreach ($Command in $DescriptionsSpec.commands) { |
| 106 | + if ($Command.name -eq "repo") { |
| 107 | + $Command.description = "Repo team's tools" |
| 108 | + } |
| 109 | + } |
| 110 | + Write-JsonFile (Join-Path $DescriptionsProject "clifp.json") $DescriptionsSpec |
| 111 | + & $GenExe generate --project $DescriptionsProject | Out-Null |
| 112 | + |
| 113 | + $ProgramPath = Join-Path $DescriptionsProject $DescriptionsSpec.app.programFile |
| 114 | + fpc ` |
| 115 | + "-Fu$RootDir\src" ` |
| 116 | + "-Fu$DescriptionsProject\src" ` |
| 117 | + "-Fu$DescriptionsProject\src\generated" ` |
| 118 | + "-Fu$DescriptionsProject\src\commands" ` |
| 119 | + $ProgramPath | Out-Null |
| 120 | + |
| 121 | + $ExePath = [System.IO.Path]::ChangeExtension($ProgramPath, ".exe") |
| 122 | + $HelpOutput = (& $ExePath repo --help) | Out-String |
| 123 | + Assert-True ($HelpOutput -match "Repo team's tools") "Regenerated command description did not update runtime help" |
| 124 | + |
| 125 | + $PathGuardProject = Join-Path $TmpDir "path-guard" |
| 126 | + & $GenExe init $PathGuardProject --force | Out-Null |
| 127 | + |
| 128 | + $PathGuardSpec = Get-Content -Raw (Join-Path $PathGuardProject "clifp.json") | ConvertFrom-Json |
| 129 | + $PathGuardSpec.app.programFile = "../outside/Escape.lpr" |
| 130 | + Write-JsonFile (Join-Path $PathGuardProject "clifp.json") $PathGuardSpec |
| 131 | + |
| 132 | + $null = (& $GenExe generate --project $PathGuardProject 2>&1 | Out-String) |
| 133 | + Assert-True ($LASTEXITCODE -ne 0) "Expected invalid programFile path to fail validation" |
| 134 | + Assert-True (-not (Test-Path (Join-Path $TmpDir "outside\Escape.lpr"))) "Generator wrote a program file outside the project directory" |
| 135 | + |
| 136 | + Write-Host "Ops test passed" |
| 137 | +} |
| 138 | +finally { |
| 139 | + if (Test-Path $TmpDir) { |
| 140 | + Remove-Item -Recurse -Force $TmpDir |
| 141 | + } |
| 142 | +} |
0 commit comments