"Fossies" - the Fresh Open Source Software Archive

Member "PowerShell-7.2.6/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1" (11 Aug 2022, 12483 Bytes) of package /linux/misc/PowerShell-7.2.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Microsoft PowerShell source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

A hint: This file contains one or more very long lines, so maybe it is better readable using the pure text view mode that shows the contents as wrapped lines within the browser window.


    1 # Copyright (c) Microsoft Corporation.
    2 # Licensed under the MIT License.
    3 
    4 Describe "Add-Type" -Tags "CI" {
    5     BeforeAll {
    6         $guid = [Guid]::NewGuid().ToString().Replace("-","")
    7 
    8         $CSharpCode1 = @"
    9         namespace Test.AddType
   10         {
   11             public class CSharpTest1$guid
   12             {
   13                 public static int Add1(int a, int b)
   14                 {
   15                     return (a + b);
   16                 }
   17             }
   18         }
   19 "@
   20         $CSharpCode2 = @"
   21         namespace Test.AddType
   22         {
   23             public class CSharpTest2$guid
   24             {
   25                 public static int Add2(int a, int b)
   26                 {
   27                     return (a + b);
   28                 }
   29             }
   30         }
   31 "@
   32         $CSharpFile1 = Join-Path -Path $TestDrive -ChildPath "CSharpFile1.cs"
   33         $CSharpFile2 = Join-Path -Path $TestDrive -ChildPath "CSharpFile2.cs"
   34 
   35         Set-Content -Path $CSharpFile1 -Value $CSharpCode1 -Force
   36         Set-Content -Path $CSharpFile2 -Value $CSharpCode2 -Force
   37 
   38         $codeWarning = @"
   39         namespace Test.AddType
   40         {
   41             public class CSharpTestWarn$guid
   42             {
   43                 public static int Add2(int a, int b)
   44                 {
   45                     return (a + b);
   46                 }
   47             }
   48         }
   49         #warning Test warning line
   50 "@
   51     }
   52 
   53     It "Public 'Language' enumeration contains all members" {
   54         [Enum]::GetNames("Microsoft.PowerShell.Commands.Language") -join "," | Should -BeExactly "CSharp"
   55     }
   56 
   57     It "Should not throw given a simple C# class definition" {
   58         # Also we check that '-Language CSharp' is by default.
   59         # In subsequent launches from the same session
   60         # the test will be passed without real compile - it will return an assembly previously compiled.
   61         { Add-Type -TypeDefinition "public static class CSharpfooType { }" } | Should -Not -Throw
   62         [CSharpfooType].Name | Should -BeExactly "CSharpfooType"
   63     }
   64 
   65     It "Can use System.Management.Automation.CmdletAttribute" {
   66         $code = @"
   67 using System.Management.Automation;
   68 [System.Management.Automation.Cmdlet("Get", "Thing$guid", ConfirmImpact = System.Management.Automation.ConfirmImpact.High, SupportsPaging = true)]
   69 public class SMAAttributeTest$guid : PSCmdlet
   70 {
   71     protected override void EndProcessing()
   72 
   73     {
   74         WriteObject("$guid");
   75     }
   76 }
   77 "@
   78         $cls = Add-Type -TypeDefinition $code -PassThru | Select-Object -First 1
   79         $testModule = Import-Module $cls.Assembly -PassThru
   80 
   81         Invoke-Expression -Command "Get-Thing$guid" | Should -BeExactly $guid
   82 
   83         Remove-Module $testModule -ErrorAction SilentlyContinue -Force
   84     }
   85 
   86     It "Can load TPA assembly System.Runtime.Serialization.Primitives.dll" {
   87         $returnedTypes = Add-Type -AssemblyName 'System.Runtime.Serialization.Primitives' -PassThru
   88         $returnedTypes.Count | Should -BeGreaterThan 0
   89         ($returnedTypes[0].Assembly.FullName -Split ",")[0]  | Should -BeExactly 'System.Runtime.Serialization.Primitives'
   90     }
   91 
   92     It "Can compile <sourceLanguage> files" -TestCases @(
   93         @{
   94             type1 = "[Test.AddType.CSharpTest1$guid]"
   95             type2 = "[Test.AddType.CSharpTest2$guid]"
   96             file1 = $CSharpFile1
   97             file2 = $CSharpFile2
   98             sourceLanguage = "CSharp"
   99         }
  100     ) {
  101         param($type1, $type2, $file1, $file2, $sourceLanguage)
  102 
  103         # The types shouldn't exist before compile the test code.
  104         $type1 -as [type] | Should -BeNullOrEmpty
  105         $type2 -as [type] | Should -BeNullOrEmpty
  106 
  107         $returnedTypes = Add-Type -Path $file1,$file2 -PassThru
  108 
  109         $type1 = Invoke-Expression -Command $type1
  110         $type2 = Invoke-Expression -Command $type2
  111 
  112         # We can compile, load and use new code.
  113         $type1::Add1(1, 2) | Should -Be 3
  114         $type2::Add2(3, 4) | Should -Be 7
  115 
  116         # Return the same assembly if source code has not been changed.
  117         # Also check that '-LiteralPath' works.
  118         $returnedTypes2 = Add-Type -LiteralPath $file1,$file2 -PassThru
  119         $returnedTypes[0].Assembly.FullName | Should -BeExactly $returnedTypes2[0].Assembly.FullName
  120     }
  121 
  122     It "Can compile <sourceLanguage> with MemberDefinition" -TestCases @(
  123         @{
  124             sourceCode = "public static string TestString() { return UTF8Encoding.UTF8.ToString();}"
  125             sourceType = "TestCSharpType1"
  126             sourceNS = "TestCSharpNS"
  127             sourceUsingNS = "System.Text"
  128             sourceRunType = "TestCSharpNS.TestCSharpType1"
  129             sourceDefaultNSRunType = "Microsoft.PowerShell.Commands.AddType.AutoGeneratedTypes.TestCSharpType1"
  130             expectedResult = "System.Text.UTF8Encoding+UTF8EncodingSealed"
  131             sourceLanguage = "CSharp"
  132         }
  133     ) {
  134         param($sourceCode, $sourceType, $sourceNS, $sourceUsingNS, $sourceRunType, $sourceDefaultNSRunType, $expectedResult, $sourceLanguage)
  135 
  136         # Add-Type show parse and compile errors and then finish with an terminationg error.
  137         # Catch non-termination information error.
  138         { Add-Type -MemberDefinition $sourceCode -Name $sourceType -Namespace $sourceNS -Language $sourceLanguage -ErrorAction Stop } | Should -Throw -ErrorId "SOURCE_CODE_ERROR,Microsoft.PowerShell.Commands.AddTypeCommand"
  139         # Catch final terminationg error.
  140         { Add-Type -MemberDefinition $sourceCode -Name $sourceType -Namespace $sourceNS -Language $sourceLanguage -ErrorAction SilentlyContinue } | Should -Throw -ErrorId "COMPILER_ERRORS,Microsoft.PowerShell.Commands.AddTypeCommand"
  141 
  142         $returnedTypes = Add-Type -MemberDefinition $sourceCode -Name $sourceType -UsingNamespace $sourceUsingNS -Namespace $sourceNS -Language $sourceLanguage -PassThru
  143         ([type]$sourceRunType)::TestString() | Should -BeExactly $expectedResult
  144 
  145         # Return the same assembly if source code has not been changed.
  146         $returnedTypes2 = Add-Type -MemberDefinition $sourceCode -Name $sourceType -UsingNamespace $sourceUsingNS -Namespace $sourceNS -Language $sourceLanguage -PassThru
  147         $returnedTypes[0].Assembly.FullName | Should -BeExactly $returnedTypes2[0].Assembly.FullName
  148 
  149         # With default namespace.
  150         Add-Type -MemberDefinition $sourceCode -Name $sourceType -UsingNamespace $sourceUsingNS -Language $sourceLanguage
  151         ([type]$sourceDefaultNSRunType)::TestString() | Should -BeExactly $expectedResult
  152     }
  153 
  154     It "Can compile without loading" {
  155 
  156         ## The assembly files cannot be removed once they are loaded, unless the current PowerShell session exits.
  157         ## If we use $TestDrive here, then Pester will try to remove them afterward and result in errors.
  158         if ($IsWindows) {
  159             $TempPath = [System.IO.Path]::GetTempFileName()
  160         }
  161         else {
  162             $TempPath = (Join-Path $env:HOME $([System.IO.Path]::GetRandomFileName()))
  163         }
  164 
  165         if (Test-Path $TempPath) { Remove-Item -Path $TempPath -Force -Recurse }
  166         New-Item -Path $TempPath -ItemType Directory -Force > $null
  167 
  168         $outFile = Join-Path -Path $TempPath -ChildPath "assembly$guid.dll"
  169         $outFile2 = Join-Path -Path $TempPath -ChildPath "assembly2$guid.dll"
  170 
  171         $code = @"
  172 using System.Management.Automation;
  173 [System.Management.Automation.Cmdlet("Get", "CompileThing$guid", ConfirmImpact = System.Management.Automation.ConfirmImpact.High, SupportsPaging = true)]
  174 public class AttributeTest$guid : PSCmdlet
  175 {
  176     protected override void EndProcessing()
  177 
  178     {
  179         WriteObject("$guid");
  180     }
  181 }
  182 "@
  183 
  184         $cmdlet = "Get-CompileThing$guid"
  185 
  186         Add-Type -TypeDefinition $code -OutputAssembly $outFile | Should -BeNullOrEmpty
  187         # Without -PassThru we don't load output assembly
  188         { [type]"System.Management.Automation.AttributeTest$guid" } | Should -Throw
  189 
  190         $outFile | Should -Exist
  191         $types = Add-Type -TypeDefinition $code -OutputAssembly $outFile2 -PassThru
  192         $types[0].Name | Should -BeExactly "AttributeTest$guid"
  193         $outFile2 | Should -Exist
  194 
  195         { Invoke-Expression -Command $cmdlet } | Should -Throw
  196 
  197         $testModule = Import-Module -Name $outFile -PassThru
  198         & $cmdlet | Should -BeExactly $guid
  199 
  200         Remove-Module $testModule -Force
  201     }
  202 
  203     It "Can report C# parse and compile errors" {
  204         # Add-Type show parse and compile errors and then finish with an terminationg error.
  205         # We test only for '-MemberDefinition' because '-Path' uses the same code path.
  206         # In the tests the error is that 'using System.Text;' is missing.
  207         #
  208         # Catch non-termination information error.
  209         { Add-Type -MemberDefinition "public static string TestString() { return UTF8Encoding.UTF8.ToString();}" -Name "TestType1" -Namespace "TestNS" -ErrorAction Stop } | Should -Throw -ErrorId "SOURCE_CODE_ERROR,Microsoft.PowerShell.Commands.AddTypeCommand"
  210         # Catch final terminationg error.
  211         { Add-Type -MemberDefinition "public static string TestString() { return UTF8Encoding.UTF8.ToString();}" -Name "TestType1" -Namespace "TestNS" -ErrorAction SilentlyContinue } | Should -Throw -ErrorId "COMPILER_ERRORS,Microsoft.PowerShell.Commands.AddTypeCommand"
  212 
  213         # Catch non-termination information error for CompilerOptions.
  214         { Add-Type -CompilerOptions "/platform:anycpuERROR" -Language CSharp -MemberDefinition "public static string TestString() { return ""}" -Name "TestType1" -Namespace "TestNS" -ErrorAction Stop } | Should -Throw -ErrorId "SOURCE_CODE_ERROR,Microsoft.PowerShell.Commands.AddTypeCommand"
  215     }
  216 
  217     It "Throw if the type already exists" {
  218         Add-Type -TypeDefinition "public class Foo$guid {}"
  219 
  220         # The cmdlet writes TYPE_ALREADY_EXISTS for every duplicated type and then terminates with COMPILER_ERRORS.
  221         # So here we check 2 errors.
  222         { Add-Type -TypeDefinition "public class Foo$guid { public int Bar {get {return 42;} }" -ErrorAction SilentlyContinue } | Should -Throw -ErrorId "COMPILER_ERRORS,Microsoft.PowerShell.Commands.AddTypeCommand"
  223         $error[1].FullyQualifiedErrorId | Should -BeExactly "TYPE_ALREADY_EXISTS,Microsoft.PowerShell.Commands.AddTypeCommand"
  224     }
  225 
  226     It "OutputType parameter requires that the OutputAssembly parameter be specified." {
  227         $code = "public static string TestString() {}"
  228         { Add-Type -TypeDefinition $code -OutputType Library } | Should -Throw -ErrorId "OUTPUTTYPE_REQUIRES_ASSEMBLY,Microsoft.PowerShell.Commands.AddTypeCommand"
  229     }
  230 
  231     It "By default Add-Type treats 'warnings as errors'." {
  232         { Add-Type -TypeDefinition $codeWarning -WarningAction SilentlyContinue 2> $null } | Should -Throw -ErrorId "COMPILER_ERRORS,Microsoft.PowerShell.Commands.AddTypeCommand"
  233     }
  234 
  235     It "IgnoreWarnings suppress 'warnings as errors'." {
  236         Add-Type -TypeDefinition $codeWarning -IgnoreWarnings -WarningVariable warnVar -WarningAction SilentlyContinue
  237         $warnVar.Count | Should -Be 1
  238     }
  239 
  240     It "Throw terminating error when file with non-supported extension is passed to -Path" {
  241         $VBFile = Join-Path -Path $TestDrive -ChildPath "VBFile.vb"
  242         New-Item -Path $VBFile -ItemType File -Force > $null
  243         { Add-Type -Path $VBFile } | Should -Throw -ErrorId "EXTENSION_NOT_SUPPORTED,Microsoft.PowerShell.Commands.AddTypeCommand"
  244     }
  245 
  246     It "Throw terminating error when specified assembly is not found: <assemblyName>" -TestCases @(
  247         @{ assemblyName = "does_not_exist_with_wildcard_*"; errorid = "ErrorLoadingAssembly,Microsoft.PowerShell.Commands.AddTypeCommand"},
  248         @{ assemblyName = "../does_not_exist_with_wildcard_*"; errorid = "ErrorLoadingAssembly,Microsoft.PowerShell.Commands.AddTypeCommand"},
  249         @{ assemblyName = "${PSHOME}/does_not_exist"; errorid = "System.IO.FileNotFoundException,Microsoft.PowerShell.Commands.AddTypeCommand"},
  250         @{ assemblyName = "does_not_exist"; errorid = "PathNotFound,Microsoft.PowerShell.Commands.AddTypeCommand"}
  251     ) {
  252         param ($assemblyName, $errorid)
  253         { Add-Type -AssemblyName $assemblyName } | Should -Throw -ErrorId $errorid
  254     }
  255 
  256     It "Throw terminating error when '-OutputType' is '<outputType>'" -TestCases @(
  257         @{ outputType = 'ConsoleApplication' }
  258         @{ outputType = 'WindowsApplication' }
  259     ) {
  260         param($outputType)
  261         { Add-Type -TypeDefinition "Hello" -OutputType $outputType } | Should -Throw -ErrorId 'AssemblyTypeNotSupported,Microsoft.PowerShell.Commands.AddTypeCommand'
  262     }
  263 }