From f1b502278e374fab40f9d4695e65442f35f77cad Mon Sep 17 00:00:00 2001 From: "Joel Sallow (/u/ta11ow)" <32407840+vexx32@users.noreply.github.com> Date: Sun, 19 Jan 2020 16:31:51 -0500 Subject: [PATCH] :bug: :wrench: Fix outstanding issues in koan topics (#347) * :wrench: Resolve issues in AboutModules Fixes #342 * :wrench: Fix issues in AboutTeeObject Fixes #341 Also added a new koan to show when the variable is created * :wrench: Fix issues in AboutMeasureObject Fixes #340 * :wrench: Fix issues in AboutSelectObject Fixes #339 Fixes #337 * :wrench: Fix issue in AboutAssignmentAndArithmetic Fixes #334 * :wrench: Fix issues in AboutDiscovery Fixes #335 Fixes #332 * :wrench: :recycle: Fix up AboutArrays Fixes #330 * :wrench: Fix missing variable reference * :art: Update format of array declaration --- .../Koans/Cmdlets 1/AboutDiscovery.Koans.ps1 | 13 ++++++-- .../Cmdlets 1/AboutMeasureObject.Koans.ps1 | 20 +++++++++-- .../Koans/Cmdlets 1/AboutModules.Koans.ps1 | 10 +++--- .../Cmdlets 1/AboutSelectObject.Koans.ps1 | 16 +++++---- .../Koans/Cmdlets 1/AboutTeeObject.Koans.ps1 | 33 ++++++++++++++++--- .../Koans/Foundations/AboutArrays.Koans.ps1 | 25 ++++++++++---- .../AboutAssignmentAndArithmetic.Koans.ps1 | 24 ++++++++++++-- 7 files changed, 112 insertions(+), 29 deletions(-) diff --git a/PSKoans/Koans/Cmdlets 1/AboutDiscovery.Koans.ps1 b/PSKoans/Koans/Cmdlets 1/AboutDiscovery.Koans.ps1 index c058317cd..321f74c4a 100644 --- a/PSKoans/Koans/Cmdlets 1/AboutDiscovery.Koans.ps1 +++ b/PSKoans/Koans/Cmdlets 1/AboutDiscovery.Koans.ps1 @@ -31,7 +31,10 @@ Describe 'Get-Help' { $HelpInfo = Get-Help 'Get-Help' $GetHelpParams = $HelpInfo.Parameters.Parameter.Name - # Using the information from Get-Help, fill in a few of the available parameter names for the cmdlet. + <# + Using the information from Get-Help, fill in a few of the available parameter names for the cmdlet. + Note that the specific parameters available may depend on your version of PowerShell. + #> $ParamNames = @( '____' 'Examples' @@ -41,7 +44,11 @@ Describe 'Get-Help' { '____' ) - $ParamNames | Group-Object | Where-Object Count -gt 1 | Should -BeNullOrEmpty + $ParamNames | + Group-Object | + Where-Object Count -gt 1 | + Should -BeNullOrEmpty -Because 'you need to enter unique parameter names' + $ParamNames | Should -BeIn $GetHelpParams } @@ -211,6 +218,6 @@ Describe 'Get-Command' { $First4Commands = $KoanCommands | Select-Object -First 4 __ | Should -Be $KoanCommands.Count - @('____', '____', '____', '____') | Should -Be $KoanCommands.Name + @('____', '____', '____', '____') | Should -Be $First4Commands.Name } } diff --git a/PSKoans/Koans/Cmdlets 1/AboutMeasureObject.Koans.ps1 b/PSKoans/Koans/Cmdlets 1/AboutMeasureObject.Koans.ps1 index 0d1509048..26480e8c9 100644 --- a/PSKoans/Koans/Cmdlets 1/AboutMeasureObject.Koans.ps1 +++ b/PSKoans/Koans/Cmdlets 1/AboutMeasureObject.Koans.ps1 @@ -17,7 +17,7 @@ Describe 'Measure-Object' { 665, 154, 943, 35, 391, 816, 420, 229, 3, 938 ) - $Files = Get-ChildItem -Path $home -Recurse -Depth 2 + $Files = Get-ChildItem -Path $HOME -Recurse -Depth 2 } It 'can count objects' { @@ -76,12 +76,26 @@ Describe 'Measure-Object' { It 'can operate on object properties' { $Data = $Files.BaseName | Measure-Object -Property Length -Sum -Average + + # Averages can have a lot of decimal places, so we'll round to just 4 decimal places. + $Average = [math]::Round($Data.Average, 4) + __ | Should -Be $Data.Sum - __ | Should -Be $Data.Average + __ | Should -Be $Average } It 'can measure text lines, characters, and words of strings' { - $Text = Get-Content "$(Get-PSKoanLocation)/Foundations/AboutTheStockChallenge.Koans.ps1" + $Text = ' + Two monks were arguing about the temple flag waving in the wind. + One said, "The flag moves." + The other said, "The wind moves." + They argued back and forth but could not agree. + + Hui-neng, the sixth patriarch, said: + "Gentlemen! It is not the flag that moves. It is not the wind that moves. It is your mind that moves." + + The two monks were struck with awe. + ' $Data = $Text | Measure-Object -Line -Word -Character __ | Should -Be $Data.Lines diff --git a/PSKoans/Koans/Cmdlets 1/AboutModules.Koans.ps1 b/PSKoans/Koans/Cmdlets 1/AboutModules.Koans.ps1 index c052a80e9..6ef76efe1 100644 --- a/PSKoans/Koans/Cmdlets 1/AboutModules.Koans.ps1 +++ b/PSKoans/Koans/Cmdlets 1/AboutModules.Koans.ps1 @@ -33,11 +33,13 @@ Describe 'Get-Module' { $FirstThreeModules = $Modules | Select-Object -First 3 $VersionOfThirdModule = $FirstThreeModules[2].Version - $TypeOf6thModule = $Modules[5].ModuleType + $TypeOfLastModule = $Modules | + Select-Object -Last 1 | + ForEach-Object -MemberName ModuleType @('____', '____', '____') | Should -Be $FirstThreeModules.Name '____' | Should -Be $VersionOfThirdModule - '____' | Should -Be $TypeOf6thModule + '____' | Should -Be $TypeOfLastModule } It 'can filter by module name' { @@ -117,7 +119,7 @@ Describe 'New-Module' { a module in-memory without needing a file on disk. #> BeforeAll { - $Module = New-Module -Name 'PSKoans_TestModule' -ScriptBlock {} -ArgumentList + $Module = New-Module -Name 'PSKoans_TestModule' -ScriptBlock {} } It 'creates a dynamic module object' { @@ -179,7 +181,7 @@ Describe 'Import-Module' { } It 'does not produce output' { - Import-Module 'TestDrive:\TestModule.psm1' | Should -Be NullOrEmpty + Import-Module 'TestDrive:\TestModule.psm1' | Should -BeNullOrEmpty } It 'imports the module into the current session' { diff --git a/PSKoans/Koans/Cmdlets 1/AboutSelectObject.Koans.ps1 b/PSKoans/Koans/Cmdlets 1/AboutSelectObject.Koans.ps1 index ae30b6015..6149ec5ec 100644 --- a/PSKoans/Koans/Cmdlets 1/AboutSelectObject.Koans.ps1 +++ b/PSKoans/Koans/Cmdlets 1/AboutSelectObject.Koans.ps1 @@ -18,7 +18,7 @@ Describe 'Select-Object' { new custom object using those properties. #> - $Selected = Get-Proces -Id $PID | Select-Object Name, ID, Path + $Selected = Get-Process -Id $PID | Select-Object Name, ID, Path @('____', '____', 'Path') | Should -Be $Selected.PSObject.Properties.Name @@ -50,7 +50,7 @@ Describe 'Select-Object' { $Folder = Get-Item -Path $PSHome - $Selected.GetType().FullName | Should -BeOfType [System.IO.Directoryinfo] + $Folder | Should -BeOfType [____] 'System.IO.Directoryinfo' | Should -BeIn $Folder.PSTypeNames @@ -109,9 +109,11 @@ Describe 'Select-Object' { It 'can ignore duplicate objects' { # Select-Object can be used to create a unique list. - $Array = '6', '1', '4', '8', '7', '5', '3', '9', '2', '3', '2', '1', '5', '1', '6', - '2', '8', '4', '7', '3', '1', '2', '6', '3', '7', '1', '4', '5', '2', '1', '3', - '6', '2', '5', '1', '4' + $Array = @( + '6', '1', '4', '8', '7', '5', '3', '9', '2', '3', '2', '1', '5', '1', '6' + '2', '8', '4', '7', '3', '1', '2', '6', '3', '7', '1', '4', '5', '2', '1' + '3', '6', '2', '5', '1', '4' + ) $UniqueItems = $Array | Select-Object -Unique @('6', '__', '4', '8', '__', '__', '3', '__', '2') | Should -Be $UniqueItems @@ -244,7 +246,7 @@ Describe 'Select-Object' { $Selected = Get-Process -Id $PID | Select-Object @( 'Name' 'Id' - @{ n = 'Size'; e = { (Get-Item $_.Path).Length } } + @{ Name = 'RunningTime'; Expression = { (Get-Date) - $_.StartTime } } ) $Selected.____ | Should -BeOfType [TimeSpan] @@ -294,6 +296,6 @@ Describe 'Select-Object' { System.Management.Automation.PSObject. It is named as it is because it creates a custom object. #> - [PSCustomObject] | Should -Be [System.Management.Automation.PSObject] + [PSCustomObject].FullName | Should -Be System.Management.Automation.PSObject } } diff --git a/PSKoans/Koans/Cmdlets 1/AboutTeeObject.Koans.ps1 b/PSKoans/Koans/Cmdlets 1/AboutTeeObject.Koans.ps1 index 9d0d2bb6f..290b73e31 100644 --- a/PSKoans/Koans/Cmdlets 1/AboutTeeObject.Koans.ps1 +++ b/PSKoans/Koans/Cmdlets 1/AboutTeeObject.Koans.ps1 @@ -19,17 +19,42 @@ Describe 'Tee-Object' { It 'can store the object(s) into a variable' { # Note the variable name is given as a string, without the $ prefix. $Values = 'alpha', 'beta', 'gamma' - @('____', '____', '____', '____') | Tee-Object -Variable 'Numbers' | Should -Be $Values + + @('____', 'beta', '____') | + Tee-Object -Variable 'Numbers' | + Should -Be $Values + + '____' | Should -Be $Numbers[0] '____' | Should -Be $Numbers[1] + 'gamma' | Should -Be $Numbers[2] + } + + It 'does not create the variable until the pipeline is completed' { + $Values = 1..10 + + $Values | + Tee-Object -Variable Test | + ForEach-Object { $Test | Should -BeNullOrEmpty } + + $Test | Should -Not -BeNullOrEmpty + $____ | Should -Be $Values } It 'can also store the object(s) into a file' { - $File = New-TemporaryFile + <# + $TestDrive, or TestDrive:, refers to a temporary location that is automatically + cleaned out by Pester when the tests are concluded. + #> + $File = New-Item -Path "$TestDrive/TeeObjectTest.txt" + + 1..5 | + ForEach-Object { "{0:N2}" -f (1 / $_) } | + Tee-Object -FilePath $File.FullName | + Out-Null - $Output = 1..5 | ForEach-Object { "{0:N2}" -f (1 / $_) } | Tee-Object -FilePath $File.FullName $Stored = Get-Content -Path $File # Text files can only store string data, so be careful storing arbitrary data to files like this. - @('__', '__', '3', '__', '__') | Should -Be $Stored + @('__', '__', '0.33', '__', '__') | Should -Be $Stored } } diff --git a/PSKoans/Koans/Foundations/AboutArrays.Koans.ps1 b/PSKoans/Koans/Foundations/AboutArrays.Koans.ps1 index 7bfd7aa73..a6a7eb089 100644 --- a/PSKoans/Koans/Foundations/AboutArrays.Koans.ps1 +++ b/PSKoans/Koans/Foundations/AboutArrays.Koans.ps1 @@ -27,13 +27,13 @@ Describe 'Arrays' { #> $Ages[0] | Should -Be 12 __ | Should -Be $Ages[3] + } + It 'can be created with the @() operator' { <# The array subexpression operator @() is used to create an array from multiple values - or expressions. Within the parentheses, either commas, semicolons, or even line - breaks can be used to divide array elements. Although in many cases in PowerShell - an expression that only returns one value will not become an array, this operator - forces the value or object to be wrapped in an array. + or expressions. Within the parentheses, you can use commas, semicolons, and even line + breaks to divide array elements. #> $Names = @( 'Steve' @@ -44,6 +44,15 @@ Describe 'Arrays' { # Where is index 4 in the above array? __ | Should -Be $Names[4] + + <# + Although in many cases in PowerShell, an expression that only returns one value will + not become an array, this operator forces the value or object to be wrapped in an array + if the result is not already an array; it guarantes the result will be an array. + #> + $Array = @( 10 ) + + $Array.GetType().FullName | Should -Be System.____ } It 'is a fixed size collection; elements cannot be added or removed' { @@ -235,9 +244,13 @@ Describe 'Arrays' { The base type of Object[], Char[], and other fixed size array types is the System.Array type, or [Array]. - The [Array] type describes the Length property (aliased to Count), as well as other methods - which can be used to work with the array. + The [Array] type describes the Length property (which is also aliased to Count in PowerShell), + as well as other methods which can be used to work with the array. + #> + } + It 'allows you to check if something is contained within it' { + <# The available methods can be seen with Get-Member: Get-Member -InputObject @() diff --git a/PSKoans/Koans/Foundations/AboutAssignmentAndArithmetic.Koans.ps1 b/PSKoans/Koans/Foundations/AboutAssignmentAndArithmetic.Koans.ps1 index 3c327c706..09cf6f805 100644 --- a/PSKoans/Koans/Foundations/AboutAssignmentAndArithmetic.Koans.ps1 +++ b/PSKoans/Koans/Foundations/AboutAssignmentAndArithmetic.Koans.ps1 @@ -179,35 +179,55 @@ Describe 'Assignment/Arithmetic Combination Operators' { It 'is a bit unwieldy to assign and increment without combination operators' { $Value = 5 + $Value = $Value + 5 __ | Should -Be $Value } It 'is possible to combine assignment and addition' { $Value = 12 + $Value += 7 __ | Should -Be $Value } It 'is also possible to combine subtraction with assignment' { + $Value = 19 + $Value -= 3 __ | Should -Be $Value } It 'works the same way with division' { + $Value = 16 + $Value /= 2 - $Value | Should -Be 8 + __ | Should -Be $Value } It 'works with multiplication as well' { + $Value = 8 + $Value *= 3 __ | Should -Be $Value } It 'even works with modulus' { - # Modulus hasn't been left out, either. $Value = 12 + $Value %= 4 __ | Should -Be $Value } + + It 'can get a bit confusing to follow' { + $Value = __ + + $Value /= 3 + $Value %= 5 + $Value += 4 + $Value *= 7 + $Value -= 7 + + $Value | Should -Be 42 + } }