1
+ using System ;
2
+ using System . IO ;
3
+ using System . Reflection ;
4
+ using NSubstitute ;
5
+ using Xunit ;
6
+
7
+ namespace AWS . Lambda . Powertools . Common . Tests ;
8
+
9
+ [ Collection ( "Sequential" ) ]
10
+ public class SystemWrapperTests : IDisposable
11
+ {
12
+ private readonly IPowertoolsEnvironment _mockEnvironment ;
13
+ private readonly StringWriter _testWriter ;
14
+ private readonly FieldInfo _outputResetPerformedField ;
15
+
16
+
17
+ public SystemWrapperTests ( )
18
+ {
19
+ _mockEnvironment = Substitute . For < IPowertoolsEnvironment > ( ) ;
20
+ _testWriter = new StringWriter ( ) ;
21
+
22
+ // Get access to private field for testing
23
+ _outputResetPerformedField = typeof ( SystemWrapper ) . GetField ( "_outputResetPerformed" ,
24
+ BindingFlags . NonPublic | BindingFlags . Static ) ;
25
+
26
+ // Reset static state between tests
27
+ SystemWrapper . ResetTestMode ( ) ;
28
+ _outputResetPerformedField . SetValue ( null , false ) ;
29
+ }
30
+
31
+ [ Fact ]
32
+ public void Log_InProductionMode_ResetsOutputOnce ( )
33
+ {
34
+ // Arrange
35
+ var wrapper = new SystemWrapper ( _mockEnvironment ) ;
36
+ var message1 = "First message" ;
37
+ var message2 = "Second message" ;
38
+ _outputResetPerformedField . SetValue ( null , false ) ;
39
+
40
+ // Act
41
+ wrapper . Log ( message1 ) ;
42
+ bool afterFirstLog = ( bool ) _outputResetPerformedField . GetValue ( null ) ;
43
+ wrapper . Log ( message2 ) ;
44
+ bool afterSecondLog = ( bool ) _outputResetPerformedField . GetValue ( null ) ;
45
+
46
+ // Assert
47
+ Assert . True ( afterFirstLog , "Flag should be set after first log" ) ;
48
+ Assert . True ( afterSecondLog , "Flag should remain set after second log" ) ;
49
+ }
50
+
51
+ [ Fact ]
52
+ public void LogLine_InProductionMode_ResetsOutputOnce ( )
53
+ {
54
+ // Arrange
55
+ var wrapper = new SystemWrapper ( _mockEnvironment ) ;
56
+ var message1 = "First line" ;
57
+ var message2 = "Second line" ;
58
+ _outputResetPerformedField . SetValue ( null , false ) ;
59
+
60
+ // Act
61
+ wrapper . LogLine ( message1 ) ;
62
+ bool afterFirstLog = ( bool ) _outputResetPerformedField . GetValue ( null ) ;
63
+ wrapper . LogLine ( message2 ) ;
64
+ bool afterSecondLog = ( bool ) _outputResetPerformedField . GetValue ( null ) ;
65
+
66
+ // Assert
67
+ Assert . True ( afterFirstLog , "Flag should be set after first LogLine" ) ;
68
+ Assert . True ( afterSecondLog , "Flag should remain set after second LogLine" ) ;
69
+ }
70
+
71
+ [ Fact ]
72
+ public void ClearOutputResetFlag_ResetsFlag_AllowsSubsequentReset ( )
73
+ {
74
+ // Arrange
75
+ var wrapper = new SystemWrapper ( _mockEnvironment ) ;
76
+ _outputResetPerformedField . SetValue ( null , false ) ;
77
+
78
+ // Act
79
+ wrapper . Log ( "First message" ) ; // This should cause a reset
80
+ bool afterFirstLog = ( bool ) _outputResetPerformedField . GetValue ( null ) ;
81
+
82
+ SystemWrapper . ClearOutputResetFlag ( ) ;
83
+ bool afterClear = ( bool ) _outputResetPerformedField . GetValue ( null ) ;
84
+
85
+ wrapper . Log ( "After clear" ) ; // This should cause another reset
86
+ bool afterSecondLog = ( bool ) _outputResetPerformedField . GetValue ( null ) ;
87
+
88
+ // Assert
89
+ Assert . True ( afterFirstLog , "Flag should be set after first log" ) ;
90
+ Assert . False ( afterClear , "Flag should be cleared after ClearOutputResetFlag" ) ;
91
+ Assert . True ( afterSecondLog , "Flag should be set again after second log" ) ;
92
+ }
93
+
94
+ [ Fact ]
95
+ public void Log_InTestMode_WritesToTestOutput ( )
96
+ {
97
+ // Arrange
98
+ var wrapper = new SystemWrapper ( _mockEnvironment ) ;
99
+ SystemWrapper . SetOut ( _testWriter ) ;
100
+ var message = "Test message" ;
101
+
102
+ // Act
103
+ wrapper . Log ( message ) ;
104
+
105
+ // Assert
106
+ Assert . Equal ( message , _testWriter . ToString ( ) ) ;
107
+ }
108
+
109
+ [ Fact ]
110
+ public void LogLine_InTestMode_WritesToTestOutput ( )
111
+ {
112
+ // Arrange
113
+ var wrapper = new SystemWrapper ( _mockEnvironment ) ;
114
+ SystemWrapper . SetOut ( _testWriter ) ;
115
+ var message = "Test line" ;
116
+
117
+ // Act
118
+ wrapper . LogLine ( message ) ;
119
+
120
+ // Assert
121
+ Assert . Equal ( message + Environment . NewLine , _testWriter . ToString ( ) ) ;
122
+ }
123
+
124
+ [ Fact ]
125
+ public void ResetTestMode_ResetsTestState ( )
126
+ {
127
+ // Arrange
128
+ var wrapper = new SystemWrapper ( _mockEnvironment ) ;
129
+ SystemWrapper . SetOut ( _testWriter ) ;
130
+ var message = "This should go to console" ;
131
+
132
+ // Act
133
+ SystemWrapper . ResetTestMode ( ) ;
134
+
135
+ // Can't directly test that this goes to console, but we can verify
136
+ // it doesn't go to the test writer
137
+ wrapper . Log ( message ) ;
138
+
139
+ // Assert
140
+ Assert . Equal ( "" , _testWriter . ToString ( ) ) ;
141
+ }
142
+
143
+ [ Fact ]
144
+ public void SetOut_EnablesTestMode ( )
145
+ {
146
+ // Arrange
147
+ var wrapper = new SystemWrapper ( _mockEnvironment ) ;
148
+ var message = "Test output" ;
149
+
150
+ // Act
151
+ SystemWrapper . SetOut ( _testWriter ) ;
152
+ wrapper . Log ( message ) ;
153
+
154
+ // Assert
155
+ Assert . Equal ( message , _testWriter . ToString ( ) ) ;
156
+ }
157
+
158
+ [ Fact ]
159
+ public void Log_InTestMode_DoesNotCallResetConsoleOutput ( )
160
+ {
161
+ // Arrange
162
+ var wrapper = new SystemWrapper ( _mockEnvironment ) ;
163
+ SystemWrapper . SetOut ( _testWriter ) ;
164
+ var message1 = "First test message" ;
165
+ var message2 = "Second test message" ;
166
+
167
+ // Act
168
+ wrapper . Log ( message1 ) ;
169
+ wrapper . Log ( message2 ) ;
170
+
171
+ // Assert
172
+ Assert . Equal ( message1 + message2 , _testWriter . ToString ( ) ) ;
173
+ }
174
+
175
+ [ Fact ]
176
+ public void Log_AfterClearingFlag_ResetsOutputAgain ( )
177
+ {
178
+ // Arrange
179
+ var wrapper = new SystemWrapper ( _mockEnvironment ) ;
180
+ _outputResetPerformedField . SetValue ( null , false ) ;
181
+
182
+ // Act
183
+ wrapper . Log ( "First message" ) ; // Should reset output
184
+ bool afterFirstLog = ( bool ) _outputResetPerformedField . GetValue ( null ) ;
185
+
186
+ SystemWrapper . ClearOutputResetFlag ( ) ;
187
+ bool afterClear = ( bool ) _outputResetPerformedField . GetValue ( null ) ;
188
+
189
+ wrapper . Log ( "Second message" ) ; // Should reset again
190
+ bool afterSecondLog = ( bool ) _outputResetPerformedField . GetValue ( null ) ;
191
+
192
+ // Assert
193
+ Assert . True ( afterFirstLog , "Flag should be set after first log" ) ;
194
+ Assert . False ( afterClear , "Flag should be reset after clearing" ) ;
195
+ Assert . True ( afterSecondLog , "Flag should be set after second log" ) ;
196
+ }
197
+
198
+ public void Dispose ( )
199
+ {
200
+ _testWriter ? . Dispose ( ) ;
201
+ SystemWrapper . ResetTestMode ( ) ;
202
+ _outputResetPerformedField . SetValue ( null , false ) ;
203
+ }
204
+ }
0 commit comments