2020-03-24 11:08:37 -07:00
# Copyright (c) Microsoft Corporation.
2018-02-13 09:23:53 -08:00
# Licensed under the MIT License.
2016-07-25 14:01:41 -07:00
Describe "Measure-Object" -Tags "CI" {
2017-10-03 07:39:51 +04:00
BeforeAll {
$testObject = 1 , 3 , 4
2018-03-15 23:45:59 -04:00
$testObject2 = 1 . .100
2017-10-03 07:39:51 +04:00
}
2015-11-17 09:34:58 -08:00
It "Should be able to be called without error" {
2018-03-23 10:26:23 -07:00
{ Measure-Object | Out-Null } | Should -Not -Throw
2015-11-17 09:34:58 -08:00
}
It "Should be able to call on piped input" {
2018-03-23 10:26:23 -07:00
{ $testObject | Measure-Object } | Should -Not -Throw
2015-11-17 09:34:58 -08:00
}
It "Should be able to count the number of objects input to it" {
2018-03-23 10:26:23 -07:00
$ ( $testObject | Measure-Object ). Count | Should -Be $testObject . Length
2015-11-17 09:34:58 -08:00
}
2018-03-15 23:45:59 -04:00
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
2020-01-11 15:41:59 +00:00
$actual . Sum | Should -Be 8
2018-03-15 23:45:59 -04:00
# 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
2020-01-11 15:41:59 +00:00
$actual . Sum | Should -Be 5050
$actual . Average | Should -Be 50.5
2018-03-15 23:45:59 -04:00
# 29.011491975882 was calculated outside powershell using formula from
# http://mathworld.wolfram.com/StandardDeviation.html
[ Math ]:: abs ( $actual . StandardDeviation - 29.011491975882 ) | Should -BeLessThan .0000000000001
}
2015-11-17 09:34:58 -08:00
It "Should be able to count using the Property switch" {
2021-08-09 15:27:09 -07:00
$items = @ (
[ pscustomobject ] @ { X = 'a' ; Y = 'b' }
[ pscustomobject ] @ { X = 'c' }
[ pscustomobject ] @ { X = 'e' ; Y = 'f' }
)
2015-11-17 09:34:58 -08:00
2021-08-09 15:27:09 -07:00
( $items | Measure-Object -Property Y ). Count | Should -Be 2
2015-11-17 09:34:58 -08:00
}
2016-06-30 18:16:37 -07:00
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
2018-03-23 10:26:23 -07:00
$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
2016-06-30 18:16:37 -07:00
}
2015-11-17 09:34:58 -08:00
Context "Numeric tests" {
2017-10-03 07:39:51 +04:00
It "Should be able to sum" {
$actual = $testObject | Measure-Object -Sum
$expected = 0
2015-11-17 09:34:58 -08:00
2017-10-03 07:39:51 +04:00
foreach ( $obj in $testObject )
{
$expected += $obj
}
2015-11-17 09:34:58 -08:00
2018-03-23 10:26:23 -07:00
$actual . Sum | Should -Be $expected
2017-10-03 07:39:51 +04:00
}
2015-11-17 09:34:58 -08:00
2017-10-03 07:39:51 +04:00
It "Should be able to average" {
$actual = $testObject | Measure-Object -Average
$expected = 0
2015-11-17 09:34:58 -08:00
2017-10-03 07:39:51 +04:00
foreach ( $obj in $testObject )
{
$expected += $obj
}
2015-11-17 09:34:58 -08:00
2017-10-03 07:39:51 +04:00
$expected /= $testObject . length
2015-11-17 09:34:58 -08:00
2018-03-23 10:26:23 -07:00
$actual . Average | Should -Be $expected
2017-10-03 07:39:51 +04:00
}
2015-11-17 09:34:58 -08:00
2017-10-03 07:39:51 +04:00
It "Should be able to return a minimum" {
$actual = $testObject | Measure-Object -Minimum
$expected = $testObject [ 0 ]
2015-11-17 09:34:58 -08:00
2017-10-03 07:39:51 +04:00
for ( $i = 0 ; $i -lt $testObject . length ; $i ++)
{
if ( $testObject [ $i ] -lt $expected )
{
$expected = $testObject [ $i ]
}
}
2015-11-17 09:34:58 -08:00
2018-03-23 10:26:23 -07:00
$actual . Minimum | Should -Be $expected
2017-10-03 07:39:51 +04:00
}
2015-11-17 09:34:58 -08:00
2017-10-03 07:39:51 +04:00
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 ]
2015-11-17 09:34:58 -08:00
2017-10-03 07:39:51 +04:00
for ( $i = 1 ; $i -lt $testMinimum . length ; $i ++)
{
if ( $testMinimum [ $i ] -lt $expected )
{
$expected = $testMinimum [ $i ]
}
}
2015-11-17 09:34:58 -08:00
2018-03-23 10:26:23 -07:00
$actual . Minimum | Should -Be $expected
2017-10-03 07:39:51 +04:00
}
2015-11-17 09:34:58 -08:00
2017-10-03 07:39:51 +04:00
It "Should be able to return a maximum" {
$actual = $testObject | Measure-Object -Maximum
$expected = $testObject [ 0 ]
2015-11-17 09:34:58 -08:00
2017-10-03 07:39:51 +04:00
for ( $i = 1 ; $i -lt $testObject . length ; $i ++)
{
if ( $testObject [ $i ] -gt $expected )
{
$expected = $testObject [ $i ]
}
}
2015-11-17 09:34:58 -08:00
2018-03-23 10:26:23 -07:00
$actual . Maximum | Should -Be $expected
2017-10-03 07:39:51 +04:00
}
2015-11-17 09:34:58 -08:00
2017-10-03 07:39:51 +04:00
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 ]
2015-11-17 09:34:58 -08:00
2017-10-03 07:39:51 +04:00
for ( $i = 1 ; $i -lt $testMaximum . length ; $i ++)
{
if ( $testMaximum [ $i ] -gt $expected )
{
$expected = $testMaximum [ $i ]
}
}
2015-11-17 09:34:58 -08:00
2018-03-23 10:26:23 -07:00
$actual . Maximum | Should -Be $expected
2017-10-03 07:39:51 +04:00
}
2018-07-09 09:15:32 +05:30
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
2019-05-20 22:43:51 -07:00
( $result . StandardDeviation ). ToString () | Should -Be '3.0276503540974917'
2018-07-09 09:15:32 +05:30
}
2015-11-17 09:34:58 -08:00
}
2022-01-13 09:33:43 -08:00
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'
}
}
2015-11-17 09:34:58 -08:00
Context "String tests" {
2017-10-03 07:39:51 +04:00
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."
}
2015-11-17 09:34:58 -08:00
2017-10-03 07:39:51 +04:00
It "Should be able to count the number of words in a string" {
$expectedLength = $testString . Replace ( $nl , "" ). Split (). length
$actualLength = $testString | Measure-Object -Word
2015-11-17 09:34:58 -08:00
2018-03-23 10:26:23 -07:00
$actualLength . Words | Should -Be $expectedLength
2017-10-03 07:39:51 +04:00
}
2015-11-17 09:34:58 -08:00
2017-10-03 07:39:51 +04:00
It "Should be able to count the number of characters in a string" {
$expectedLength = $testString . length
$actualLength = $testString | Measure-Object -Character
2015-11-17 09:34:58 -08:00
2018-03-23 10:26:23 -07:00
$actualLength . Characters | Should -Be $expectedLength
2017-10-03 07:39:51 +04:00
}
2015-11-17 09:34:58 -08:00
2017-10-03 07:39:51 +04:00
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
2015-11-17 09:34:58 -08:00
2018-03-23 10:26:23 -07:00
$actualLength . Lines | Should -Be $expectedLength
2017-10-03 07:39:51 +04:00
}
2015-11-17 09:34:58 -08:00
}
}
2016-05-23 00:27:24 -07:00
2016-07-25 14:01:41 -07:00
Describe "Measure-Object DRT basic functionality" -Tags "CI" {
2017-10-03 07:39:51 +04:00
BeforeAll {
if ( -not ([ System.Management.Automation.PSTypeName ] 'TestMeasureGeneric' ). Type )
{
Add-Type -TypeDefinition @"
2016-05-23 00:27:24 -07:00
[System.Flags]
public enum TestMeasureGeneric : uint
{
TestSum = 1,
TestAverage = 2,
TestMax = 4,
TestMin = 8
}
"@
2017-10-03 07:39:51 +04:00
}
if ( -not ([ System.Management.Automation.PSTypeName ] 'TestMeasureText' ). Type )
{
Add-Type -TypeDefinition @"
2016-05-23 00:27:24 -07:00
[System.Flags]
public enum TestMeasureText : uint
{
TestIgnoreWS = 1,
TestCharacter = 2,
TestWord = 4,
TestLine = 8
}
"@
2017-10-03 07:39:51 +04:00
}
$employees = [ pscustomobject ] @ { "FirstName" = "joseph" ; "LastName" = "smith" ; "YearsInMS" = 15 },
2016-05-23 00:27:24 -07:00
[ pscustomobject ] @ { "FirstName" = "paul" ; "LastName" = "smith" ; "YearsInMS" = 15 },
[ pscustomobject ] @ { "FirstName" = "mary jo" ; "LastName" = "soe" ; "YearsInMS" = 5 },
[ pscustomobject ] @ { "FirstName" = "edmund `t odd `n " ; "LastName" = "bush" ; "YearsInMS" = 9 }
2017-10-03 07:39:51 +04:00
}
2017-01-16 13:31:14 -08:00
2016-05-23 00:27:24 -07:00
It "Measure-Object with Generic enum value options combination should work" {
$flags = [ TestMeasureGeneric ] 0
2017-10-03 07:39:51 +04:00
$property = "FirstName"
$testSum = ( $flags -band [ TestMeasureGeneric ]:: TestSum ) -gt 0
2016-05-23 00:27:24 -07:00
$testAverage = ( $flags -band [ TestMeasureGeneric ]:: TestAverage ) -gt 0
$testMax = ( $flags -band [ TestMeasureGeneric ]:: TestMax ) -gt 0
$testMin = ( $flags -band [ TestMeasureGeneric ]:: TestMin ) -gt 0
2017-10-03 07:39:51 +04:00
$result = $employees | Measure-Object -Sum: $testSum -Average: $testAverage -Max: $testMax -Min: $testMin -Prop $property
2018-03-23 10:26:23 -07:00
$result . Count | Should -Be 4
$result . Sum | Should -BeNullOrEmpty
$result . Average | Should -BeNullOrEmpty
$result . Max | Should -BeNullOrEmpty
$result . Min | Should -BeNullOrEmpty
2017-10-03 07:39:51 +04:00
for ( $i = 1 ; $i -lt 8 * 2 ; $i ++)
2016-05-23 00:27:24 -07:00
{
2017-10-03 07:39:51 +04:00
$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
2018-03-23 10:26:23 -07:00
$result . Count | Should -Be 4
2017-10-03 07:39:51 +04:00
if ( $testSum )
{
2018-03-23 10:26:23 -07:00
$result . Sum | Should -Be 44
2017-10-03 07:39:51 +04:00
}
else
{
2018-03-23 10:26:23 -07:00
$result . Sum | Should -BeNullOrEmpty
2017-10-03 07:39:51 +04:00
}
2017-01-16 13:31:14 -08:00
2017-10-03 07:39:51 +04:00
if ( $testAverage )
{
2018-03-23 10:26:23 -07:00
$result . Average | Should -Be 11
2017-10-03 07:39:51 +04:00
}
else
{
2018-03-23 10:26:23 -07:00
$result . Average | Should -BeNullOrEmpty
2017-10-03 07:39:51 +04:00
}
2017-01-16 13:31:14 -08:00
2017-10-03 07:39:51 +04:00
if ( $testMax )
{
2018-03-23 10:26:23 -07:00
$result . Maximum | Should -Be 15
2017-10-03 07:39:51 +04:00
}
else
{
2018-03-23 10:26:23 -07:00
$result . Maximum | Should -BeNullOrEmpty
2017-10-03 07:39:51 +04:00
}
2017-01-16 13:31:14 -08:00
2017-10-03 07:39:51 +04:00
if ( $testMin )
{
2018-03-23 10:26:23 -07:00
$result . Minimum | Should -Be 5
2017-10-03 07:39:51 +04:00
}
else
{
2018-03-23 10:26:23 -07:00
$result . Minimum | Should -BeNullOrEmpty
2017-10-03 07:39:51 +04:00
}
}
2016-05-23 00:27:24 -07:00
}
2017-01-16 13:31:14 -08:00
2017-10-03 07:39:51 +04:00
It "Measure-Object with Text combination should work" {
for ( $i = 1 ; $i -lt 8 * 2 ; $i ++)
2016-05-23 00:27:24 -07:00
{
2017-10-03 07:39:51 +04:00
$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
2017-01-16 13:31:14 -08:00
2017-10-03 07:39:51 +04:00
if ( $testCharacter )
{
if ( $testIgnoreWS )
{
2018-03-23 10:26:23 -07:00
$result . Characters | Should -Be 25
2017-10-03 07:39:51 +04:00
}
else
{
2018-03-23 10:26:23 -07:00
$result . Characters | Should -Be 29
2017-10-03 07:39:51 +04:00
}
}
else
{
2018-03-23 10:26:23 -07:00
$result . Characters | Should -BeNullOrEmpty
2017-10-03 07:39:51 +04:00
}
2017-01-16 13:31:14 -08:00
2017-10-03 07:39:51 +04:00
if ( $testWord )
{
2018-03-23 10:26:23 -07:00
$result . Words | Should -Be 6
2017-10-03 07:39:51 +04:00
}
else
{
2018-03-23 10:26:23 -07:00
$result . Words | Should -BeNullOrEmpty
2017-10-03 07:39:51 +04:00
}
2017-01-16 13:31:14 -08:00
2017-10-03 07:39:51 +04:00
if ( $testLine )
{
2018-03-23 10:26:23 -07:00
$result . Lines | Should -Be 4
2017-10-03 07:39:51 +04:00
}
else
{
2018-03-23 10:26:23 -07:00
$result . Lines | Should -BeNullOrEmpty
2017-10-03 07:39:51 +04:00
}
}
2016-05-23 00:27:24 -07:00
}
2018-06-20 00:23:11 -07:00
}
# 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
2020-05-15 21:19:54 +03:00
# as a parameter in script
2018-06-20 00:23:11 -07:00
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" {
2019-01-06 12:00:56 +00:00
$result = ( 1 . .10 ). ForEach { @ { value = $_ }} | Test-PSPropertyExpression val *
2018-06-20 00:23:11 -07:00
$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 `n 4" | 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
}
}