Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions DevSetup/Private/Commands/Update-DevSetup.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
BeforeAll {
# Source the function under test
. $PSScriptRoot\Update-DevSetup.ps1
. $PSScriptRoot\..\Updater\Start-DevSetupSelfUpdate.ps1
Mock Start-DevSetupSelfUpdate { }
}

Describe "Update-DevSetup" {

Context "When Main parameter is specified" {
It "Should call Start-DevSetupSelfUpdate with Main parameter" {
Update-DevSetup -Main
Assert-MockCalled Start-DevSetupSelfUpdate -Exactly 1 -Scope It -ParameterFilter { $Main -eq $true }
}
}

Context "When Develop parameter is specified" {
It "Should call Start-DevSetupSelfUpdate with Develop parameter" {
Update-DevSetup -Develop
Assert-MockCalled Start-DevSetupSelfUpdate -Exactly 1 -Scope It -ParameterFilter { $Develop -eq $true }
}
}

Context "When Version parameter is specified" {
It "Should call Start-DevSetupSelfUpdate with Version parameter" {
Update-DevSetup -Version "1.0.0"
Assert-MockCalled Start-DevSetupSelfUpdate -Exactly 1 -Scope It -ParameterFilter { $Version -eq "1.0.0" }
}
}

Context "When no parameters are specified (default)" {
It "Should call Start-DevSetupSelfUpdate without parameters (letting it use its own defaults)" {
Update-DevSetup
Assert-MockCalled Start-DevSetupSelfUpdate -Exactly 1 -Scope It -ParameterFilter { $PSBoundParameters.Count -eq 0 }
}
}

Context "Parameter set validation" {
It "Should allow Main parameter alone" {
{ Update-DevSetup -Main } | Should -Not -Throw
}

It "Should allow Develop parameter alone" {
{ Update-DevSetup -Develop } | Should -Not -Throw
}

It "Should allow Version parameter alone" {
{ Update-DevSetup -Version "2.0.0" } | Should -Not -Throw
}

It "Should not allow Main and Develop together" {
{ Update-DevSetup -Main -Develop } | Should -Throw
}

It "Should not allow Main and Version together" {
{ Update-DevSetup -Main -Version "1.0.0" } | Should -Throw
}

It "Should not allow Develop and Version together" {
{ Update-DevSetup -Develop -Version "1.0.0" } | Should -Throw
}
}

Context "PSBoundParameters forwarding" {
It "Should forward all parameters using splatting" {
Mock Start-DevSetupSelfUpdate { } -ParameterFilter { $PSBoundParameters.Count -gt 0 }
Update-DevSetup -Version "test"
Assert-MockCalled Start-DevSetupSelfUpdate -Exactly 1 -Scope It
}
}

Context "Cross-platform compatibility" {
It "Should work on Windows" {
Update-DevSetup -Main
Assert-MockCalled Start-DevSetupSelfUpdate -Exactly 1 -Scope It
}

It "Should work on Linux" {
Update-DevSetup -Develop
Assert-MockCalled Start-DevSetupSelfUpdate -Exactly 1 -Scope It
}

It "Should work on macOS" {
Update-DevSetup -Version "1.0.0"
Assert-MockCalled Start-DevSetupSelfUpdate -Exactly 1 -Scope It
}
}
}
29 changes: 6 additions & 23 deletions DevSetup/Private/Commands/Update-DevSetup.ps1
Original file line number Diff line number Diff line change
@@ -1,30 +1,13 @@
Function Update-DevSetup {
[CmdletBinding()]
[CmdletBinding(DefaultParameterSetName="ReleaseInstall")]
Param(
[Parameter(Mandatory=$true, ParameterSetName="Main")]
[Parameter(Mandatory=$true, ParameterSetName="MainWebInstall")]
[switch]$Main,
[Parameter(Mandatory=$true, ParameterSetName="Develop")]
[Parameter(Mandatory=$true, ParameterSetName="DevelopWebInstall")]
[switch]$Develop,
[Parameter(Mandatory=$true, ParameterSetName="Version")]
[string]$Version,
[Parameter(Mandatory=$true, ParameterSetName="Latest")]
[switch]$Latest
[Parameter(Mandatory=$false, ParameterSetName="ReleaseInstall")]
[string]$Version = "latest"
)

$RemoteVersion = Get-DevSetupVersion -Remote
$LocalVersion = Get-DevSetupVersion -Local
if($RemoteVersion -gt $LocalVersion) {
Write-Host "A new version of DevSetup is available: $RemoteVersion (current version: $LocalVersion)" -ForegroundColor Yellow
} elseif ($RemoteVersion -eq $LocalVersion) {
Write-Host "You are already running the latest version of DevSetup: $LocalVersion" -ForegroundColor Green
return
} else {
Write-Host "You are running a newer version of DevSetup ($LocalVersion) than the latest release ($RemoteVersion)" -ForegroundColor Yellow
return
}
Write-Host ""
Write-Host "- Updating list of available environments..." -ForegroundColor Cyan
Optimize-DevSetupEnvs | Out-Null
Write-Host "- Available environments updated successfully" -ForegroundColor Green
Write-Host ""
Start-DevSetupSelfUpdate @PSBoundParameters
}
151 changes: 151 additions & 0 deletions DevSetup/Private/Updater/Expand-DevSetupUpdateArchive.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
BeforeAll {
$global:LASTEXITCODE = 0
Function Expand-Archive {
param (
[string]$Path,
[string]$DestinationPath,
[switch]$Force
)
}

Mock Expand-Archive {
switch($Path) {
(Join-Path $TestDrive "test.zip") {
# Simulate successful expansion
#Write-Output "test.zip expanded successfully"
$global:LASTEXITCODE = 0
return
}
(Join-Path $TestDrive "bad.zip") {
#Write-Output "bad.zip encountered an error"
# Simulate failed expansion
throw "Simulated bad zip"
return
}
(Join-Path $TestDrive "testdest.zip") {
switch($DestinationPath) {
(Join-Path $TestDrive "extracted") {
#Write-Output "testdest.zip expanded successfully"
# Simulate successful extraction
$global:LASTEXITCODE = 0
return
}
(Join-Path $TestDrive "badextract") {
#Write-Output "testdest.zip encountered an error"
# Simulate failed extraction
throw "Simulated bad destination"
return
}
default {
#Write-Output "Invalid destination: $DestinationPath"
# Simulate invalid destination
$global:LASTEXITCODE = 1
throw "Invalid destination: $DestinationPath"
}
}
}
default {
Write-Error "File not found: $Path"
# Simulate file not found
$global:LASTEXITCODE = 1
throw "File not found: $Path"
}
}
# Simulate successful expansion
$global:LASTEXITCODE = 1
}
. $PSScriptRoot\Expand-DevSetupUpdateArchive.ps1
. $PSScriptRoot\..\Utils\Write-StatusMessage.ps1
}

Describe "Expand-DevSetupUpdateArchive" {

Context "When the archive file does not exist" {
It "Should return false and log an error" {
Mock Write-StatusMessage { }
$Archive = (Join-Path $TestDrive "nonexistent.zip")
$result = Expand-DevSetupUpdateArchive -Path $Archive -DestinationPath (Join-Path $TestDrive "temp")
$result | Should -Be $false
Assert-MockCalled Write-StatusMessage -Exactly 1 -Scope It -ParameterFilter {
$Message -match "Archive file not found at path: $([regex]::Escape($Archive))" -and $Verbosity -eq "Error"
}
}
}

Context "When the archive expansion fails" {
It "Should return false and log an error" {
Mock Write-StatusMessage { }
Mock Test-Path { $true } -ParameterFilter { $Path -eq (Join-Path $TestDrive "bad.zip") }
$badArchive = (Join-Path $TestDrive "bad.zip")
$goodDestination = (Join-Path $TestDrive "extracted")
$result = Expand-DevSetupUpdateArchive -Path $badArchive -DestinationPath $goodDestination
$result | Should -Be $false
Assert-MockCalled Expand-Archive -Exactly 1 -Scope It -ParameterFilter {
$Path -eq $badArchive -and $DestinationPath -eq $goodDestination -and $Force
}
Assert-MockCalled Write-StatusMessage -Scope It -ParameterFilter {
$Message -match "Expanding archive file from $([regex]::Escape($badArchive)) to $([regex]::Escape($goodDestination))" -and $Verbosity -eq "Debug"
} -Exactly 1
}
}

Context "When the archive expansion fails with bad destination" {
It "Should return false and log an error" {
Mock Write-StatusMessage { }
Mock Test-Path { $true } -ParameterFilter { $Path -eq (Join-Path $TestDrive "testdest.zip") }
$goodArchive = (Join-Path $TestDrive "testdest.zip")
$badDestination = (Join-Path $TestDrive "badextract")
$result = Expand-DevSetupUpdateArchive -Path $goodArchive -DestinationPath $badDestination
$result | Should -Be $false
Assert-MockCalled Expand-Archive -Exactly 1 -Scope It -ParameterFilter {
$Path -eq $goodArchive -and $DestinationPath -eq $badDestination -and $Force
}
Assert-MockCalled Write-StatusMessage -Scope It -ParameterFilter {
$Message -match "Expanding archive file from $([regex]::Escape($goodArchive)) to $([regex]::Escape($badDestination))" -and $Verbosity -eq "Debug"
} -Exactly 1
}
}

Context "When the archive expansion fails with invalid destination" {
It "Should return false and log an error" {
Mock Write-StatusMessage { }
Mock Test-Path { $true } -ParameterFilter { $Path -eq (Join-Path $TestDrive "testdest.zip") }
$goodArchive = (Join-Path $TestDrive "testdest.zip")
$invalidDestination = (Join-Path $TestDrive "invalid\path")
$result = Expand-DevSetupUpdateArchive -Path $goodArchive -DestinationPath $invalidDestination
$result | Should -Be $false
Assert-MockCalled Expand-Archive -Exactly 1 -Scope It -ParameterFilter {
$Path -eq $goodArchive -and $DestinationPath -eq $invalidDestination -and $Force
}
Assert-MockCalled Write-StatusMessage -Scope It -ParameterFilter {
$Message -match "Expanding archive file from $([regex]::Escape($goodArchive)) to $([regex]::Escape($invalidDestination))" -and $Verbosity -eq "Debug"
} -Exactly 1
Assert-MockCalled Write-StatusMessage -Scope It -ParameterFilter {
$Message -match "Failed to expand archive:" -and $Verbosity -eq "Error"
} -Exactly 1
Assert-MockCalled Write-StatusMessage -Scope It -ParameterFilter {
$Verbosity -eq "Error"
} -Exactly 2
}
}

Context "When the archive expansion succeeds" {
It "Should return true and log debug messages" {
Mock Write-StatusMessage { }
Mock Test-Path { $true } -ParameterFilter { $Path -eq (Join-Path $TestDrive "test.zip") }
$goodArchive = (Join-Path $TestDrive "test.zip")
$goodDestination = (Join-Path $TestDrive "extracted")
$result = Expand-DevSetupUpdateArchive -Path $goodArchive -DestinationPath $goodDestination
$result | Should -Be $true
Assert-MockCalled Expand-Archive -Exactly 1 -Scope It -ParameterFilter {
$Path -eq $goodArchive -and $DestinationPath -eq $goodDestination -and $Force
}
Assert-MockCalled Write-StatusMessage -Scope It -ParameterFilter {
$Message -match "Expanding archive file from $([regex]::Escape($goodArchive)) to $([regex]::Escape($goodDestination))" -and $Verbosity -eq "Debug"
} -Exactly 1
Assert-MockCalled Write-StatusMessage -Scope It -ParameterFilter {
$Message -match "Expansion completed successfully." -and $Verbosity -eq "Debug"
} -Exactly 1
}
}
}
29 changes: 29 additions & 0 deletions DevSetup/Private/Updater/Expand-DevSetupUpdateArchive.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Function Expand-DevSetupUpdateArchive {
[CmdletBinding()]
[OutputType([bool])]
Param(
[Parameter(Mandatory = $true, Position=0)]
[ValidateNotNullOrEmpty()]
[string]$Path,

[Parameter(Mandatory = $true, Position=1)]
[ValidateNotNullOrEmpty()]
[string]$DestinationPath
)

if (-not (Test-Path $Path -ErrorAction SilentlyContinue)) {
Write-StatusMessage "Archive file not found at path: $Path" -Verbosity Error
return $false
}

try {
Write-StatusMessage "Expanding archive file from $Path to $DestinationPath" -Verbosity Debug
Expand-Archive -Path $Path -DestinationPath $DestinationPath -Force
Write-StatusMessage "Expansion completed successfully." -Verbosity Debug
return $true
} catch {
Write-StatusMessage "Failed to expand archive: $_" -Verbosity Error
Write-StatusMessage $_.ScriptStackTrace -Verbosity Error
return $false
}
}
62 changes: 62 additions & 0 deletions DevSetup/Private/Updater/Get-DevSetupModuleInstallPath.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
BeforeAll {
. $PSScriptRoot\Get-DevSetupModuleInstallPath.ps1
. $PSScriptRoot\..\Providers\Powershell\Get-PowershellModuleScopeMap.ps1
. $PSScriptRoot\..\Utils\Write-StatusMessage.ps1
}

Describe "Get-DevSetupModuleInstallPath" {
Context "When DevSetup module is installed in CurrentUser scope" {
It "Should return the correct path" {
$CurrentUserPath = (Join-Path (Join-Path (Join-Path $TestDrive "Documents" ) "PowerShell" ) "Modules")
$AllUsersPath = (Join-Path (Join-Path (Join-Path $TestDrive "ProgramFiles" ) "PowerShell" ) "Modules")
Mock Get-PowershellModuleScopeMap {
return @(
@{ Scope = "CurrentUser"; Path = $CurrentUserPath },
@{ Scope = "AllUsers"; Path = $AllUsersPath }
)
}

$expectedPath = Join-Path -Path $CurrentUserPath -ChildPath "DevSetup"
Mock Test-Path { return $true } -ParameterFilter { $Path -eq $expectedPath }

$result = Get-DevSetupModuleInstallPath
$result | Should -Be $expectedPath
}
}

Context "When DevSetup module is installed in AllUsers scope" {
It "Should return the correct path" {
$CurrentUserPath = (Join-Path (Join-Path (Join-Path $TestDrive "Documents" ) "PowerShell" ) "Modules")
$AllUsersPath = (Join-Path (Join-Path (Join-Path $TestDrive "ProgramFiles" ) "PowerShell" ) "Modules")
Mock Get-PowershellModuleScopeMap {
return @(
@{ Scope = "CurrentUser"; Path = $CurrentUserPath },
@{ Scope = "AllUsers"; Path = $AllUsersPath }
)
}

$expectedPath = Join-Path -Path $AllUsersPath -ChildPath "DevSetup"
Mock Test-Path { return $true } -ParameterFilter { $Path -eq $expectedPath }

$result = Get-DevSetupModuleInstallPath
$result | Should -Be $expectedPath
}
}

Context "When DevSetup module is not installed" {
It "Should return the first scope path if module is not found" {
$CurrentUserPath = (Join-Path (Join-Path (Join-Path $TestDrive "Documents" ) "PowerShell" ) "Modules")
$AllUsersPath = (Join-Path (Join-Path (Join-Path $TestDrive "ProgramFiles" ) "PowerShell" ) "Modules")
Mock Get-PowershellModuleScopeMap {
return @(
@{ Scope = "CurrentUser"; Path = $CurrentUserPath },
@{ Scope = "AllUsers"; Path = $AllUsersPath }
)
}
Mock Test-Path { return $false }
$expectedPath = Join-Path -Path $CurrentUserPath -ChildPath "DevSetup"
$result = Get-DevSetupModuleInstallPath
$result | Should -Be $expectedPath
}
}
}
16 changes: 16 additions & 0 deletions DevSetup/Private/Updater/Get-DevSetupModuleInstallPath.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Function Get-DevSetupModuleInstallPath {
[CmdletBinding()]
Param()

# Get the module scope map
$ScopeMap = Get-PowershellModuleScopeMap

foreach ($Scope in $ScopeMap) {
$PotentialPath = Join-Path -Path $Scope.Path -ChildPath "DevSetup"
if (Test-Path -Path $PotentialPath) {
return $PotentialPath
}
}

return (Join-Path ($ScopeMap | Select-Object -First 1).Path -ChildPath "DevSetup")
}
Loading
Loading