-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathGenericMethods.Tests.ps1
253 lines (204 loc) · 10 KB
/
GenericMethods.Tests.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
$scriptRoot = Split-Path -Path $MyInvocation.MyCommand.Path
Import-Module -Name $scriptRoot\GenericMethods.psm1 -Force -ErrorAction Stop
Describe 'GenericMethods' {
$cSharp = @'
using System;
using System.Management.Automation;
using System.Collections.Generic;
public class TestClass
{
public string InstanceMethodNoParameters<T> ()
{
return typeof(T).FullName;
}
public static string StaticMethodNoParameters<T> ()
{
return typeof(T).FullName;
}
public static T GetDefaultValue<T> ()
{
return default(T);
}
public static string GenericTypeParameterTest<T> (List<T> parameter)
{
if (parameter == null) { throw new ArgumentNullException("parameter"); }
return parameter.GetType().FullName;
}
public static string GenericTypeParameterTest2<T> (List<string> parameter)
{
if (parameter == null) { throw new ArgumentNullException("parameter"); }
return parameter.GetType().FullName;
}
public static string GenericTypeParameterTest3<T> (List<List<T>> parameter)
{
if (parameter == null) { throw new ArgumentNullException("parameter"); }
return parameter.GetType().FullName;
}
public static string ArrayParameterTest<T>(T[] parameter)
{
if (parameter == null) { throw new ArgumentException("parameter"); }
return parameter.GetType().FullName;
}
public static string OutParameterTest<T>(out T parameter, out string sparam)
{
parameter = default(T);
sparam = "Out Value";
return "OutParameterTest";
}
public static string RefParameterTest<T>(ref T parameter, ref string sparam)
{
string originalValue = sparam;
parameter = default(T);
sparam = "Out Value";
return String.Format("RefParameterTest: '{0}'", originalValue);
}
public static string NullableRefTest<T>(ref int? parameter)
{
string message;
if (parameter.HasValue)
{
message = String.Format("NullableRefTest: OriginalValue '{0}'", parameter.Value);
}
else
{
message = "NullableRefTest: OriginalValue null";
}
parameter = 5;
return message;
}
public static string ParamsArgumentTest<T>(int required, params string[] values)
{
return string.Format("T: {0}, required: {1}, values: {2}", typeof(T).FullName, required, string.Join(" ", values));
}
}
'@
Add-Type -TypeDefinition $cSharp -ErrorAction Stop
if ($PSVersionTable.PSVersion.Major -ge 3)
{
$cSharp = @'
using System;
using System.Management.Automation;
using System.Collections.Generic;
public class TestClass2
{
public static string DefaultParameterTest<T> (string required, string optional = "Default value")
{
return string.Format("'{0}', '{1}'", required, optional);
}
}
'@
Add-Type -TypeDefinition $cSharp -ErrorAction Stop
}
Context 'A static method with no parameters' {
It 'Returns the generic type''s full name' {
Invoke-GenericMethod -Type TestClass -MethodName StaticMethodNoParameters -GenericType psobject |
Should Be ([psobject].FullName)
}
}
Context 'A method with a generic return type' {
It 'Returns the default value for Numeric types' {
Invoke-GenericMethod -Type TestClass -MethodName GetDefaultValue -GenericType int |
Should Be 0
}
It 'Returns the default value for Boolean types' {
Invoke-GenericMethod -Type TestClass -MethodName GetDefaultValue -GenericType bool |
Should Be $false
}
It 'Returns the default value for Reference types' {
Invoke-GenericMethod -Type TestClass -MethodName GetDefaultValue -GenericType System.IO.FileInfo |
Should Be $null
}
}
if ($PSVersionTable.PSVersion.Major -ge 3)
{
Context 'A method with optional parameters (default values)' {
It 'Returns the specified value' {
Invoke-GenericMethod -Type TestClass2 -MethodName DefaultParameterTest -GenericType string -ArgumentList 'Required Parameter', 'Optional Parameter' |
Should Be "'Required Parameter', 'Optional Parameter'"
}
It 'Returns the default value' {
Invoke-GenericMethod -Type TestClass2 -MethodName DefaultParameterTest -GenericType string -ArgumentList 'Required Parameter' |
Should Be "'Required Parameter', 'Default value'"
}
}
}
Context 'A method with parameters that are Generic types' {
It 'Resolves the runtime types correctly (Test 1: Generic parameter type based on method generic type)' {
Invoke-GenericMethod -Type TestClass -MethodName GenericTypeParameterTest -GenericType string -ArgumentList (,(New-Object System.Collections.Generic.List[string])) |
Should Match '^System\.Collections\.Generic\.List`1\[\[System\.String'
}
It 'Resolves the runtime types correctly (Test 2: Generic parameter type not based on method generic type)' {
Invoke-GenericMethod -Type TestClass -MethodName GenericTypeParameterTest2 -GenericType string -ArgumentList (,(New-Object System.Collections.Generic.List[string])) |
Should Match '^System\.Collections\.Generic\.List`1\[\[System\.String'
}
It 'Resolves the runtime types correctly (Test 3: Nested generic type)' {
Invoke-GenericMethod -Type TestClass -MethodName GenericTypeParameterTest3 -GenericType string -ArgumentList (,(New-Object System.Collections.Generic.List[System.Collections.Generic.List[string]])) |
Should Match '^System\.Collections\.Generic\.List`1\[\[System\.Collections\.Generic\.List`1\[\[System\.String'
}
}
Context 'A method with a parameter that is an array of the method''s generic type' {
It 'Resolves runtime types correctly' {
Invoke-GenericMethod -Type TestClass -MethodName ArrayParameterTest -GenericType string -ArgumentList (,(New-Object string[](4))) |
Should Be 'System.String[]'
}
}
Context 'A method with "out" parameters' {
It 'Assigns the default boolean value to the generic out parameter, and the value "Out Value" to the out string parameter.' {
$string = $null
$bool = $true
$result = Invoke-GenericMethod -Type TestClass -MethodName OutParameterTest -GenericType bool -ArgumentList ([ref]$bool, [ref]$string)
$result | Should Be 'OutParameterTest'
$string | Should Be 'Out Value'
$bool | Should Be $false
}
}
Context 'A method with "ref" parameters' {
It 'Assigns the default boolean value to the generic ref parameter, and the value "Out Value" to the ref string parameter.' {
$string = 'Original Value'
$bool = $true
$result = Invoke-GenericMethod -Type TestClass -MethodName RefParameterTest -GenericType bool -ArgumentList ([ref]$bool, [ref]$string)
$result | Should Be "RefParameterTest: 'Original Value'"
$string | Should Be 'Out Value'
$bool | Should Be $false
}
}
Context 'A method with Nullable Ref parameters' {
It 'Correctly resolves the runtime types, the original null value, and assigns a value of 5 to the reference parameter' {
$ref = $null
$result = Invoke-GenericMethod -Type TestClass -MethodName NullableRefTest -GenericType string -ArgumentList @([ref] $ref)
$result | Should Be 'NullableRefTest: OriginalValue null'
$ref | Should Be 5
}
It 'Correctly resolves the runtime types, the original non-null value, and assigns a value of 5 to the reference parameter' {
$ref = 10
$result = Invoke-GenericMethod -Type TestClass -MethodName NullableRefTest -GenericType string -ArgumentList @([ref] $ref)
$result | Should Be "NullableRefTest: OriginalValue '10'"
$ref | Should Be 5
}
It 'Performs type conversion when an exact method signature is not found' {
$ref = 10L
$result = Invoke-GenericMethod -Type TestClass -MethodName NullableRefTest -GenericType string -ArgumentList @([ref] $ref)
$result | Should Be "NullableRefTest: OriginalValue '10'"
$ref | Should Be 5
}
}
Context 'An instance method' {
It 'Invokes the instance method using -InputObject' {
$object = New-Object TestClass
Invoke-GenericMethod -InputObject $object -MethodName InstanceMethodNoParameters -GenericType psobject |
Should Be ([psobject].FullName)
}
It 'Invokes the instance method using pipeline input' {
$object = New-Object TestClass
$object | Invoke-GenericMethod -MethodName InstanceMethodNoParameters -GenericType psobject |
Should Be ([psobject].FullName)
}
}
Context 'Method with params argument' {
$arguments = 10, 'One', 'Two', 'Three', 'Four', 'Five'
It 'Invokes the method with a params argument' {
$result = Invoke-GenericMethod -Type TestClass -MethodName ParamsArgumentTest -GenericType object -ArgumentList $arguments -ErrorAction Stop
$result | Should Be 'T: System.Object, required: 10, values: One Two Three Four Five'
}
}
}