@@ -84,6 +84,171 @@ Describe "Trace-Command" -tags "CI" {
84
84
}
85
85
}
86
86
87
+ Context " MethodInvocation traces" {
88
+
89
+ BeforeAll {
90
+ $filePath = Join-Path $TestDrive ' testtracefile.txt'
91
+
92
+ class MyClass {
93
+ MyClass() {}
94
+ MyClass([int ]$arg ) {}
95
+
96
+ [void ]Method() { return }
97
+ [void ]Method([string ]$arg ) { return }
98
+ [void ]Method([int ]$arg ) { return }
99
+
100
+ [string ]ReturnMethod() { return " foo" }
101
+
102
+ static [void ]StaticMethod() { return }
103
+ static [void ]StaticMethod([string ]$arg ) { return }
104
+ }
105
+
106
+ # C# classes support more features than pwsh classes
107
+ Add-Type - TypeDefinition @'
108
+ namespace TraceCommandTests;
109
+
110
+ public sealed class OverloadTests
111
+ {
112
+ public int PropertySetter { get; set; }
113
+
114
+ public OverloadTests() {}
115
+ public OverloadTests(int value)
116
+ {
117
+ PropertySetter = value;
118
+ }
119
+
120
+ public void GenericMethod<T>()
121
+ {}
122
+
123
+ public T GenericMethodWithArg<T>(T obj) => obj;
124
+
125
+ public void MethodWithDefault(string arg1, int optional = 1)
126
+ {}
127
+
128
+ public void MethodWithOut(out int val)
129
+ {
130
+ val = 1;
131
+ }
132
+
133
+ public void MethodWithRef(ref int val)
134
+ {
135
+ val = 1;
136
+ }
137
+ }
138
+ '@
139
+ }
140
+
141
+ AfterEach {
142
+ Remove-Item $filePath - Force - ErrorAction SilentlyContinue
143
+ }
144
+
145
+ It " Traces instance method" {
146
+ $myClass = [MyClass ]::new()
147
+ Trace-Command - Name MethodInvocation - Expression {
148
+ $myClass.Method (1 )
149
+ } - FilePath $filePath
150
+ Get-Content $filePath | Should - BeLike " *Invoking method: void Method(int arg)"
151
+ }
152
+
153
+ It " Traces static method" {
154
+ Trace-Command - Name MethodInvocation - Expression {
155
+ [MyClass ]::StaticMethod(1 )
156
+ } - FilePath $filePath
157
+ Get-Content $filePath | Should - BeLike " *Invoking method: static void StaticMethod(string arg)"
158
+ }
159
+
160
+ It " Traces method with return type" {
161
+ $myClass = [MyClass ]::new()
162
+ Trace-Command - Name MethodInvocation - Expression {
163
+ $myClass.ReturnMethod ()
164
+ } - FilePath $filePath
165
+ Get-Content $filePath | Should - BeLike " *Invoking method: string ReturnMethod()"
166
+ }
167
+
168
+ It " Traces constructor" {
169
+ Trace-Command - Name MethodInvocation - Expression {
170
+ [TraceCommandTests.OverloadTests ]::new(" 1234" )
171
+ } - FilePath $filePath
172
+ Get-Content $filePath | Should - BeLike " *Invoking method: TraceCommandTests.OverloadTests new(int value)"
173
+ }
174
+
175
+ It " Traces Property setter invoked as a method" {
176
+ $obj = [TraceCommandTests.OverloadTests ]::new()
177
+ Trace-Command - Name MethodInvocation - Expression {
178
+ $obj.set_PropertySetter (1234 )
179
+ } - FilePath $filePath
180
+ Get-Content $filePath | Should - BeLike " *Invoking method: void set_PropertySetter(int value)"
181
+ }
182
+
183
+ It " Traces generic method" {
184
+ $obj = [TraceCommandTests.OverloadTests ]::new()
185
+ Trace-Command - Name MethodInvocation - Expression {
186
+ $obj.GenericMethod [int ]()
187
+ } - FilePath $filePath
188
+ Get-Content $filePath | Should - BeLike " *Invoking method: void GenericMethod`` [int`` ]()"
189
+ }
190
+
191
+ It " Traces generic method with argument" {
192
+ $obj = [TraceCommandTests.OverloadTests ]::new()
193
+ Trace-Command - Name MethodInvocation - Expression {
194
+ $obj.GenericMethodWithArg (" foo" )
195
+ } - FilePath $filePath
196
+ Get-Content $filePath | Should - BeLike " *Invoking method: string GenericMethodWithArg`` [string`` ](string obj)"
197
+ }
198
+
199
+ It " Traces .NET call with default value" {
200
+ $obj = [TraceCommandTests.OverloadTests ]::new()
201
+ Trace-Command - Name MethodInvocation - Expression {
202
+ $obj.MethodWithDefault (" foo" )
203
+ } - FilePath $filePath
204
+ Get-Content $filePath | Should - BeLike " *Invoking method: void MethodWithDefault(string arg1, int optional = 1)"
205
+ }
206
+
207
+ It " Traces method with ref argument" {
208
+ $obj = [TraceCommandTests.OverloadTests ]::new()
209
+ $v = 1
210
+
211
+ Trace-Command - Name MethodInvocation - Expression {
212
+ $obj.MethodWithRef ([ref ]$v )
213
+ } - FilePath $filePath
214
+ # [ref] goes through the binder so will trigger the first trace
215
+ Get-Content $filePath | Select-Object - Skip 1 | Should - BeLike " *Invoking method: void MethodWithRef(`` [ref`` ] int val)"
216
+ }
217
+
218
+ It " Traces method with out argument" {
219
+ $obj = [TraceCommandTests.OverloadTests ]::new()
220
+ $v = 1
221
+
222
+ Trace-Command - Name MethodInvocation - Expression {
223
+ $obj.MethodWithOut ([ref ]$v )
224
+ } - FilePath $filePath
225
+ # [ref] goes through the binder so will trigger the first trace
226
+ Get-Content $filePath | Select-Object - Skip 1 | Should - BeLike " *Invoking method: void MethodWithOut(`` [ref`` ] int val)"
227
+ }
228
+
229
+ It " Traces a binding error" {
230
+ Trace-Command - Name MethodInvocation - Expression {
231
+ # try/catch is used as error formatter will hit the trace as well
232
+ try {
233
+ [System.Runtime.InteropServices.Marshal ]::SizeOf([int ])
234
+ }
235
+ catch {
236
+ # Satisfy codefactor
237
+ $_ | Out-Null
238
+ }
239
+ } - FilePath $filePath
240
+ # type fqn is used, the wildcard avoids hardcoding that
241
+ Get-Content $filePath | Should - BeLike " *Invoking method: static int SizeOf`` [System.RuntimeType, *`` ](System.RuntimeType, * structure)"
242
+ }
243
+
244
+ It " Traces LINQ call" {
245
+ Trace-Command - Name MethodInvocation - Expression {
246
+ [System.Linq.Enumerable ]::Union([int []]@ (1 , 2 ), [int []]@ (3 , 4 ))
247
+ } - FilePath $filePath
248
+ Get-Content $filePath | Should - BeLike " *Invoking method: static System.Collections.Generic.IEnumerable`` [int`` ] Union`` [int`` ](System.Collections.Generic.IEnumerable`` [int`` ] first, System.Collections.Generic.IEnumerable`` [int`` ] second)"
249
+ }
250
+ }
251
+
87
252
Context " Trace-Command tests for code coverage" {
88
253
89
254
BeforeAll {
0 commit comments