tests/New-DFInstallPlan.Tests.ps1
|
BeforeAll { . "$PSScriptRoot/TestSupport.ps1" foreach ($f in Get-DFTestModuleFile) { . $f } function script:Rec([string]$Json) { ConvertTo-DFToolRecord ($Json | ConvertFrom-Json) } function script:New-ChainDb { $db = @{} foreach ($r in @( (Rec '{ "name": "scoop", "executable": "scoop.cmd", "roles": { "package-manager": { "priority": 30 } }, "installs": { "from": "scoop", "command": ["scoop","install","{id}"], "batch": true } }'), (Rec '{ "name": "fnm", "executable": "fnm.exe", "packages": { "scoop": "fnm" }, "roles": { "version-manager": {} }, "installs": { "from": "fnm", "command": ["fnm","install","{id}"], "reactivate": true } }'), (Rec '{ "name": "node", "executable": "node.exe", "packages": { "fnm": "lts", "scoop": "nodejs-lts" }, "install": { "prefer": ["fnm"] }, "roles": { "js-runtime": {} } }'), (Rec '{ "name": "npm", "executable": "npm.cmd", "requires": ["node"], "roles": { "js-package-manager": { "priority": 30 } }, "installs": { "from": "npm", "command": ["npm","i","-g","{id}"], "batch": true } }'), (Rec '{ "name": "ish", "executable": "is.cmd", "packages": { "npm": "@microsoft/inshellisense" } }'), (Rec '{ "name": "glow", "executable": "glow.exe", "packages": { "scoop": "glow" } }') )) { $db[$r.name] = $r } $db } # Only scoop is installed on this "fresh machine". $script:OnlyScoop = { param($m) $m.name -eq 'scoop' } } Describe 'New-DFInstallPlan' { BeforeEach { Set-DFTestConfig $null; $script:Db = New-ChainDb; Mock Test-DFElevated { $false } } AfterEach { Set-DFTestConfig $null } It 'stages the scoop -> fnm -> node -> npm -> ish chain when all are requested' { $p = New-DFInstallPlan -Name fnm, node, npm, ish -ToolDb $script:Db -IsAvailable $script:OnlyScoop ($p.Items | Where-Object Tool -eq fnm).Stage | Should -Be 1 ($p.Items | Where-Object Tool -eq node).Stage | Should -Be 2 ($p.Items | Where-Object Tool -eq node).Source | Should -Be 'fnm' ($p.Items | Where-Object Tool -eq npm).ProvidedBy | Should -Be 'node' ($p.Items | Where-Object Tool -eq npm).Stage | Should -Be 3 ($p.Items | Where-Object Tool -eq ish).Stage | Should -Be 4 $p.Gaps | Should -BeNullOrEmpty } It 'groups one stage''s tools into one batch per manager' { $p = New-DFInstallPlan -Name fnm, glow -ToolDb $script:Db -IsAvailable $script:OnlyScoop $p.Stages.Count | Should -Be 1 $p.Stages[0].Batches.Count | Should -Be 1 $p.Stages[0].Batches[0].Manager.name | Should -Be 'scoop' @($p.Stages[0].Batches[0].Items.Tool) | Should -Be @('fnm', 'glow') } It 'never adds an unrequested manager: a gap names it and the tools that wait on it' { $p = New-DFInstallPlan -Name ish -ToolDb $script:Db -IsAvailable $script:OnlyScoop $p.Items | Should -BeNullOrEmpty $p.Gaps[0].Tool | Should -Be 'ish' $p.Gaps[0].Options | Should -Be @('npm') } It 'adds a manager the user chose for a gap, with what it needs' { $p = New-DFInstallPlan -Name ish, fnm, node -ToolDb $script:Db -IsAvailable $script:OnlyScoop -Choice @{ npm = 'npm' } ($p.Items | Where-Object Tool -eq npm).ProvidedBy | Should -Be 'node' ($p.Items | Where-Object Tool -eq ish).DependsOn | Should -Contain 'npm' } It 'says a chosen manager comes with a runtime that isn''t planned' { $p = New-DFInstallPlan -Name ish -ToolDb $script:Db -IsAvailable $script:OnlyScoop -Choice @{ npm = 'npm' } ($p.Gaps | Where-Object Tool -eq npm).Reason | Should -Match 'comes with node.*add node' } It 'falls back past a preferred source whose manager is neither installed nor requested' { $p = New-DFInstallPlan -Name node, npm, ish -ToolDb $script:Db -IsAvailable $script:OnlyScoop # node prefers fnm, which isn't installed or requested, so scoop installs it; npm comes with it. ($p.Items | Where-Object Tool -eq node).Source | Should -Be 'scoop' $p.Gaps | Should -BeNullOrEmpty } It 'names the requested tools that wait on a gap' { $db = New-ChainDb $db.ishplug = Rec '{ "name": "ishplug", "executable": "ip.cmd", "requires": ["ish"], "packages": { "scoop": "ishplug" } }' $p = New-DFInstallPlan -Name ish, ishplug -ToolDb $db -IsAvailable $script:OnlyScoop ($p.Gaps | Where-Object Tool -eq ish).Dependents | Should -Contain 'ishplug' $p.Items.Tool | Should -Not -Contain 'ishplug' } } Describe 'New-DFInstallPlan and elevation' { BeforeEach { Set-DFTestConfig @{ InstallVia = @{ glow = 'choco' } } Mock Test-DFElevated { $false } $script:Db = New-ChainDb $script:Db.choco = Rec '{ "name": "choco", "executable": "choco.exe", "roles": { "package-manager": { "priority": 10 } }, "installs": { "from": "choco", "command": ["choco","install","{id}","-y"], "batch": true, "elevate": true } }' $script:Db.gsudo = Rec '{ "name": "gsudo", "executable": "gsudo.exe", "roles": { "elevator": {} }, "packages": { "scoop": "gsudo" } }' $script:Db.glow = Rec '{ "name": "glow", "executable": "glow.exe", "packages": { "choco": "glow", "scoop": "glow" } }' } AfterEach { Set-DFTestConfig $null } It 'skips a manager that needs admin when nothing can elevate, and uses the next source' { $p = New-DFInstallPlan -Name glow -ToolDb $script:Db -IsAvailable { param($m) $m.name -in 'scoop', 'choco' } ($p.Items | Where-Object Tool -eq glow).Source | Should -Be 'scoop' } It 'plans it through an installed elevator, and says so' { $p = New-DFInstallPlan -Name glow -ToolDb $script:Db -IsAvailable { param($m) $m.name -in 'scoop', 'choco', 'gsudo' } $b = $p.Stages[0].Batches[0] $b.Manager.name | Should -Be 'choco' $b.Elevate | Should -BeTrue $b.ElevateWith | Should -Be 'gsudo.exe' } It 'makes it wait for an elevator installed in the same run' { $p = New-DFInstallPlan -Name gsudo, glow -ToolDb $script:Db -IsAvailable { param($m) $m.name -in 'scoop', 'choco' } ($p.Items | Where-Object Tool -eq glow).Source | Should -Be 'choco' ($p.Items | Where-Object Tool -eq glow).DependsOn | Should -Contain 'gsudo' } It 'needs no elevator when the shell is already elevated' { Mock Test-DFElevated { $true } $p = New-DFInstallPlan -Name glow -ToolDb $script:Db -IsAvailable { param($m) $m.name -in 'scoop', 'choco' } $p.Stages[0].Batches[0].Manager.name | Should -Be 'choco' $p.Stages[0].Batches[0].Elevate | Should -BeFalse } } |