/
githubmirror
/
PowerShell
Обзор
Документация
Войти
/
githubmirror
/
PowerShell
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
test/powershell/Modules/Microsoft.PowerShell.Utility/Measure-Object.Tests.ps1
458 строк
17 KB
KiwiThePoodle
Make `Measure-Object` ignore missing properties unless running in strict mode (#16589)
13 янв 2022, 20:33
Не верифицирован
13 янв 2022, 20:33
83a809b
Код
Авторство
О чём код?
# Copyright (c) Microsoft Corporation. # Licensed under the MIT License. Describe "Measure-Object" -Tags "CI" { BeforeAll { $testObject = 1,3,4 $testObject2 = 1..100 } It "Should be able to be called without error" { { Measure-Object | Out-Null } | Should -Not -Throw } It "Should be able to call on piped input" { { $testObject | Measure-Object } | Should -Not -Throw } It "Should be able to count the number of objects input to it" { $($testObject | Measure-Object).Count | Should -Be $testObject.Length } It "Should calculate Standard Deviation" { $actual = ($testObject | Measure-Object -StandardDeviation) # We check this way since .StandardDeviation returns a double value # 1.52752523165195 was calculated outside powershell using formula from # http://mathworld.wolfram.com/StandardDeviation.html [Math]::abs($actual.StandardDeviation - 1.52752523165195) | Should -BeLessThan .00000000000001 } It "Should calculate Standard Deviation" { $actual = ($testObject2 | Measure-Object -StandardDeviation) # We check this way since .StandardDeviation returns a double value # 29.011491975882 was calculated outside powershell using formula from # http://mathworld.wolfram.com/StandardDeviation.html [Math]::abs($actual.StandardDeviation - 29.011491975882) | Should -BeLessThan .0000000000001 } It "Should calculate Standard Deviation with -Sum" { $actual = ($testObject | Measure-Object -Sum -StandardDeviation) # We check this way since .StandardDeviation returns a double value $actual.Sum | Should -Be 8 # 1.52752523165195 was calculated outside powershell using formula from # http://mathworld.wolfram.com/StandardDeviation.html [Math]::abs($actual.StandardDeviation - 1.52752523165195) | Should -BeLessThan .00000000000001 } It "Should calculate Standard Deviation with -Average" { $actual = ($testObject | Measure-Object -Average -StandardDeviation) # We check this way since .StandardDeviation returns a double value [Math]::abs($actual.Average - 2.66666666666667) | Should -BeLessThan .00000000000001 # 1.52752523165195 was calculated outside powershell using formula from # http://mathworld.wolfram.com/StandardDeviation.html [Math]::abs($actual.StandardDeviation - 1.52752523165195) | Should -BeLessThan .00000000000001 } It "Should calculate Standard Deviation with -Sum -Average" { $actual = ($testObject2 | Measure-Object -Sum -Average -StandardDeviation) # We check this way since .StandardDeviation returns a double value $actual.Sum | Should -Be 5050 $actual.Average | Should -Be 50.5 # 29.011491975882 was calculated outside powershell using formula from # http://mathworld.wolfram.com/StandardDeviation.html [Math]::abs($actual.StandardDeviation - 29.011491975882) | Should -BeLessThan .0000000000001 } It "Should be able to count using the Property switch" { $items = @( [pscustomobject]@{ X = 'a'; Y = 'b' } [pscustomobject]@{ X = 'c' } [pscustomobject]@{ X = 'e'; Y = 'f' } ) ($items | Measure-Object -Property Y).Count | Should -Be 2 } It "Should be able to use wildcards for the Property argument" { $data = [pscustomobject]@{ A1 = 1; A2 = 2; C3 = 3 }, [pscustomobject]@{ A1 = 1; A2 = 2; A3 = 3 } $actual = $data | Measure-Object -Property A* -Sum $actual.Count | Should -Be 3 $actual[0].Property | Should -Be A1 $actual[0].Sum | Should -Be 2 $actual[0].Count | Should -Be 2 $actual[1].Property | Should -Be A2 $actual[1].Sum | Should -Be 4 $actual[1].Count | Should -Be 2 $actual[2].Property | Should -Be A3 $actual[2].Sum | Should -Be 3 $actual[2].Count | Should -Be 1 } Context "Numeric tests" { It "Should be able to sum" { $actual = $testObject | Measure-Object -Sum $expected = 0 foreach ( $obj in $testObject ) { $expected += $obj } $actual.Sum | Should -Be $expected } It "Should be able to average" { $actual = $testObject | Measure-Object -Average $expected = 0 foreach ( $obj in $testObject ) { $expected += $obj } $expected /= $testObject.length $actual.Average | Should -Be $expected } It "Should be able to return a minimum" { $actual = $testObject | Measure-Object -Minimum $expected = $testObject[0] for ($i=0; $i -lt $testObject.length; $i++) { if ( $testObject[$i] -lt $expected ) { $expected = $testObject[$i] } } $actual.Minimum | Should -Be $expected } It "Should be able to return a minimum when multiple objects are the minimum" { $testMinimum = 1,1,2,4 $actual = $testMinimum | Measure-Object -Minimum $expected = $testMinimum[0] for ($i=1; $i -lt $testMinimum.length; $i++) { if ( $testMinimum[$i] -lt $expected ) { $expected = $testMinimum[$i] } } $actual.Minimum | Should -Be $expected } It "Should be able to return a maximum" { $actual = $testObject | Measure-Object -Maximum $expected = $testObject[0] for ($i=1; $i -lt $testObject.length; $i++) { if ( $testObject[$i] -gt $expected ) { $expected = $testObject[$i] } } $actual.Maximum | Should -Be $expected } It "Should be able to return a maximum when multiple objects are the maximum" { $testMaximum = 1,3,5,5 $actual = $testMaximum | Measure-Object -Maximum $expected = $testMaximum[0] for ($i=1; $i -lt $testMaximum.length; $i++) { if ( $testMaximum[$i] -gt $expected ) { $expected = $testMaximum[$i] } } $actual.Maximum | Should -Be $expected } It "Should be able to return all the statitics for given values" { $result = 1..10 | Measure-Object -AllStats $result.Count | Should -Be 10 $result.Average | Should -Be 5.5 $result.Sum | Should -Be 55 $result.Minimum | Should -Be 1 $result.Maximum | Should -Be 10 ($result.StandardDeviation).ToString() | Should -Be '3.0276503540974917' } } Context "Empty folder tests" { BeforeAll { $repoPath = Join-Path -Path $TESTDRIVE -ChildPath "my_folder" $testEmptyFolder = New-Item $repoPath -ItemType "directory" $propertyName = "Length" } AfterAll { Set-StrictMode -off } It "Should not throw an invalid property error when not in StrictMode" { { Set-StrictMode -off; Get-Item $testEmptyFolder | Measure-Object $propertyName -ErrorAction Stop -sum } | Should -Not -Throw } It "Should throw an invalid property error when in StrictMode" { { Set-StrictMode -version 3.0; Get-Item $testEmptyFolder | Measure-Object $propertyName -ErrorAction Stop -sum } | Should -Throw -ErrorId 'GenericMeasurePropertyNotFound,Microsoft.PowerShell.Commands.MeasureObjectCommand' } } Context "String tests" { BeforeAll { $nl = [Environment]::NewLine $testString = "HAD I the heavens' embroidered cloths,$nl Enwrought with golden and silver light,$nl The blue and the dim and the dark cloths$nl Of night and light and the half light,$nl I would spread the cloths under your feet:$nl But I, being poor, have only my dreams;$nl I have spread my dreams under your feet;$nl Tread softly because you tread on my dreams." } It "Should be able to count the number of words in a string" { $expectedLength = $testString.Replace($nl,"").Split().length $actualLength = $testString | Measure-Object -Word $actualLength.Words | Should -Be $expectedLength } It "Should be able to count the number of characters in a string" { $expectedLength = $testString.length $actualLength = $testString | Measure-Object -Character $actualLength.Characters | Should -Be $expectedLength } It "Should be able to count the number of lines in a string" { $expectedLength = $testString.Split($nl, [System.StringSplitOptions]::RemoveEmptyEntries).length $actualLength = $testString | Measure-Object -Line $actualLength.Lines | Should -Be $expectedLength } } } Describe "Measure-Object DRT basic functionality" -Tags "CI" { BeforeAll { if(-not ([System.Management.Automation.PSTypeName]'TestMeasureGeneric').Type) { Add-Type -TypeDefinition @" [System.Flags] public enum TestMeasureGeneric : uint { TestSum = 1, TestAverage = 2, TestMax = 4, TestMin = 8 } "@ } if(-not ([System.Management.Automation.PSTypeName]'TestMeasureText').Type) { Add-Type -TypeDefinition @" [System.Flags] public enum TestMeasureText : uint { TestIgnoreWS = 1, TestCharacter = 2, TestWord = 4, TestLine = 8 } "@ } $employees = [pscustomobject]@{"FirstName"="joseph"; "LastName"="smith"; "YearsInMS"=15}, [pscustomobject]@{"FirstName"="paul"; "LastName"="smith"; "YearsInMS"=15}, [pscustomobject]@{"FirstName"="mary jo"; "LastName"="soe"; "YearsInMS"=5}, [pscustomobject]@{"FirstName"="edmund`todd `n"; "LastName"="bush"; "YearsInMS"=9} } It "Measure-Object with Generic enum value options combination should work"{ $flags = [TestMeasureGeneric]0 $property = "FirstName" $testSum = ($flags -band [TestMeasureGeneric]::TestSum) -gt 0 $testAverage = ($flags -band [TestMeasureGeneric]::TestAverage) -gt 0 $testMax = ($flags -band [TestMeasureGeneric]::TestMax) -gt 0 $testMin = ($flags -band [TestMeasureGeneric]::TestMin) -gt 0 $result = $employees | Measure-Object -Sum:$testSum -Average:$testAverage -Max:$testMax -Min:$testMin -Prop $property $result.Count | Should -Be 4 $result.Sum | Should -BeNullOrEmpty $result.Average | Should -BeNullOrEmpty $result.Max | Should -BeNullOrEmpty $result.Min | Should -BeNullOrEmpty for ($i = 1; $i -lt 8 * 2; $i++) { $flags = [TestMeasureGeneric]$i $property = "YearsInMS" $testSum = ($flags -band [TestMeasureGeneric]::TestSum) -gt 0 $testAverage = ($flags -band [TestMeasureGeneric]::TestAverage) -gt 0 $testMax = ($flags -band [TestMeasureGeneric]::TestMax) -gt 0 $testMin = ($flags -band [TestMeasureGeneric]::TestMin) -gt 0 $result = $employees | Measure-Object -Sum:$testSum -Average:$testAverage -Max:$testMax -Min:$testMin -Prop $property $result.Count | Should -Be 4 if($testSum) { $result.Sum | Should -Be 44 } else { $result.Sum | Should -BeNullOrEmpty } if($testAverage) { $result.Average | Should -Be 11 } else { $result.Average | Should -BeNullOrEmpty } if($testMax) { $result.Maximum | Should -Be 15 } else { $result.Maximum | Should -BeNullOrEmpty } if($testMin) { $result.Minimum | Should -Be 5 } else { $result.Minimum | Should -BeNullOrEmpty } } } It "Measure-Object with Text combination should work"{ for ($i = 1; $i -lt 8 * 2; $i++) { $flags = [TestMeasureText]$i $property = "FirstName" $testIgnoreWS = ($flags -band [TestMeasureText]::TestIgnoreWS) -gt 0 $testCharacter = ($flags -band [TestMeasureText]::TestCharacter) -gt 0 $testWord = ($flags -band [TestMeasureText]::TestWord) -gt 0 $testLine = ($flags -band [TestMeasureText]::TestLine) -gt 0 $result = $employees | Measure-Object -IgnoreWhiteSpace:$testIgnoreWS -Character:$testCharacter -Word:$testWord -Line:$testLine -Prop $property if($testCharacter) { if($testIgnoreWS) { $result.Characters | Should -Be 25 } else { $result.Characters | Should -Be 29 } } else { $result.Characters | Should -BeNullOrEmpty } if($testWord) { $result.Words | Should -Be 6 } else { $result.Words | Should -BeNullOrEmpty } if($testLine) { $result.Lines | Should -Be 4 } else { $result.Lines | Should -BeNullOrEmpty } } } } # Since PSPropertyExpression is now a public type, it can be tested # directly, independent of the Measure-Object cmdlet Describe "Directly test the PSPropertyExpression type" -Tags "CI" { # this function is used to test the use of PSPropertyExpression # as a parameter in script function Test-PSPropertyExpression { [CmdletBinding()] param ( [Parameter(Mandatory,Position=0)] [PSPropertyExpression] $pe, [Parameter(ValueFromPipeline)] $InputObject ) begin { $sum = 0} process { $sum += $pe.GetValues($InputObject).result } end { $sum } } It "Test-PropertyExpression function with a wildcard property expression should sum numbers" { $result = (1..10).ForEach{@{value = $_}} | Test-PSPropertyExpression val* $result | Should -Be 55 } It "Test-PropertyExpression function with a scriptblock property expression should sum numbers" { $result = 1..10 | Test-PSPropertyExpression {$_} $result | Should -Be 55 } It "Test-PropertyExpression function with a scriptblock property expression should be able to transform input" { # Count the number of 'e's in the words. $result = "one", "two", "three", "four", "five" | Test-PSPropertyExpression {($_.ToCharArray() -match 'e').Count} $result | Should -Be 4 } It "Measure-Object with multiple lines should work"{ $result = "123`n4" | Measure-Object -Line $result.Lines | Should -Be 2 } It "Measure-Object with ScriptBlock properties should work" { $result = 1..10 | Measure-Object -Sum -Average -Minimum -Maximum -Property {$_ * 10} $result.Count | Should -Be 10 $result.Average | Should -Be 55 $result.Sum | Should -Be 550 $result.Minimum | Should -Be 10 $result.Maximum | Should -Be 100 $result.Property | Should -Be '$_ * 10' } It "Measure-Object with ScriptBlock properties should work with -word" { $result = "a,b,c", "d,e" | Measure-Object -Word {$_ -split ','} $result.Words | Should -Be 5 } It "Measure-Object ScriptBlock properties should be able to transform input" { $map = @{ one = 1; two = 2; three = 3 } $result = "one", "two", "three" | Measure-Object -Sum {$map[$_]} $result.Sum | Should -Be 6 } It "Measure-Object should handle hashtables as objects" { $htables = @{foo = 1}, @{foo = 3}, @{foo = 10} $result = $htables | Measure-Object -Sum fo* $result.Sum | Should -Be 14 } It "Measure-Object should handle hashtables as objects with ScriptBlock properties" { $htables = @{foo = 1}, @{foo = 3}, @{foo = 10} $result = $htables | Measure-Object -Sum {$_.foo * 10 } $result.Sum | Should -Be 140 } }