From 312ec5ffd09be12d29cb0e31ee4290be03b8fa0e Mon Sep 17 00:00:00 2001 From: Yanbing Wang Date: Fri, 26 Aug 2016 14:49:44 -0700 Subject: [PATCH] Add Tests for parsing, international, and script help. --- .../Language/LanguageTestSupport.psm1 | 115 ++-- .../Language/Parser/Parsing.Tests.ps1 | 311 ++++++++++ .../Language/Scripting/I18n.Tests.ps1 | 185 ++++++ .../Scripting/I18n.Tests_fallback.psd1 | 5 + .../Language/Scripting/ScriptHelp.Tests.ps1 | 561 ++++++++++++++++++ .../Language/Scripting/ScriptHelp.Tests.xml | 28 + .../Language/Scripting/en-US/I18n.Tests.psd1 | 4 + .../Language/Scripting/en-US/bad.psd1 | 7 + .../Language/Scripting/en-US/foo.psd1 | 4 + .../Language/Scripting/en-US/if.psd1 | 7 + .../Language/Scripting/en-US/scriptHelp1.xml | 28 + .../Language/Scripting/fr-FR/I18n.Tests.psd1 | 4 + .../Language/Scripting/fr-FR/foo.psd1 | 4 + .../Scripting/newbase/en-US/I18n.Tests.psd1 | 4 + .../Language/Scripting/newbase/en-US/foo.psd1 | 4 + .../Scripting/newbase/en-US/scriptHelp1.xml | 28 + .../Scripting/newbase/fr-FR/I18n.Tests.psd1 | 4 + .../Language/Scripting/newbase/fr-FR/foo.psd1 | 4 + 18 files changed, 1259 insertions(+), 48 deletions(-) create mode 100644 test/powershell/Language/Parser/Parsing.Tests.ps1 create mode 100644 test/powershell/Language/Scripting/I18n.Tests.ps1 create mode 100644 test/powershell/Language/Scripting/I18n.Tests_fallback.psd1 create mode 100644 test/powershell/Language/Scripting/ScriptHelp.Tests.ps1 create mode 100644 test/powershell/Language/Scripting/ScriptHelp.Tests.xml create mode 100644 test/powershell/Language/Scripting/en-US/I18n.Tests.psd1 create mode 100644 test/powershell/Language/Scripting/en-US/bad.psd1 create mode 100644 test/powershell/Language/Scripting/en-US/foo.psd1 create mode 100644 test/powershell/Language/Scripting/en-US/if.psd1 create mode 100644 test/powershell/Language/Scripting/en-US/scriptHelp1.xml create mode 100644 test/powershell/Language/Scripting/fr-FR/I18n.Tests.psd1 create mode 100644 test/powershell/Language/Scripting/fr-FR/foo.psd1 create mode 100644 test/powershell/Language/Scripting/newbase/en-US/I18n.Tests.psd1 create mode 100644 test/powershell/Language/Scripting/newbase/en-US/foo.psd1 create mode 100644 test/powershell/Language/Scripting/newbase/en-US/scriptHelp1.xml create mode 100644 test/powershell/Language/Scripting/newbase/fr-FR/I18n.Tests.psd1 create mode 100644 test/powershell/Language/Scripting/newbase/fr-FR/foo.psd1 diff --git a/test/powershell/Language/LanguageTestSupport.psm1 b/test/powershell/Language/LanguageTestSupport.psm1 index 2d7e46a1d7..3d10a67cae 100644 --- a/test/powershell/Language/LanguageTestSupport.psm1 +++ b/test/powershell/Language/LanguageTestSupport.psm1 @@ -53,37 +53,6 @@ function position_message } -# -# Run the new parser, check the errors against the expected errors -# -function Test-Error -{ - [CmdletBinding()] - param([string]$src, [string[]]$expectedErrors, [int[]]$expectedOffsets) - - Assert ($expectedErrors.Count -eq $expectedOffsets.Count) "Test case error" - - $errors = Get-ParseResults -Src $src - - - if ($null -ne $errors) - { - Assert ($errors.Count -eq $expectedErrors.Count) "Expected $($expectedErrors.Count) errors, got $($errors.Count)" - for ($i = 0; $i -lt $errors.Count; ++$i) - { - $err = $errors[$i] - Assert ($expectedErrors[$i] -eq $err.ErrorId) ("Unexpected error: {0,-30}{1}" -f ("$($err.ErrorId):", - (position_message $err.Extent.StartScriptPosition))) - Assert ($expectedOffsets[$i] -eq $err.Extent.StartScriptPosition.Offset) ` - "Expected position: $($expectedOffsets[$i]), got $($err.Extent.StartScriptPosition.Offset)" - } - } - else - { - Assert $false "Expected errors but didn't receive any." - } -} - # # Pester friendly version of Test-Error # @@ -95,7 +64,9 @@ function ShouldBeParseError [string[]]$expectedErrors, [int[]]$expectedOffsets, # This is a temporary solution after moving type creation from parse time to runtime - [switch]$SkipAndCheckRuntimeError + [switch]$SkipAndCheckRuntimeError, + # for test coverarage purpose, tests validate columnNumber or offset + [switch]$CheckColumnNumber ) Context "Parse error expected: <<$src>>" { @@ -129,7 +100,9 @@ function ShouldBeParseError $errorId = $err.ErrorId } It "Error Id" { $errorId | Should Be $expectedErrors[$i] } - It "Error position" -Pending:$SkipAndCheckRuntimeError { $err.Extent.StartScriptPosition.Offset | Should Be $expectedOffsets[$i] } + $acutalPostion = $err.Extent.StartScriptPosition.Offset + if ( $CheckColumnNumber ) { $acutalPostion = $err.Extent.StartScriptPosition.ColumnNumber } + It "Error position" -Pending:$SkipAndCheckRuntimeError { $acutalPostion | Should Be $expectedOffsets[$i] } } } } @@ -149,30 +122,76 @@ function Flatten-Ast function Test-ErrorStmt { param([string]$src, [string]$errorStmtExtent) + $a = $args + Context "Error Statement expected: <<$src>>" { + $ast = Get-ParseResults $src -Ast + $asts = @(Flatten-Ast $ast.EndBlock.Statements[0]) - $ast = Get-ParseResults $src -Ast - $asts = @(Flatten-Ast $ast.EndBlock.Statements[0]) - - Assert ($asts[0] -is [System.Management.Automation.Language.ErrorStatementAst]) "Expected error statement" - Assert ($asts.Count -eq $args.Count + 1) "Incorrect number of nested asts" - Assert ($asts[0].Extent.Text -eq $errorStmtExtent) "Error statement expected <$errorStmtExtent>, got <$($asts[0].Extent.Text)>" - for ($i = 0; $i -lt $args.Count; ++$i) - { - Assert ($asts[$i + 1].Extent.Text -eq $args[$i]) "Nested ast incorrect: <$($asts[$i+1].Extent.Text)>, expected <$($args[$i])>" + It 'Type is ErrorStatementAst' { $asts[0].GetType() | Should Be System.Management.Automation.Language.ErrorStatementAst } + It "`$asts.count" { $asts.Count | Should Be ($a.Count + 1) } + It "`$asts[0].Extent.Text" { $asts[0].Extent.Text | Should Be $errorStmtExtent } + for ($i = 0; $i -lt $a.Count; ++$i) + { + It "`$asts[$($i + 1)].Extent.Text" { $asts[$i + 1].Extent.Text | Should Be $a[$i] } + } } } function Test-Ast { param([string]$src) - + $a = $args $ast = Get-ParseResults $src -Ast $asts = @(Flatten-Ast $ast) - Assert ($asts.Count -eq $args.Count) "Incorrect number of nested asts, got $($asts.Count), expected $($args.Count)" - for ($i = 0; $i -lt $args.Count; ++$i) - { - Assert ($asts[$i].Extent.Text -eq $args[$i]) "Nested ast incorrect: <$($asts[$i].Extent.Text)>, expected <$($args[$i])>" + Context "Ast Validation: <<$src>>" { + It "`$asts.count" { $asts.Count | Should Be $a.Count } + for ($i = 0; $i -lt $a.Count; ++$i) + { + It "`$asts[$i].Extent.Text" { $asts[$i].Extent.Text | Should Be $a[$i] } + } } } -Export-ModuleMember -Function Test-Error, Test-ErrorStmt, Test-Ast, ShouldBeParseError, Get-ParseResults, Get-RuntimeError +## ErrorStatement is special for SwitchStatement + function Test-ErrorStmtForSwitchFlag + { + param([string]$src, [string]$flagName) + $a = $args + $ast = Get-ParseResults $src -Ast + $ast = $ast.EndBlock.Statements[0] + Context "Ast Validation: <<$src>>" { + $ast.GetType() | Should Be System.Management.Automation.Language.ErrorStatementAst + $ast.Flags.ContainsKey($flagName) | Should be $true + + $asts = @(Flatten-Ast $ast.Flags[$flagName].Item2) + + $asts.Count | Should Be $a.Count + for ($i = 0; $i -lt $a.Count; ++$i) + { + $asts[$i].Extent.Text | Should Be $a[$i] + } + } + } + + function ShouldBeErrorId + { + param([Parameter(ValueFromPipeline, Mandatory)] + [ScriptBlock] + $sb, + + [Parameter(Mandatory, Position=0)] + [string] + $FullyQualifiedErrorId) + + try + { + & $sb + throw "Unexpected" + } + catch + { + $_.FullyQualifiedErrorId | Should Be $FullyQualifiedErrorId + } + } + +Export-ModuleMember -Function Test-ErrorStmt, Test-Ast, ShouldBeParseError, Get-ParseResults, Get-RuntimeError, Test-ErrorStmtForSwitchFlag, ShouldBeErrorId diff --git a/test/powershell/Language/Parser/Parsing.Tests.ps1 b/test/powershell/Language/Parser/Parsing.Tests.ps1 new file mode 100644 index 0000000000..f23624b111 --- /dev/null +++ b/test/powershell/Language/Parser/Parsing.Tests.ps1 @@ -0,0 +1,311 @@ +Import-Module ..\LanguageTestSupport.psm1 -force + + set-strictmode -v 2 + + +Describe 'for statement parsing' -Tags "CI" { + ShouldBeParseError 'for' MissingOpenParenthesisAfterKeyword 4 -CheckColumnNumber + ShouldBeParseError 'for(' MissingEndParenthesisAfterStatement 5 -CheckColumnNumber + ShouldBeParseError 'for(;' MissingEndParenthesisAfterStatement 6 -CheckColumnNumber + ShouldBeParseError 'for(;;' MissingEndParenthesisAfterStatement 7 -CheckColumnNumber + ShouldBeParseError 'for($a' MissingEndParenthesisAfterStatement 7 -CheckColumnNumber + ShouldBeParseError 'for($a;' MissingEndParenthesisAfterStatement 8 -CheckColumnNumber + ShouldBeParseError 'for($a;$b' MissingEndParenthesisAfterStatement 10 -CheckColumnNumber + ShouldBeParseError 'for($a;$b;' MissingEndParenthesisAfterStatement 11 -CheckColumnNumber + ShouldBeParseError 'for($a;$b;$c' MissingEndParenthesisAfterStatement 13 -CheckColumnNumber + ShouldBeParseError 'for($a;$b;$c)' MissingLoopStatement 14 -CheckColumnNumber + ShouldBeParseError ':lab for' MissingOpenParenthesisAfterKeyword 9 -CheckColumnNumber + ShouldBeParseError ':lab for(' MissingEndParenthesisAfterStatement 9 + ShouldBeParseError ':lab for(;' MissingEndParenthesisAfterStatement 11 -CheckColumnNumber + ShouldBeParseError ':lab for(;;' MissingEndParenthesisAfterStatement 12 -CheckColumnNumber + ShouldBeParseError ':lab for($a' MissingEndParenthesisAfterStatement 12 -CheckColumnNumber + ShouldBeParseError ':lab for($a;' MissingEndParenthesisAfterStatement 12 + ShouldBeParseError ':lab for($a;$b' MissingEndParenthesisAfterStatement 14 + ShouldBeParseError ':lab for($a;$b;' MissingEndParenthesisAfterStatement 15 + ShouldBeParseError ':lab for($a;$b;$c' MissingEndParenthesisAfterStatement 17 + ShouldBeParseError ':lab for($a;$b;$c)' MissingLoopStatement 18 + + + Test-ErrorStmt 'for z' 'for' + Test-ErrorStmt 'for {}' 'for' + Test-ErrorStmt 'for ()' 'for ()' + Test-ErrorStmt 'for(' 'for(' + Test-ErrorStmt 'for(;' 'for(;' + Test-ErrorStmt 'for(;;' 'for(;;' + Test-ErrorStmt 'for($a' 'for($a' '$a' '$a' '$a' + Test-ErrorStmt 'for($a;$b' 'for($a;$b' '$a' '$a' '$a' '$b' '$b' '$b' + Test-ErrorStmt 'for($a;$b;$c' 'for($a;$b;$c' '$a' '$a' '$a' '$b' '$b' '$b' '$c' '$c' '$c' + Test-ErrorStmt 'for($a;$b;$c)' 'for($a;$b;$c)' '$a' '$a' '$a' '$b' '$b' '$b' '$c' '$c' '$c' + Test-ErrorStmt 'for()zzzz' 'for()' + + Test-ErrorStmt ':lab for z' ':lab for' + Test-ErrorStmt ':lab for {}' ':lab for' + Test-ErrorStmt ':lab for ()' ':lab for ()' + Test-ErrorStmt ':lab for(' ':lab for(' + Test-ErrorStmt ':lab for(;' ':lab for(;' + Test-ErrorStmt ':lab for(;;' ':lab for(;;' + Test-ErrorStmt ':lab for($a' ':lab for($a' '$a' '$a' '$a' + Test-ErrorStmt ':lab for($a;$b' ':lab for($a;$b' '$a' '$a' '$a' '$b' '$b' '$b' + Test-ErrorStmt ':lab for($a;$b;$c' ':lab for($a;$b;$c' '$a' '$a' '$a' '$b' '$b' '$b' '$c' '$c' '$c' + Test-ErrorStmt ':lab for($a;$b;$c)' ':lab for($a;$b;$c)' '$a' '$a' '$a' '$b' '$b' '$b' '$c' '$c' '$c' + Test-ErrorStmt ':lab for()zzzz' ':lab for()' +} + +Describe 'foreach statement parsing' -Tags "CI" { + ShouldBeParseError 'foreach' MissingOpenParenthesisAfterKeyword 7 + ShouldBeParseError 'foreach (' MissingVariableNameAfterForeach 9 + ShouldBeParseError 'foreach ($a' MissingInInForeach 11 + ShouldBeParseError 'foreach ($a into' MissingInInForeach 11 + ShouldBeParseError 'foreach ($a in' MissingForeachExpression 14 + ShouldBeParseError 'foreach ($a in $x' MissingEndParenthesisAfterForeach 17 + ShouldBeParseError 'foreach ($a in $x)' MissingForeachStatement 18 + ShouldBeParseError ':lab foreach' MissingOpenParenthesisAfterKeyword 12 + ShouldBeParseError ':lab foreach (' MissingVariableNameAfterForeach 14 + ShouldBeParseError ':lab foreach ($a' MissingInInForeach 16 + ShouldBeParseError ':lab foreach ($a into' MissingInInForeach 17 -CheckColumnNumber + ShouldBeParseError ':lab foreach ($a in' MissingForeachExpression 20 -CheckColumnNumber + ShouldBeParseError ':lab foreach ($a in $x' MissingEndParenthesisAfterForeach 23 -CheckColumnNumber + ShouldBeParseError ':lab foreach ($a in $x)' MissingForeachStatement 24 -CheckColumnNumber + + Test-ErrorStmt 'foreach' 'foreach' + Test-ErrorStmt 'foreach z' 'foreach' + Test-ErrorStmt 'foreach (' 'foreach (' + Test-ErrorStmt 'foreach ($a' 'foreach ($a' '$a' + Test-ErrorStmt 'foreach ($a zz' 'foreach ($a' '$a' + Test-ErrorStmt 'foreach ($a # line comment' 'foreach ($a' '$a' + Test-ErrorStmt 'foreach ($a $zz' 'foreach ($a' '$a' + Test-ErrorStmt 'foreach ($a in' 'foreach ($a in' '$a' + Test-ErrorStmt 'foreach ($a in $b' 'foreach ($a in $b' '$a' '$b' '$b' '$b' + Test-ErrorStmt 'foreach ($a in $b <#hmm#>)' 'foreach ($a in $b <#hmm#>)' '$a' '$b' '$b' '$b' + Test-ErrorStmt ':lab foreach' ':lab foreach' + Test-ErrorStmt ':lab foreach z' ':lab foreach' + Test-ErrorStmt ':lab foreach (' ':lab foreach (' + Test-ErrorStmt ':lab foreach ($a' ':lab foreach ($a' '$a' + Test-ErrorStmt ':lab foreach ($a zz' ':lab foreach ($a' '$a' + Test-ErrorStmt ':lab foreach ($a # line comment' ':lab foreach ($a' '$a' + Test-ErrorStmt ':lab foreach ($a $zz' ':lab foreach ($a' '$a' + Test-ErrorStmt ':lab foreach ($a in' ':lab foreach ($a in' '$a' + Test-ErrorStmt ':lab foreach ($a in $b' ':lab foreach ($a in $b' '$a' '$b' '$b' '$b' + Test-ErrorStmt ':lab foreach ($a in $b <#hmm#>)' ':lab foreach ($a in $b <#hmm#>)' '$a' '$b' '$b' '$b' +} + +Describe 'do/while statement statement parsing' -Tags "CI" { + ShouldBeParseError 'do' MissingLoopStatement 2 + ShouldBeParseError 'do {}' MissingWhileOrUntilInDoWhile 5 + ShouldBeParseError 'do {} while' MissingOpenParenthesisAfterKeyword 11 + ShouldBeParseError 'do {} while (' MissingExpressionAfterKeyword 13 + ShouldBeParseError 'do {} while (1' MissingEndParenthesisAfterStatement 14 + ShouldBeParseError ':lab do' MissingLoopStatement 8 -CheckColumnNumber + ShouldBeParseError ':lab do {}' MissingWhileOrUntilInDoWhile 11 -CheckColumnNumber + ShouldBeParseError ':lab do {} while' MissingOpenParenthesisAfterKeyword 17 -CheckColumnNumber + ShouldBeParseError ':lab do {} while (' MissingExpressionAfterKeyword 19 -CheckColumnNumber + ShouldBeParseError ':lab do {} while (1' MissingEndParenthesisAfterStatement 20 -CheckColumnNumber + + Test-ErrorStmt 'do' 'do' + Test-ErrorStmt 'do {1}' 'do {1}' '{1}' '1' '1' '1' + Test-ErrorStmt 'do {1} while' 'do {1} while' '{1}' '1' '1' '1' + Test-ErrorStmt 'do {1} while(' 'do {1} while(' '{1}' '1' '1' '1' + Test-ErrorStmt 'do {1} while($false' 'do {1} while($false' '{1}' '1' '1' '1' '$false' '$false' '$false' + Test-ErrorStmt ':lab do' ':lab do' + Test-ErrorStmt ':lab do {1}' ':lab do {1}' '{1}' '1' '1' '1' + Test-ErrorStmt ':lab do {1} while' ':lab do {1} while' '{1}' '1' '1' '1' + Test-ErrorStmt ':lab do {1} while(' ':lab do {1} while(' '{1}' '1' '1' '1' + Test-ErrorStmt ':lab do {1} while($false' ':lab do {1} while($false' '{1}' '1' '1' '1' '$false' '$false' '$false' +} + + +Describe 'do/while statement statement parsing' -Tags "CI" { + ShouldBeParseError 'do' MissingLoopStatement 3 -CheckColumnNumber + ShouldBeParseError 'do {}' MissingWhileOrUntilInDoWhile 6 -CheckColumnNumber + ShouldBeParseError 'do {} until' MissingOpenParenthesisAfterKeyword 12 -CheckColumnNumber + ShouldBeParseError 'do {} until (' MissingExpressionAfterKeyword 14 -CheckColumnNumber + ShouldBeParseError 'do {} until (1' MissingEndParenthesisAfterStatement 15 -CheckColumnNumber + ShouldBeParseError ':lab do' MissingLoopStatement 8 -CheckColumnNumber + ShouldBeParseError ':lab do {}' MissingWhileOrUntilInDoWhile 10 + ShouldBeParseError ':lab do {} until' MissingOpenParenthesisAfterKeyword 16 + ShouldBeParseError ':lab do {} until (' MissingExpressionAfterKeyword 18 + ShouldBeParseError ':lab do {} until (1' MissingEndParenthesisAfterStatement 19 + + Test-ErrorStmt 'do' 'do' + Test-ErrorStmt 'do {1}' 'do {1}' '{1}' '1' '1' '1' + Test-ErrorStmt 'do {1} until' 'do {1} until' '{1}' '1' '1' '1' + Test-ErrorStmt 'do {1} until(' 'do {1} until(' '{1}' '1' '1' '1' + Test-ErrorStmt 'do {1} until($false' 'do {1} until($false' '{1}' '1' '1' '1' '$false' '$false' '$false' + Test-ErrorStmt ':lab do' ':lab do' + Test-ErrorStmt ':lab do {1}' ':lab do {1}' '{1}' '1' '1' '1' + Test-ErrorStmt ':lab do {1} until' ':lab do {1} until' '{1}' '1' '1' '1' + Test-ErrorStmt ':lab do {1} until(' ':lab do {1} until(' '{1}' '1' '1' '1' + Test-ErrorStmt ':lab do {1} until($false' ':lab do {1} until($false' '{1}' '1' '1' '1' '$false' '$false' '$false' +} + +Describe 'trap statement parsing' -Tags "CI" { + + ShouldBeParseError 'trap' MissingTrapStatement 4 + ShouldBeParseError 'trap [int]' MissingTrapStatement 11 -CheckColumnNumber + + Test-ErrorStmt 'trap' 'trap' + Test-ErrorStmt 'trap [int]' 'trap [int]' '[int]' +} + + +Describe 'named blocks parsing' -Tags "CI" { + ShouldBeParseError 'begin' MissingNamedStatementBlock 5 + ShouldBeParseError 'process' MissingNamedStatementBlock 7 + ShouldBeParseError 'end' MissingNamedStatementBlock 3 + ShouldBeParseError 'dynamicparam' MissingNamedStatementBlock 12 + ShouldBeParseError 'begin process {}' MissingNamedStatementBlock 6 -CheckColumnNumber + ShouldBeParseError 'end process {}' MissingNamedStatementBlock 4 -CheckColumnNumber + ShouldBeParseError 'dynamicparam process {}' MissingNamedStatementBlock 13 -CheckColumnNumber + ShouldBeParseError 'process begin {}' MissingNamedStatementBlock 8 -CheckColumnNumber + ShouldBeParseError 'begin process end' MissingNamedStatementBlock,MissingNamedStatementBlock,MissingNamedStatementBlock 6,14,18 -CheckColumnNumber + + Test-Ast 'begin' 'begin' 'begin' + Test-Ast 'begin end' 'begin end' 'begin' 'end' + Test-Ast 'begin end process' 'begin end process' 'begin' 'end' 'process' + Test-Ast 'begin {} end' 'begin {} end' 'begin {}' 'end' +} + + # + # data statement + # +Describe 'data statement parsing' -Tags "CI" { + ShouldBeParseError 'data' MissingStatementBlockForDataSection 5 -CheckColumnNumber + ShouldBeParseError 'data foo' MissingStatementBlockForDataSection 9 -CheckColumnNumber + ShouldBeParseError 'data -abc' InvalidParameterForDataSectionStatement 6 -CheckColumnNumber + ShouldBeParseError 'data -abc foo {}' InvalidParameterForDataSectionStatement 6 -CheckColumnNumber + ShouldBeParseError 'data -abc & {}' InvalidParameterForDataSectionStatement 5 + ShouldBeParseError 'data -s & {}' MissingValueForSupportedCommandInDataSectionStatement 7 + ShouldBeParseError 'data -s ) {}' MissingValueForSupportedCommandInDataSectionStatement,UnexpectedToken 8,9 -CheckColumnNumber + ShouldBeParseError 'data -s } {}' MissingValueForSupportedCommandInDataSectionStatement,UnexpectedToken 7,8 + ShouldBeParseError 'data -s ; {}' MissingValueForSupportedCommandInDataSectionStatement 7 + ShouldBeParseError 'data -sup a,' MissingValueForSupportedCommandInDataSectionStatement 13 -CheckColumnNumber + ShouldBeParseError 'data -sup a,b' MissingStatementBlockForDataSection 14 -CheckColumnNumber + + Test-ErrorStmt 'data' 'data' + Test-ErrorStmt 'data -s & {}' 'data -s' + Test-ErrorStmt 'data -s ) {}' 'data -s' + Test-ErrorStmt 'data -s abc' 'data -s abc' 'abc' + Test-ErrorStmt 'data -s abc,' 'data -s abc,' 'abc' + Test-ErrorStmt 'data -s a,b' 'data -s a,b' 'a' 'b' +} + + # + # try/catch/finally statement + # + +Describe 'try/catch/finally statement parsing' -Tags "CI" { + ShouldBeParseError 'try' MissingTryStatementBlock 3 + ShouldBeParseError 'try {}' MissingCatchOrFinally 6 + ShouldBeParseError 'try {} catch' MissingCatchHandlerBlock 12 + ShouldBeParseError 'try {} finally' MissingFinallyStatementBlock 15 -CheckColumnNumber + ShouldBeParseError 'try {} catch [int]' MissingCatchHandlerBlock 19 -CheckColumnNumber + ShouldBeParseError 'try {} catch {} finally' MissingFinallyStatementBlock 23 + ShouldBeParseError 'try {} catch {} catch' MissingCatchHandlerBlock 21 + ShouldBeParseError 'try {} catch [int],' MissingTypeLiteralToken 19 + ShouldBeParseError 'try {} finally { return }' ControlLeavingFinally 17 + ShouldBeParseError 'try {} finally { break }' ControlLeavingFinally 17 + ShouldBeParseError 'try {} finally { continue }' ControlLeavingFinally 17 + + Test-ErrorStmt 'try' 'try' + Test-ErrorStmt 'try {1}' 'try {1}' '{1}' '1' '1' '1' + Test-ErrorStmt 'try {1} catch' 'try {1} catch' '{1}' '1' '1' '1' + Test-ErrorStmt 'try {1} finally' 'try {1} finally' '{1}' '1' '1' '1' + Test-ErrorStmt 'try {1} catch [int]' 'try {1} catch [int]' '{1}' '1' '1' '1' '[int]' + Test-ErrorStmt 'try {1} catch {2} finally' 'try {1} catch {2} finally' '{1}' '1' '1' '1' 'catch {2}' '{2}' '2' '2' '2' + Test-ErrorStmt 'try {1} catch {2} catch' 'try {1} catch {2} catch' '{1}' '1' '1' '1' 'catch {2}' '{2}' '2' '2' '2' + Test-ErrorStmt 'try {1} catch [int],[char] {2} catch' 'try {1} catch [int],[char] {2} catch' '{1}' '1' '1' '1' 'catch [int],[char] {2}' '{2}' '2' '2' '2' '[int]' '[char]' + Test-ErrorStmt 'try {1} catch [int],' 'try {1} catch [int],' '{1}' '1' '1' '1' '[int]' +} + + +Describe 'switch statement parsing' -Tags "CI" { + ShouldBeParseError 'switch' PipelineValueRequired 6 + ShouldBeParseError 'switch -abc' InvalidSwitchFlag,PipelineValueRequired 7,11 + ShouldBeParseError 'switch -file' MissingFilenameOption 12 + ShouldBeParseError 'switch -file a (1)' PipelineValueRequired,MissingCurlyBraceInSwitchStatement 15,18 + ShouldBeParseError 'switch (' PipelineValueRequired 8 + ShouldBeParseError 'switch ()' PipelineValueRequired,MissingCurlyBraceInSwitchStatement 8,9 + ShouldBeParseError 'switch ("abc") ' MissingCurlyBraceInSwitchStatement 14 + ShouldBeParseError 'switch ("abc") {' MissingSwitchConditionExpression 17 + ShouldBeParseError 'switch ("abc") { 1' MissingSwitchStatementClause 19 + ShouldBeParseError 'switch ("abc") { 1 }' MissingSwitchStatementClause 19 + ShouldBeParseError 'switch (1) {default {} default {}}' MultipleSwitchDefaultClauses 23 + + Test-ErrorStmt 'switch' 'switch' + Test-ErrorStmt 'switch -abc' 'switch -abc' + Test-ErrorStmt 'switch (' 'switch (' + Test-ErrorStmt 'switch ()' 'switch ()' + Test-ErrorStmt 'switch -file' 'switch -file' + Test-ErrorStmt 'switch -file a' 'switch -file a' + Test-ErrorStmtForSwitchFlag 'switch -file a' 'file' 'a' 'a' 'a' + Test-ErrorStmt 'switch -file a (1)' 'switch -file a (1)' '1' '1' '1' + Test-ErrorStmtForSwitchFlag 'switch -file a (1)' 'file' 'a' 'a' 'a' + Test-ErrorStmt 'switch (1) {foo' 'switch (1) {foo' 'foo' '1' '1' '1' + Test-ErrorStmt 'switch (1) {foo}' 'switch (1) {foo' 'foo' '1' '1' '1' + Test-ErrorStmt 'switch (1) {foo {bar}' 'switch (1) {foo {bar}' 'foo' '{bar}' 'bar' 'bar' 'bar' '1' '1' '1' + Test-ErrorStmt 'switch (1) {default {9} default{2}' 'switch (1) {default {9} default{2}' 'default' '{9}' '9' '9' '9' 'default' '{2}' '2' '2' '2' '1' '1' '1' +} + + +Describe 'function statement parsing' -Tags "CI" { + ShouldBeParseError 'function' MissingNameAfterKeyword 8 + ShouldBeParseError 'function foo' MissingFunctionBody 12 + ShouldBeParseError 'function foo(' MissingEndParenthesisInFunctionParameterList 13 + ShouldBeParseError 'function foo {' MissingEndCurlyBrace 13 + ShouldBeParseError 'function foo { function bar { if (1) {} }' MissingEndCurlyBrace 13 + ShouldBeParseError 'function f { param($a,[int]$a) }' DuplicateFormalParameter 27 + ShouldBeParseError 'function f($a,[int]$a){}' DuplicateFormalParameter 19 + ShouldBeParseError 'function foo {param(}' MissingEndParenthesisInFunctionParameterList 20 + + Test-ErrorStmt 'function foo()' 'function foo()' + Test-ErrorStmt 'function foo($a)' 'function foo($a)' '$a' '$a' + Test-ErrorStmt 'function foo($a = 1)' 'function foo($a = 1)' '$a = 1' '1' '$a' + Test-ErrorStmt 'function foo($a' 'function foo($a' '$a' '$a' + Test-ErrorStmt 'function foo($a 1' 'function foo($a' '$a' '$a' + Test-ErrorStmt 'function foo($a = 1' 'function foo($a = 1' '$a = 1' '1' '$a' +} + + +Describe 'assignment statement parsing' -Tags "CI" { + ShouldBeParseError '$a,$b += 1,2' InvalidLeftHandSide 0 +} + + +Describe 'splatting parsing' -Tags "CI" { + ShouldBeParseError '@a' SplattingNotPermitted 0 + ShouldBeParseError 'foreach (@a in $b) {}' SplattingNotPermitted 9 + ShouldBeParseError 'param(@a)' SplattingNotPermitted 6 + ShouldBeParseError 'function foo (@a) {}' SplattingNotPermitted 14 +} + + +Describe 'Pipes parsing' -Tags "CI" { + ShouldBeParseError 'gps|' EmptyPipeElement 4 + ShouldBeParseError '1|1' ExpressionsMustBeFirstInPipeline 2 + ShouldBeParseError '$a=' ExpectedValueExpression 3 + ShouldBeParseError '1 &' UnexpectedToken,MissingExpression 2,2 +} + +Describe 'commands parsing' -Tags "CI" { + ShouldBeParseError 'gcm -a:' ParameterRequiresArgument 7 + ShouldBeParseError 'gcm -a: 1,' MissingExpression 11 -CheckColumnNumber + ShouldBeParseError 'gcm ,' MissingArgument 4 +} + + # + # tokens + # +Describe 'tokens parsing' -Tags "CI" { + ShouldBeParseError ' )' UnexpectedToken 3 + ShouldBeParseError ' }' UnexpectedToken 4 -CheckColumnNumber +} + + +Describe 'expressions parsing' -Tags "CI" { + ShouldBeParseError '1+' ExpectedValueExpression 2 + ShouldBeParseError '[a()][b]' UnexpectedAttribute 0 + ShouldBeParseError '[a()][b]2' UnexpectedAttribute 0 + ShouldBeParseError '[ref][ref]$x' ReferenceNeedsToBeByItselfInTypeSequence 5 + ShouldBeParseError '[int][ref]$x' ReferenceNeedsToBeLastTypeInTypeConversion 5 + ShouldBeParseError '[int][ref]$x = 42' ReferenceNeedsToBeByItselfInTypeConstraint 5 +} \ No newline at end of file diff --git a/test/powershell/Language/Scripting/I18n.Tests.ps1 b/test/powershell/Language/Scripting/I18n.Tests.ps1 new file mode 100644 index 0000000000..8fcba54a03 --- /dev/null +++ b/test/powershell/Language/Scripting/I18n.Tests.ps1 @@ -0,0 +1,185 @@ +#This works only for en-US or fr-FR +if ($PSUICulture -ne 'en-US' -and $PSUICulture -ne 'fr-FR') +{ + return +} + + +Describe 'Testing of script internationalization' -Tags "CI" { + BeforeAll { + $dir=$PSScriptRoot + } + + It 'converFromString-Data.' { + + data mydata + { + ConvertFrom-StringData @' + string1=string1 + string2=string2 +'@ + } + + $mydata.string1 | Should Be 'string1' + $mydata.string2 | Should Be 'string2' + } + + It 'Import default culture' { + + import-localizedData mydata; + + $mydata.string1 | Should Be 'string1 for en-US' + $mydata.string2 | Should be 'string2 for en-US' + } + + It 'Import specific culture' { + + import-localizedData mydata -uiculture en-US + + $mydata.string1 | Should Be 'string1 for en-US' + $mydata.string2 | Should Be 'string2 for en-US' + + import-localizedData mydata -uiculture fr-FR + + $mydata.string1 | Should Be 'string1 for fr-FR' + $mydata.string2 | Should Be 'string2 for fr-FR' + } + + It 'Import non existing culture' { + + import-localizedData mydata -uiculture nl-NL -ea SilentlyContinue -ev ev + + $ev[0].Exception.GetType() | Should Be System.Management.Automation.PSInvalidOperationException + } + + It 'Import different file name' { + + import-localizedData mydata -filename foo + + $mydata.string1 | Should Be 'string1 from foo in en-US' + $mydata.string2 | Should Be 'string2 from foo in en-US' + + import-localizedData mydata -filename foo -uiculture fr-FR + + $mydata.string1 | Should Be 'string1 from foo in fr-FR' + $mydata.string2 | Should Be 'string2 from foo in fr-FR' + } + + It 'Import different file base' { + + import-localizedData mydata -basedirectory "${dir}\newbase" + + $mydata.string1 | Should Be 'string1 for en-US under newbase' + $mydata.string2 | Should Be 'string2 for en-US under newbase' + + import-localizedData mydata -basedirectory "${dir}\newbase" -uiculture fr-FR + + $mydata.string1 | Should Be 'string1 for fr-FR under newbase' + $mydata.string2 | Should Be 'string2 for fr-FR under newbase' + } + + It 'Import different file base and file name' { + + import-localizedData mydata -basedirectory "${dir}\newbase" -filename foo + + $mydata.string1 | Should Be 'string1 for en-US from foo under newbase' + $mydata.string2 | Should Be 'string2 for en-US from foo under newbase' + + import-localizedData mydata -basedirectory "${dir}\newbase" -filename foo -uiculture fr-FR + + $mydata.string1 | Should Be 'string1 for fr-FR from foo under newbase' + $mydata.string2 | Should Be 'string2 for fr-FR from foo under newbase' + } + + It "Import variable that doesn't exist" { + + import-localizedData mydata2 + + $mydata2.string1 | Should Be 'string1 for en-US' + $mydata2.string2 | Should Be 'string2 for en-US' + } + + It 'Import bad psd1 file - tests the use of disallowed variables' { + + $script:exception = $null + & { + trap {$script:exception = $_ ; continue } + import-localizedData mydata -filename bad + } + + $script:exception.exception.gettype() | Should Be System.management.automation.psinvalidoperationexception + } + + It 'Import if psd1 file' { + + import-localizedData mydata -filename if + + if ($psculture -eq 'en-US') + { + $mydata.string1 | Should Be 'string1 for en-US in if' + $mydata.string2 | Should Be 'string2 for en-US in if' + } + else + { + $mydata | Should Be $null + } + } + + It 'Allowed cmdlets checked properly' { + + $script:exception = $null + & { + trap {$script:exception = $_.Exception ; continue } + iex 'data d { @{ x=$(get-command)} }' + } + $exception -like '*get-command*' | Should Be $true + + + $script:exception = $null + & { + trap {$script:exception = $_.Exception ; continue } + iex 'data d { if ($(get-command)) {} }' + } + $exception -like '*get-command*' | Should Be $true + + + $script:exception = $null + & { + trap {$script:exception = $_.Exception ; continue } + iex 'data d { @(get-command) }' + } + $exception -like '*get-command*' | Should Be $true + } + + + It 'Check alternate syntax that also supports complex variable names' { + + & { + $script:mydata = data { 123 } + } + $mydata | Should Be 123 + + $mydata = data { 456 } + & { + # This import should not clobber the one at script scope + import-localizedData mydata -uiculture en-US + } + $mydata | Should Be 456 + + & { + # This import should clobber the one at script scope + import-localizedData script:mydata -uiculture en-US + } + $script:mydata.string1 | Should Be 'string1 for en-US' + } + + + It 'Check fallback to current directory plus -SupportedCommand parameter' { + + new-alias MyConvertFrom-StringData ConvertFrom-StringData + + import-localizeddata local:mydata -uiculture fr-ca -filename I18n.Tests_fallback.psd1 -SupportedCommand MyConvertFrom-StringData + $mydata[0].string1 | Should Be 'fallback string1 for en-US' + $mydata[1] | Should Be 42 + } +} diff --git a/test/powershell/Language/Scripting/I18n.Tests_fallback.psd1 b/test/powershell/Language/Scripting/I18n.Tests_fallback.psd1 new file mode 100644 index 0000000000..f0a856fbd3 --- /dev/null +++ b/test/powershell/Language/Scripting/I18n.Tests_fallback.psd1 @@ -0,0 +1,5 @@ +MyConvertFrom-StringData @' +string1=fallback string1 for en-US +string2=fallback string2 for en-US +'@ +42 \ No newline at end of file diff --git a/test/powershell/Language/Scripting/ScriptHelp.Tests.ps1 b/test/powershell/Language/Scripting/ScriptHelp.Tests.ps1 new file mode 100644 index 0000000000..a2ebc701a1 --- /dev/null +++ b/test/powershell/Language/Scripting/ScriptHelp.Tests.ps1 @@ -0,0 +1,561 @@ + Describe 'get-help HelpFunc1' -Tags "CI" { + + BeforeAll { + function TestHelpError { + [CmdletBinding()] + param( + $x, + [System.Management.Automation.ErrorRecord[]]$e, + [string] $expectedError + ) + It 'Help result should be $null' { $x | Should Be $null } + It '$e.Count' { $e.Count | Should BeGreaterThan 0 } + It 'FullyQualifiedErrorId' { $e[0].FullyQualifiedErrorId | Should Be $expectedError } + } + + function TestHelpFunc1 { + [CmdletBinding()] + param( $x ) + It '$x should not be $null' { $x | Should Not Be $null } + It '$x.Synopsis' { $x.Synopsis | Should Be "A relatively useless function." } + It '$x.Description' { $x.Description[0].Text | Should Be "A description`n`n with indented text and a blank line." } + It '$x.alertSet.alert' { $x.alertSet.alert[0].Text | Should Be "This function is mostly harmless." } + It '$x.relatedLinks.navigationLink[0].uri' { $x.relatedLinks.navigationLink[0].uri | Should Be "http://blogs.msdn.com/powershell" } + It '$x.relatedLinks.navigationLink[1].linkText' { $x.relatedLinks.navigationLink[1].linkText | Should Be "other commands" } + It '$x.examples.example.code' { $x.examples.example.code | Should Be "If you need an example, you're hopeless." } + It '$x.inputTypes.inputType.type.name‘ { $x.inputTypes.inputType.type.name | Should Be "Anything you like." } + It '$x.returnValues.returnValue.type.name' { $x.returnValues.returnValue.type.name | Should Be "Nothing." } + It '$x.Component' { $x.Component | Should Be "Something" } + It '$x.Role' { $x.Role | Should Be "CrazyUser" } + It '$x.Functionality' { $x.Functionality | Should Be "Useless" } + } + + # .SYNOPSIS + # + # A relatively useless function. + # + # .DESCRIPTION + # + # A description + # + # with indented text and a blank line. + # + # .NOTES + # + # This function is mostly harmless. + # + # .LINK + # + # http://blogs.msdn.com/powershell + # + # .LINK + # + # other commands + # + # .EXAMPLE + # + # If you need an example, you're hopeless. + # + # .INPUTS + # + # Anything you like. + # + # .OUTPUTS + # + # Nothing. + # + # .COMPONENT + # + # Something + # + # .ROLE + # + # CrazyUser + # + # .FUNCTIONALITY + # + # Useless + # + function helpFunc1 {} + } + + + Context 'Get-Help helpFunc1' { + $x = get-help helpFunc1 + TestHelpFunc1 $x + } + + Context 'get-help helpFunc1 -component blah' { + $x = get-help helpFunc1 -component blah -ea SilentlyContinue -ev e + TestHelpError $x $e 'HelpNotFound,Microsoft.PowerShell.Commands.GetHelpCommand' + } + + Context 'get-help helpFunc1 -component Something' { + $x = get-help helpFunc1 -component Something -ea SilentlyContinue -ev e + TestHelpFunc1 $x + It '$e should be empty' { $e.Count | Should Be 0 } + } + + Context 'get-help helpFunc1 -role blah' { + $x = get-help helpFunc1 -component blah -ea SilentlyContinue -ev e + TestHelpError $x $e 'HelpNotFound,Microsoft.PowerShell.Commands.GetHelpCommand' + } + + Context 'get-help helpFunc1 -role CrazyUser' { + $x = get-help helpFunc1 -role CrazyUser -ea SilentlyContinue -ev e + TestHelpFunc1 $x + It '$e should be empty' { $e.Count | Should Be 0 } + } + + Context '$x = get-help helpFunc1 -functionality blah' { + $x = get-help helpFunc1 -functionality blah -ea SilentlyContinue -ev e + TestHelpError $x $e 'HelpNotFound,Microsoft.PowerShell.Commands.GetHelpCommand' + } + + Context '$x = get-help helpFunc1 -functionality Useless' { + $x = get-help helpFunc1 -functionality Useless -ea SilentlyContinue -ev e + TestHelpFunc1 $x + It '$e should be empty' { $e.Count | Should Be 0 } + } +} + +Describe 'get-help file' -Tags "CI" { + BeforeAll { + try { + $tmpfile = [IO.Path]::ChangeExtension([IO.Path]::GetTempFileName(), "ps1") + } catch { + return + } + } + + AfterAll { + remove-item $tmpfile -Force -ea silentlycontinue + } + + Context 'get-help file1' { + + @' + # .SYNOPSIS + # Function help, not script help + function foo + { + } + + get-help foo +'@ > $tmpfile + + $x = get-help $tmpfile + It '$x should not be $null' { $x | Should Not Be $null } + $x = & $tmpfile + It '$x.Synopsis' { $x.Synopsis | Should Be 'Function help, not script help' } + } + + Context 'get-help file2' { + + # Note - 2 blank lines below are intentional, do not delete + @' + # .SYNOPSIS + # Script help, not function help + + + function foo + { + } + + get-help foo +'@ > $tmpfile + + $x = get-help $tmpfile + It '$x.Synopsis' { $x.Synopsis | Should Be 'Script help, not function help' } + $x = & $tmpfile + It '$x should not be $null' { $x | Should Not Be $null } + } +} + +Describe 'get-help other tests' -Tags "CI" { + + BeforeAll { + try { + $tempFile = [IO.Path]::ChangeExtension([IO.Path]::GetTempFileName(), "ps1") + } catch { + return + } + } + + AfterAll { + remove-item $tempFile -Force -ea silentlycontinue + } + + Context 'get-help missingHelp' { + # Blank lines here are important, do not adjust the formatting, remove blank lines, etc. + + <# + .SYNOPSIS + This help block doesn't belong to any function because it is more than 1 line away from the function. + #> + + + function missingHelp { param($abc) } + $x = get-help missingHelp + It '$x should not be $null' { $x | Should Not Be $null } + It '$x.Synopsis' { $x.Synopsis.Trim() | Should Be 'missingHelp [[-abc] ]' } + } + + Context 'get-help helpFunc2' { + + <# + .SYNOPSIS + This help block goes on helpFunc2 + #> + + function helpFunc2 { param($abc) } + + $x = get-help helpFunc2 + It '$x should not be $null' { $x | Should Not Be $null } + It '$x.Synopsis' { $x.Synopsis.Trim() | Should Be 'This help block goes on helpFunc2' } + } + + Context 'get-help file and get-help helpFunc2' { + $script = @" + <# + .SYNOPSIS + This is script help + #> + + <# + .SYNOPSIS + This is function help for helpFunc2 + #> + function helpFunc2 {} + + get-help helpFunc2 +"@ + + Set-Content $tempFile $script + $x = get-help $tempFile + It '$x.Synopsis' { $x.Synopsis | Should Be "This is script help" } + + $x = & $tempFile + It '$x.Synopsis' { $x.Synopsis | Should Be "This is function help for helpFunc2" } + } + + Context 'get-help file and get-help helpFunc2' { + $script = @" + # + # .SYNOPSIS + # This is script help + # + + # + # .SYNOPSIS + # This is function help for helpFunc2 + # + function helpFunc2 {} + + get-help helpFunc2 +"@ + + Set-Content $tempFile $script + $x = get-help $tempFile + It $x.Synopsis { $x.Synopsis | Should Be "This is script help" } + + $x = & $tempFile + It $x.Synopsis { $x.Synopsis | Should Be "This is function help for helpFunc2" } + } + + Context 'get-help psuedo file' { + + $script = @' + ########################################### + # + # Psuedo-Copyright header comment + # + ########################################### + + #requires -version 2.0 + + # + # .Synopsis + # Changes Admin passwords across all KDE servers. + # + [CmdletBinding(DefaultParameterSetName="Live")] + param( + [Parameter( + ParameterSetName="Live", + Mandatory=$true)] + $live, + [Parameter( + ParameterSetName="Test", + Mandatory=$true)] + $test) +'@ + + Set-Content $tempFile $script + $x = get-help $tempFile + + It '$x.Synopsis' { $x.Synopsis | Should Be "Changes Admin passwords across all KDE servers." } + It '$x.parameters.parameter[0].required' { $x.parameters.parameter[0].required | Should Be $true} + It '$x.syntax.syntaxItem[0].parameter.required' { $x.syntax.syntaxItem[0].parameter.required | Should Be $true} + It '$x.syntax.syntaxItem[0].parameter.parameterValue.required' { $x.syntax.syntaxItem[0].parameter.parameterValue.required | Should Be $true} + It 'Common parameters should not be appear in the syntax' { $x.Syntax -like "*verbose*" | Should Be $false } + It 'Common parameters should not be in syntax maml' {@($x.syntax.syntaxItem[0].parameter).Count | Should Be 1} + It 'Common parameters should also not appear in parameters maml' { $x.parameters.parameter.Count | Should Be 2} + } + + Context 'helpFunc3 -?' { + + + ############################################## + + function helpFunc3() + { + # + # + #.Synopsis + # + # A synopsis of helpFunc3. + # + # + } + + $x = helpFunc3 -? + It '$x.Synopsis' { $x.Synopsis | Should Be "A synopsis of helpFunc3." } + } + + Context 'get-help helpFunc4' { + + <# + .Description + description + + .Synopsis + + + .Component + component + #> + function helpFunc4() + { + } + + $x = get-help helpFunc4 + It '$x.Synopsis should be empty' { $x.Synopsis | Should Be "" } + } + + Context 'get-help helpFunc5' { + + function helpFunc5 + { + # .EXTERNALHELP scriptHelp.Tests.xml + } + $x = get-help helpFunc5 + It '$x should not be $null' { $x | Should Not Be $null } + It '$x.Synopsis' { $x.Synopsis | Should Be "A useless function, really." } + } + + Context 'get-help helpFunc6 script help xml' { + function helpFunc6 + { + # .EXTERNALHELP scriptHelp1.xml + } + if ($PSUICulture -ieq "en-us") + { + $x = get-help helpFunc6 + It '$x should not be $null' { $x | Should Not Be $null } + It '$x.Synopsis' { $x.Synopsis | Should Be "Useless. Really, trust me on this one." } + } + } + + Context 'get-help helpFunc6 script help xml' { + function helpFunc6 + { + # .EXTERNALHELP newbase/scriptHelp1.xml + } + if ($PSUICulture -ieq "en-us") + { + $x = get-help helpFunc6 + It '$x should not be $null' { $x | Should Not Be $null } + It '$x.Synopsis' { $x.Synopsis | Should Be "Useless in newbase. Really, trust me on this one." } + } + } + + Context 'get-help helpFunc7' { + + function helpFunc7 + { + # .FORWARDHELPTARGETNAME Get-Help + # .FORWARDHELPCATEGORY Cmdlet + } + $x = Get-Help helpFunc7 + It '$x.Name' { $x.Name | Should Be 'Get-Help' } + It '$x.Category' { $x.Category | Should Be 'Cmdlet' } + + # Make sure help is a function, or the test would fail + if ($null -ne (get-command -type Function help)) + { + if ((get-content function:help) -match "FORWARDHELP") + { + $x = Get-Help help + It '$x.Name' { $x.Name | Should Be 'Get-Help' } + It '$x.Category' { $x.Category | Should Be 'Cmdlet' } + } + } + } + + Context 'get-help helpFunc8' { + + function func8 + { + # .SYNOPSIS + # Help on helpFunc8, not func8 + function helpFunc8 + { + } + get-help helpFunc8 + } + + $x = Get-Help func8 + It '$x should not be $null' { $x | Should Not Be $null } + + $x = func8 + It '$x.Synopsis' { $x.Synopsis | Should Be 'Help on helpFunc8, not func8' } + } + + Context 'get-help helpFunc9' { + function helpFunc9 + { + # .SYNOPSIS + # Help on helpFunc9, not func9 + param($x) + + function func9 + { + } + get-help func9 + } + $x = Get-Help helpFunc9 + It 'help is on the outer functon' { $x.Synopsis | Should Be 'Help on helpFunc9, not func9' } + $x = helpFunc9 + It '$x should not be $null' { $x | Should Not Be $null } + } + + Context 'get-help helpFunc10' { + ####################################################### + # .SYNOPSIS + # Help on helpFunc10 + ####################################################### + function helpFunc10 + { + } + + $x = get-help helpFunc10 + It '$x.Synopsis' { $x.Synopsis | Should Be 'Help on helpFunc10' } + } + + Context 'get-help helpFunc11' { + function helpFunc11 + { + # .Synopsis + # + # useless, sorry + + param( + + # not in help + + <# abc #><# help #> [parameter()] [string] + $abc, + + [string] + # def help + $def, + + [parameter()] + # ghi help + $ghi, + + # jkl help + + $jkl, + + <#mno help#>$mno, + <#pqr help#>[int]$pqr + + ) + } + + $x = get-help helpFunc11 -det + $x.Parameters.parameter | % { + It '$_.description' { $_.description[0].text | Should match "^$($_.Name)\s+help" } + } + } + + Context 'get-help helpFunc12' { + # Test case w/ cmdlet binding, but no parameter sets. + function helpFunc12 { + Param ([Parameter(Mandatory=$true)][String]$Name, + [string]$Extension = "txt", + $NoType, + [switch]$ASwitch, + [System.Management.Automation.CommandTypes]$AnEnum) + $name = $name + "." + $extension + $name + + <# + .SYNOPSIS + Adds a file name extension to a supplied name. + + .EXAMPLE + + PS>helpFunc12 -Name foo + + Adds .txt to foo + + .EXAMPLE + + C:\PS>helpFunc12 bar txt + + Adds .txt to bar + #> + } + $x = get-help helpFunc12 + It '$x.syntax' { ($x.syntax | Out-String -width 250) | Should match "helpFunc12 \[-Name] \[\[-Extension] ] \[\[-NoType] ] \[-ASwitch] \[\[-AnEnum] \{Alias.*All}] \[]" } + It '$x.syntax.syntaxItem.parameter[3].position' { $x.syntax.syntaxItem.parameter[3].position | Should Be 'named' } + It '$x.syntax.syntaxItem.parameter[3].parameterValue' { $x.syntax.syntaxItem.parameter[3].parameterValue | Should Be $null } + It '$x.parameters.parameter[3].parameterValue' { $x.parameters.parameter[3].parameterValue | Should Not Be $null } + It '$x.syntax.syntaxItem.parameter[4].parameterValueGroup' { $x.syntax.syntaxItem.parameter[4].parameterValueGroup | Should Not be $null } + It '$x.parameters.parameter[4].parameterValueGroup' { $x.parameters.parameter[4].parameterValueGroup | Should Not be $null } + It '$x.examples.example[0].introduction[0].text' { $x.examples.example[0].introduction[0].text | Should Be 'PS>' } + It '$x.examples.example[0].code' { $x.examples.example[0].code | Should Be 'helpFunc12 -Name foo' } + It '$x.examples.example[0].remarks[0].text' { $x.examples.example[0].remarks[0].text | Should Be 'Adds .txt to foo' } + It '$x.examples.example[0].remarks.length' { $x.examples.example[0].remarks.length | Should Be 5 } + It '$x.examples.example[1].introduction[0].text' { $x.examples.example[1].introduction[0].text | Should Be 'C:\PS>' } + It '$x.examples.example[1].code' { $x.examples.example[1].code | Should Be 'helpFunc12 bar txt' } + It '$x.examples.example[1].remarks[0].text' { $x.examples.example[1].remarks[0].text | Should Be 'Adds .txt to bar' } + It '$x.examples.example[1].remarks.length' { $x.examples.example[1].remarks.length | Should Be 5 } + } + + Context 'get-help helpFunc12' { + function helpFunc13 + { + <# + .Synopsis + + empty synopsis + #> + param( + [SupportsWildcards()] + $p1, + $p2 = 42, + [PSDefaultValue(Help="parameter is mandatory")] + $p3 = $(throw "parameter p3 is not specified") + ) + } + + $x = get-help helpFunc13 + + It '$x.Parameters.parameter[0].globbing' { $x.Parameters.parameter[0].globbing | Should Be 'true' } + It '$x.Parameters.parameter[1].defaultValue' { $x.Parameters.parameter[1].defaultValue | Should Be '42' } + It '$x.Parameters.parameter[2].defaultValue' { $x.Parameters.parameter[2].defaultValue | Should Be 'parameter is mandatory' } + } +} \ No newline at end of file diff --git a/test/powershell/Language/Scripting/ScriptHelp.Tests.xml b/test/powershell/Language/Scripting/ScriptHelp.Tests.xml new file mode 100644 index 0000000000..050d2d6fe0 --- /dev/null +++ b/test/powershell/Language/Scripting/ScriptHelp.Tests.xml @@ -0,0 +1,28 @@ + + + + + + + + helpFunc5 + + + A useless function, really. + + + + + + + + helpFunc6 + + + Useless. Really, trust me on this one. + + + + + + diff --git a/test/powershell/Language/Scripting/en-US/I18n.Tests.psd1 b/test/powershell/Language/Scripting/en-US/I18n.Tests.psd1 new file mode 100644 index 0000000000..c8d1550f8a --- /dev/null +++ b/test/powershell/Language/Scripting/en-US/I18n.Tests.psd1 @@ -0,0 +1,4 @@ +ConvertFrom-StringData @' +string1=string1 for en-US +string2=string2 for en-US +'@ # SIG # Begin signature block diff --git a/test/powershell/Language/Scripting/en-US/bad.psd1 b/test/powershell/Language/Scripting/en-US/bad.psd1 new file mode 100644 index 0000000000..b5e653ec66 --- /dev/null +++ b/test/powershell/Language/Scripting/en-US/bad.psd1 @@ -0,0 +1,7 @@ +if($a -eq 'en-US') +{ + ConvertFrom-StringData @' + string1=string1 from foo in en-US + string2=string2 from foo in en-US +'@ +} \ No newline at end of file diff --git a/test/powershell/Language/Scripting/en-US/foo.psd1 b/test/powershell/Language/Scripting/en-US/foo.psd1 new file mode 100644 index 0000000000..6a82b0d1cb --- /dev/null +++ b/test/powershell/Language/Scripting/en-US/foo.psd1 @@ -0,0 +1,4 @@ +ConvertFrom-StringData @' +string1=string1 from foo in en-US +string2=string2 from foo in en-US +'@ \ No newline at end of file diff --git a/test/powershell/Language/Scripting/en-US/if.psd1 b/test/powershell/Language/Scripting/en-US/if.psd1 new file mode 100644 index 0000000000..1f139ae0e6 --- /dev/null +++ b/test/powershell/Language/Scripting/en-US/if.psd1 @@ -0,0 +1,7 @@ +if($psculture -eq 'en-US') +{ + ConvertFrom-StringData @' + string1=string1 for en-US in if + string2=string2 for en-US in if +'@ +} \ No newline at end of file diff --git a/test/powershell/Language/Scripting/en-US/scriptHelp1.xml b/test/powershell/Language/Scripting/en-US/scriptHelp1.xml new file mode 100644 index 0000000000..050d2d6fe0 --- /dev/null +++ b/test/powershell/Language/Scripting/en-US/scriptHelp1.xml @@ -0,0 +1,28 @@ + + + + + + + + helpFunc5 + + + A useless function, really. + + + + + + + + helpFunc6 + + + Useless. Really, trust me on this one. + + + + + + diff --git a/test/powershell/Language/Scripting/fr-FR/I18n.Tests.psd1 b/test/powershell/Language/Scripting/fr-FR/I18n.Tests.psd1 new file mode 100644 index 0000000000..02c8a35512 --- /dev/null +++ b/test/powershell/Language/Scripting/fr-FR/I18n.Tests.psd1 @@ -0,0 +1,4 @@ +ConvertFrom-StringData @' +string1=string1 for fr-FR +string2=string2 for fr-FR +'@ \ No newline at end of file diff --git a/test/powershell/Language/Scripting/fr-FR/foo.psd1 b/test/powershell/Language/Scripting/fr-FR/foo.psd1 new file mode 100644 index 0000000000..ba1c90d3e6 --- /dev/null +++ b/test/powershell/Language/Scripting/fr-FR/foo.psd1 @@ -0,0 +1,4 @@ +ConvertFrom-StringData @' +string1=string1 from foo in fr-FR +string2=string2 from foo in fr-FR +'@ \ No newline at end of file diff --git a/test/powershell/Language/Scripting/newbase/en-US/I18n.Tests.psd1 b/test/powershell/Language/Scripting/newbase/en-US/I18n.Tests.psd1 new file mode 100644 index 0000000000..39611f8a0d --- /dev/null +++ b/test/powershell/Language/Scripting/newbase/en-US/I18n.Tests.psd1 @@ -0,0 +1,4 @@ +ConvertFrom-StringData @' +string1=string1 for en-US under newbase +string2=string2 for en-US under newbase +'@ \ No newline at end of file diff --git a/test/powershell/Language/Scripting/newbase/en-US/foo.psd1 b/test/powershell/Language/Scripting/newbase/en-US/foo.psd1 new file mode 100644 index 0000000000..c3ee32d9d9 --- /dev/null +++ b/test/powershell/Language/Scripting/newbase/en-US/foo.psd1 @@ -0,0 +1,4 @@ +ConvertFrom-StringData @' +string1=string1 for en-US from foo under newbase +string2=string2 for en-US from foo under newbase +'@ \ No newline at end of file diff --git a/test/powershell/Language/Scripting/newbase/en-US/scriptHelp1.xml b/test/powershell/Language/Scripting/newbase/en-US/scriptHelp1.xml new file mode 100644 index 0000000000..19bc119f6d --- /dev/null +++ b/test/powershell/Language/Scripting/newbase/en-US/scriptHelp1.xml @@ -0,0 +1,28 @@ + + + + + + + + helpFunc5 + + + A useless function in newbase, really. + + + + + + + + helpFunc6 + + + Useless in newbase. Really, trust me on this one. + + + + + + diff --git a/test/powershell/Language/Scripting/newbase/fr-FR/I18n.Tests.psd1 b/test/powershell/Language/Scripting/newbase/fr-FR/I18n.Tests.psd1 new file mode 100644 index 0000000000..2c4387d2e5 --- /dev/null +++ b/test/powershell/Language/Scripting/newbase/fr-FR/I18n.Tests.psd1 @@ -0,0 +1,4 @@ +ConvertFrom-StringData @' +string1=string1 for fr-FR under newbase +string2=string2 for fr-FR under newbase +'@ \ No newline at end of file diff --git a/test/powershell/Language/Scripting/newbase/fr-FR/foo.psd1 b/test/powershell/Language/Scripting/newbase/fr-FR/foo.psd1 new file mode 100644 index 0000000000..2ddf5a0775 --- /dev/null +++ b/test/powershell/Language/Scripting/newbase/fr-FR/foo.psd1 @@ -0,0 +1,4 @@ +ConvertFrom-StringData @' +string1=string1 for fr-FR from foo under newbase +string2=string2 for fr-FR from foo under newbase +'@ \ No newline at end of file