Koans/Introduction/AboutStrings.Koans.ps1
using module PSKoans [Koan(Position = 104)] param() <# Strings Strings in PowerShell come in two flavours: standard strings, and string literals. Standard strings in PoSH are created using double-quotes, whereas string literals are created with single quotes. Unlike most other languages, standard strings in PowerShell are not literal and can evaluate expressions or variables mid-string in order to dynamically insert values into a preset string. #> Describe 'Strings' { It 'is a simple string of text' { '____' | Should -Be 'string' } Context 'Literal Strings' { It 'assumes everything is literal' { $var = 'Some things you must take literally' '____' | Should -Be $var } It 'can contain special characters' { # 'Special' is just a title. $complexVar = 'They have $ or ` or " or $()' '____' | Should -Be $complexVar } It 'can contain quotation marks' { $Quotes = 'These are ''quotation marks'' you see?' # Single quotes go more easily in double-quoted strings. "____" | Should -Be $Quotes } } Context 'Evaluated Strings' { It 'can expand variables' { $var = 'apple' '____' | Should -Be "My favorite fruit is $var" } It 'can do a simple expansion' { '____' | Should -Be "Your home directory is located here: $HOME" } It 'handles other ways of doing the same thing' { # Strings can handle entire subexpressions being inserted as well! $String = "Your home folder is: $(Get-Item $HOME)" '____' | Should -Be $String } It 'will expand variables that do not exist' { <# If a string contains a variable that has not been created, PowerShell will still try and expand the value. This could be a typing mistake. #> $String = "PowerShell's home folder is: $SPHome" '____' | Should -Be $String } It 'can get confused about :' { <# In PowerShell, : is used to define a scope or a provider for a variable. For example, the Environment variable provider uses the $env:SomeVariableName. When : is part of a string, PowerShell will try and expand a variable in that scope or from that provider. #> $Number = 1 $String = "$Number:Get shopping" '____' | Should -Be $String } It 'can use curly braces to define the variable name in a string with :' { # Variables followed by : can be included in an expanding string if curly braces are used. $Number = 1 $String = "${Number}:Get shopping" '____' | Should -Be $String } It 'can escape special characters with backticks' { $LetterA = 'Apple' $String = "`$LetterA contains $LetterA." '____' | Should -Be $String } It 'can escape quotation marks' { $String = "This is a `"string`" value." $AlternateString = "This is a ""string"" value." # A mirror image, a familiar pattern, reflected in the glass. $Results = @( '____' '____' ) $Results | Should -Be @($String, $AlternateString) } It 'can insert special characters with escape sequences' { <# All text strings in PowerShell are actually just a series of character values. Each of these values has a specific number assigned in the [char] type that represents that letter, number, space, symbol, etc. .NET uses UTF16 encoding for [char] and [string] values. However, with most common letters, numbers, and symbols the assigned [char] values are identical to the ASCII values. ASCII is an older standard encoding for text, but you can still use all those values as-is with [char] and get back what you'd expect thanks to the design of the UTF16 encoding. An extended ASCII code table is available at: https://www.ascii-code.com/ #> $ExpectedValue = [char] 9 <# If you're not sure what character you're after, consult the ASCII code table above. Get-Help about_Special_Characters will list the escape sequence you can use to create the right character with PowerShell's native string escape sequences. #> $ActualValue = "`_" $ActualValue | Should -Be $ExpectedValue } } Context 'String Concatenation' { It 'adds strings together' { # Two become one. $String1 = '_____' $String2 = 'is cool.' $String1 + ' ' + $String2 | Should -Be 'This string is cool.' } It 'can be done more easily' { # Water mixes seamlessly with itself. $String1 = 'This string' $String2 = 'is cool.' "$String1 ____" | Should -Be 'This string is cool.' } } Context 'Substrings' { It 'lets you select portions of a string' { # Few things require the entirety of the library. $String = 'At the very top!' '____' | Should -Be $String.Substring(0, 6) '____' | Should -Be $String.Substring(7) } } Context 'Here-Strings' { <# Here-strings are a fairly common programming concept, but have some additional quirks in PowerShell that bear mention. They start with the sequence @' or @" and end with the matching reverse "@ or '@ sequence. The terminating sequence MUST be at the start of the line, or the string will not end where you want it to. #> It 'can be a literal string' { $LiteralString = @' Hullo! '@ # This terminating sequence cannot be indented; it must be at the start of the line. # "Empty" space, too, is a thing of substance for some. ' ____' | Should -Be $LiteralString } It 'can be an evaluated string' { # The key is in the patterns. $Number = __ # These can mess with indentation rules, but have their uses nonetheless! $String = @" I am number #$Number! "@ '____' | Should -Be $String } It 'allows use of quotation marks easily' { $AllYourQuotes = @" All things that are not 'evaluated' are "recognised" as characters. "@ '____' | Should -Be $AllYourQuotes } } Context 'Arrays and Strings' { <# An array can be inserted into a string in PowerShell. #> It 'joins using a space by default' { $array = @( 'Hello' 'world' ) '____ ____' | Should -Be "$array" } It 'can be joined with a different string by setting the OFS variable' { <# The $OFS variable, short for output field separator, defines the separator used to join an array when it is included in a string. By default, the OFS variable is unset, and a single space is used as the separator. #> $OFS = '... ' $array = @( 'Hello' 'world' ) '____' | Should -Be "$array" Remove-Variable OFS } } } |