functions/Resolve-ExtensionDuplicates.Tests.ps1
|
# <copyright file="Resolve-ExtensionDuplicates.Tests.ps1" company="Endjin Limited"> # Copyright (c) Endjin Limited. All rights reserved. # </copyright> BeforeAll { # sut . $PSCommandPath.Replace('.Tests.ps1','.ps1') } Describe 'Resolve-ExtensionDuplicates' { BeforeAll { Mock Write-Warning {} } Context 'When there are no duplicate extensions' { It 'Returns all extensions and does not warn' { $extensions = @( @{ Name = 'ZeroFailed.Build.PowerShell'; Path = '/zf/ZeroFailed.Build.PowerShell/main' } @{ Name = 'ZeroFailed.Build.Common'; Path = '/zf/ZeroFailed.Build.Common/main' } ) [array]$result = Resolve-ExtensionDuplicates -Extensions $extensions $result.Count | Should -Be 2 Should -Invoke Write-Warning -Times 0 -Exactly } } Context 'When the same extension is referenced more than once at the same version' { It 'De-duplicates without warning (the issue scenario)' { # Two top-level extensions both depend on the same version of a shared extension, # which therefore resolves to the same Path. $extensions = @( @{ Name = 'ZeroFailed.Build.PowerShell'; Path = '/zf/ZeroFailed.Build.PowerShell/main' } @{ Name = 'ZeroFailed.Build.Common'; Path = '/zf/ZeroFailed.Build.Common/main' } @{ Name = 'ZeroFailed.Build.GitHub'; Path = '/zf/ZeroFailed.Build.GitHub/main' } @{ Name = 'ZeroFailed.Build.Common'; Path = '/zf/ZeroFailed.Build.Common/main' } ) [array]$result = Resolve-ExtensionDuplicates -Extensions $extensions $result.Count | Should -Be 3 @($result | Where-Object { $_.Name -eq 'ZeroFailed.Build.Common' }).Count | Should -Be 1 Should -Invoke Write-Warning -Times 0 -Exactly } } Context 'When the same extension is resolved to different versions' { It 'Keeps the first one found' { $extensions = @( @{ Name = 'ZeroFailed.Build.Common'; Version = '1.0.0'; Path = '/zf/ZeroFailed.Build.Common/1.0.0' } @{ Name = 'ZeroFailed.Build.GitHub'; Path = '/zf/ZeroFailed.Build.GitHub/main' } @{ Name = 'ZeroFailed.Build.Common'; Version = '2.0.0'; Path = '/zf/ZeroFailed.Build.Common/2.0.0' } ) [array]$result = Resolve-ExtensionDuplicates -Extensions $extensions $common = @($result | Where-Object { $_.Name -eq 'ZeroFailed.Build.Common' }) $common.Count | Should -Be 1 $common[0].Path | Should -Be '/zf/ZeroFailed.Build.Common/1.0.0' } It 'Warns exactly once, naming the extension' { $extensions = @( @{ Name = 'ZeroFailed.Build.Common'; Version = '1.0.0'; Path = '/zf/ZeroFailed.Build.Common/1.0.0' } @{ Name = 'ZeroFailed.Build.GitHub'; Path = '/zf/ZeroFailed.Build.GitHub/main' } @{ Name = 'ZeroFailed.Build.Common'; Version = '2.0.0'; Path = '/zf/ZeroFailed.Build.Common/2.0.0' } ) Resolve-ExtensionDuplicates -Extensions $extensions | Out-Null Should -Invoke Write-Warning -Times 1 -Exactly -ParameterFilter { $Message -like '*ZeroFailed.Build.Common*' } } It 'Lists both the winning and the ignored paths in the warning' { $extensions = @( @{ Name = 'ZeroFailed.Build.Common'; Version = '1.0.0'; Path = '/zf/ZeroFailed.Build.Common/1.0.0' } @{ Name = 'ZeroFailed.Build.GitHub'; Path = '/zf/ZeroFailed.Build.GitHub/main' } @{ Name = 'ZeroFailed.Build.Common'; Version = '2.0.0'; Path = '/zf/ZeroFailed.Build.Common/2.0.0' } ) Resolve-ExtensionDuplicates -Extensions $extensions | Out-Null Should -Invoke Write-Warning -Times 1 -Exactly -ParameterFilter { $Message -like '*ZeroFailed.Build.Common/1.0.0*' -and $Message -like '*ZeroFailed.Build.Common/2.0.0*' } } } Context 'When there is a mix of conflicting and non-conflicting duplicates' { BeforeAll { $extensions = @( @{ Name = 'ZeroFailed.Build.Common'; Path = '/zf/ZeroFailed.Build.Common/main' } # shared, same version @{ Name = 'ZeroFailed.DevOps.Common'; Version = '1.0.0'; Path = '/zf/ZeroFailed.DevOps.Common/1.0.0' } # conflict @{ Name = 'ZeroFailed.Build.Common'; Path = '/zf/ZeroFailed.Build.Common/main' } # shared, same version @{ Name = 'ZeroFailed.DevOps.Common'; Version = '2.0.0'; Path = '/zf/ZeroFailed.DevOps.Common/2.0.0' } # conflict ) } It 'De-duplicates every extension by name' { [array]$result = Resolve-ExtensionDuplicates -Extensions $extensions $result.Count | Should -Be 2 } It 'Warns only for the genuinely conflicting extension' { Resolve-ExtensionDuplicates -Extensions $extensions | Out-Null Should -Invoke Write-Warning -Times 1 -Exactly Should -Invoke Write-Warning -Times 1 -Exactly -ParameterFilter { $Message -like '*ZeroFailed.DevOps.Common*' } } } Context 'When given a single extension' { It 'Returns it unchanged without warning' { $extensions = @( @{ Name = 'ZeroFailed.Build.Common'; Path = '/zf/ZeroFailed.Build.Common/main' } ) [array]$result = Resolve-ExtensionDuplicates -Extensions $extensions $result.Count | Should -Be 1 Should -Invoke Write-Warning -Times 0 -Exactly } } Context 'When given an empty collection' { It 'Returns nothing without warning' { [array]$result = Resolve-ExtensionDuplicates -Extensions @() $result.Count | Should -Be 0 Should -Invoke Write-Warning -Times 0 -Exactly } } } |