test/qbuild-cache.tests.ps1
|
BeforeAll { $script:discoveryCacheEnvBackup = (Get-Item -Path env:QCONF_DiscoveryCache -ErrorAction SilentlyContinue).Value $script:discoveryCacheLocationEnvBackup = (Get-Item -Path env:QCONF_DiscoveryCacheLocation -ErrorAction SilentlyContinue).Value Remove-Item -Path env:QCONF_DiscoveryCache -ErrorAction SilentlyContinue Remove-Item -Path env:QCONF_DiscoveryCacheLocation -ErrorAction SilentlyContinue Get-Module ConfigMap -ErrorAction SilentlyContinue | Remove-Module Import-Module $PSScriptRoot\..\configmap.psm1 -Force } AfterAll { Remove-Item -Path env:QCONF_DiscoveryCache -ErrorAction SilentlyContinue Remove-Item -Path env:QCONF_DiscoveryCacheLocation -ErrorAction SilentlyContinue if ($null -ne $script:discoveryCacheEnvBackup) { Set-Item -Path env:QCONF_DiscoveryCache -Value $script:discoveryCacheEnvBackup } if ($null -ne $script:discoveryCacheLocationEnvBackup) { Set-Item -Path env:QCONF_DiscoveryCacheLocation -Value $script:discoveryCacheLocationEnvBackup } & (Get-Module ConfigMap) { Update-ConfigMapSettings | Out-Null } } Describe 'qbuild !cache' { BeforeEach { & (Get-Module ConfigMap) { Clear-ConfigMapDiscoveryCacheMemory } $script:tempRoot = Join-Path $TestDrive "qbuild-cache-$(New-Guid)" New-Item -ItemType Directory -Force -Path $script:tempRoot | Out-Null @' @{ build = @{ exec = { "build" } description = "Build" } clean = { "clean" } } '@ | Set-Content -Path (Join-Path $script:tempRoot '.build.map.ps1') } It 'returns status for the local map after a cache miss has written the file' { Push-Location $script:tempRoot try { $null = qbuild list $result = qbuild '!cache' -Porcelain $result.Action | Should -Be 'status' $result.Enabled | Should -BeTrue $result.Location | Should -Be 'local' $result.Exists | Should -BeTrue $result.Valid | Should -BeTrue $result.Source | Should -Be 'memory' $result.Language | Should -Be 'build' $result.Path | Should -Be (Join-Path $script:tempRoot '.configmap\discovery.build.cache.json') $result.EntryCount | Should -BeGreaterThan 0 Test-Path $result.Path | Should -BeTrue } finally { Pop-Location } } It 'bare !cache matches !cache.status' { Push-Location $script:tempRoot try { $null = qbuild list $implicit = qbuild '!cache' -Porcelain $explicit = qbuild '!cache.status' -Porcelain $implicit.Action | Should -Be 'status' $explicit.Action | Should -Be 'status' $explicit.Path | Should -Be $implicit.Path } finally { Pop-Location } } It 'clears the JSON file and later status shows Exists = $false' { Push-Location $script:tempRoot try { $null = qbuild list $cachePath = Join-Path $script:tempRoot '.configmap\discovery.build.cache.json' Test-Path $cachePath | Should -BeTrue $cleared = qbuild '!cache.clear' -Porcelain $cleared.Action | Should -Be 'clear' $cleared.Exists | Should -BeFalse $cleared.Valid | Should -BeFalse $cleared.Source | Should -Be 'none' Test-Path $cachePath | Should -BeFalse $status = qbuild '!cache' -Porcelain $status.Exists | Should -BeFalse $status.Source | Should -Be 'none' } finally { Pop-Location } } It 'rebuilds after a map edit so new entries appear' { Push-Location $script:tempRoot try { $null = qbuild list $before = qbuild '!cache' -Porcelain Set-Content -Path (Join-Path $script:tempRoot '.build.map.ps1') -Value @' @{ build = { "build" } clean = { "clean" } test = { "test" } } '@ $rebuilt = qbuild '!cache.rebuild' -Porcelain $rebuilt.Action | Should -Be 'rebuild' $rebuilt.Exists | Should -BeTrue $rebuilt.Valid | Should -BeTrue $rebuilt.Source | Should -Be 'memory' $rebuilt.EntryCount | Should -BeGreaterThan $before.EntryCount $cache = Get-Content -LiteralPath $rebuilt.Path -Raw | ConvertFrom-Json @($cache.entries.hierarchical).key | Should -Contain 'test' } finally { Pop-Location } } It 'prints a summary and returns nothing without -Porcelain' { Push-Location $script:tempRoot try { $null = qbuild list $cachePath = Join-Path $script:tempRoot '.configmap\discovery.build.cache.json' qbuild '!cache' 6>$null | Should -BeNullOrEmpty $status = qbuild '!cache' 6>&1 | Out-String $status | Should -Match 'Discovery cache' $status | Should -Match 'valid \(memory\)' $status | Should -Match ([regex]::Escape($cachePath)) $status | Should -Match 'Entries' $rebuilt = qbuild '!cache.rebuild' 6>&1 | Out-String $rebuilt | Should -Match 'Discovery cache rebuilt' $cleared = qbuild '!cache.clear' 6>&1 | Out-String $cleared | Should -Match 'Discovery cache cleared' $cleared | Should -Match 'missing' $cleared | Should -Not -Match 'Entries' Test-Path $cachePath | Should -BeFalse } finally { Pop-Location } } It 'rejects the old action forms instead of falling back to status' { Push-Location $script:tempRoot try { $null = qbuild list $cachePath = Join-Path $script:tempRoot '.configmap\discovery.build.cache.json' { qbuild '!cache' 'clear' } | Should -Throw -ExpectedMessage '*!cache.clear*' { qbuild '!cache' -Action clear } | Should -Throw -ExpectedMessage '*!cache.clear*' Test-Path $cachePath | Should -BeTrue } finally { Pop-Location } } It 'rejects extra arguments on subcommands' { Push-Location $script:tempRoot try { { qbuild '!cache.clear' 'rebuild' } | Should -Throw -ExpectedMessage '*takes no arguments*' } finally { Pop-Location } } It 'throws when map is missing' { $emptyDir = Join-Path $TestDrive 'no-map-cache' New-Item -ItemType Directory -Force -Path $emptyDir | Out-Null Push-Location $emptyDir try { { qbuild '!cache' } | Should -Throw -ExpectedMessage '*No build map file found*' } finally { Pop-Location } } It 'includes !cache in entry completions when a map exists' { Push-Location $script:tempRoot try { $line = 'qbuild ' $completions = (TabExpansion2 $line $line.Length).CompletionMatches.CompletionText $completions | Should -Contain '!cache' } finally { Pop-Location } } It 'includes !cache in entry completions without a build map' { $emptyDir = Join-Path $TestDrive 'no-map-cache-complete' New-Item -ItemType Directory -Force -Path $emptyDir | Out-Null Push-Location $emptyDir try { $line = 'qbuild !ca' $completions = (TabExpansion2 $line $line.Length).CompletionMatches.CompletionText $completions | Should -Contain '!cache' } finally { Pop-Location } } It 'includes !cache subcommands in entry completions' { Push-Location $script:tempRoot try { $line = 'qbuild !cache.' $completions = (TabExpansion2 $line $line.Length).CompletionMatches.CompletionText $completions | Should -Be @('!cache.status', '!cache.clear', '!cache.rebuild') } finally { Pop-Location } } It 'exposes only -Porcelain for <key>' -ForEach @( @{ key = '!cache' } @{ key = '!cache.status' } @{ key = '!cache.clear' } @{ key = '!cache.rebuild' } ) { InModuleScope ConfigMap -Parameters @{ key = $key } { $map = Merge-ConfigMapCommands -Language build $params = Get-EntryDynamicParam -map $map -key $key -command exec @($params.Keys) | Should -Be @('Porcelain') $params['Porcelain'].ParameterType | Should -Be ([switch]) } } It 'reports user cache path when DiscoveryCacheLocation is user' { $userHome = Join-Path $TestDrive 'qbuild-cache-user-home' New-Item -ItemType Directory -Force -Path $userHome | Out-Null Set-Content -Path (Join-Path $script:tempRoot '.build.map.ps1') -Value @' @{ _settings = @{ DiscoveryCacheLocation = 'user' } build = { "build" } } '@ $previousHome = $env:HOME $env:HOME = $userHome Push-Location $script:tempRoot try { $result = qbuild '!cache.rebuild' -Porcelain $result.Location | Should -Be 'user' $result.Exists | Should -BeTrue $result.Path | Should -Match '\\.configmap\\' $result.Path | Should -BeLike "$userHome*" Test-Path (Join-Path $script:tempRoot '.configmap') | Should -BeFalse } finally { Pop-Location if ($null -eq $previousHome) { Remove-Item env:HOME -ErrorAction SilentlyContinue } else { $env:HOME = $previousHome } } } It 'reports Enabled = $false, throws on rebuild, and still clears leftover files when disabled' { Push-Location $script:tempRoot try { $null = qbuild list $cachePath = Join-Path $script:tempRoot '.configmap\discovery.build.cache.json' Test-Path $cachePath | Should -BeTrue $previous = $env:QCONF_DiscoveryCache $env:QCONF_DiscoveryCache = '0' try { & (Get-Module ConfigMap) { Update-ConfigMapSettings | Out-Null } $status = qbuild '!cache' -Porcelain $status.Enabled | Should -BeFalse $status.Exists | Should -BeTrue { qbuild '!cache.rebuild' } | Should -Throw -ExpectedMessage '*disabled*' $cleared = qbuild '!cache.clear' -Porcelain $cleared.Enabled | Should -BeFalse $cleared.Exists | Should -BeFalse Test-Path $cachePath | Should -BeFalse } finally { if ($null -eq $previous) { Remove-Item env:QCONF_DiscoveryCache -ErrorAction SilentlyContinue } else { $env:QCONF_DiscoveryCache = $previous } & (Get-Module ConfigMap) { Update-ConfigMapSettings | Out-Null } } } finally { Pop-Location } } } |