10
10
11
11
package org .junit .jupiter .engine .extension ;
12
12
13
+ import static com .google .common .jimfs .Configuration .unix ;
14
+ import static java .lang .annotation .ElementType .METHOD ;
15
+ import static java .lang .annotation .RetentionPolicy .RUNTIME ;
13
16
import static java .nio .file .Files .createDirectory ;
14
17
import static java .nio .file .Files .createFile ;
15
18
import static java .nio .file .Files .createSymbolicLink ;
18
21
import static java .nio .file .Files .deleteIfExists ;
19
22
import static org .assertj .core .api .Assertions .assertThat ;
20
23
import static org .assertj .core .api .Assertions .assertThatExceptionOfType ;
24
+ import static org .junit .jupiter .api .condition .OS .WINDOWS ;
21
25
import static org .junit .jupiter .api .io .CleanupMode .ALWAYS ;
22
26
import static org .junit .jupiter .api .io .CleanupMode .DEFAULT ;
23
27
import static org .junit .jupiter .api .io .CleanupMode .NEVER ;
24
28
import static org .junit .jupiter .api .io .CleanupMode .ON_SUCCESS ;
25
29
import static org .mockito .ArgumentMatchers .any ;
26
30
import static org .mockito .Mockito .mock ;
31
+ import static org .mockito .Mockito .reset ;
27
32
import static org .mockito .Mockito .spy ;
28
33
import static org .mockito .Mockito .verify ;
29
34
import static org .mockito .Mockito .when ;
30
35
36
+ import java .io .File ;
31
37
import java .io .IOException ;
38
+ import java .lang .annotation .Retention ;
39
+ import java .lang .annotation .Target ;
40
+ import java .nio .file .FileSystem ;
32
41
import java .nio .file .Path ;
33
42
import java .util .Optional ;
34
43
44
+ import com .google .common .jimfs .Jimfs ;
45
+
35
46
import org .assertj .core .api .ThrowableAssert .ThrowingCallable ;
36
47
import org .junit .jupiter .api .AfterEach ;
37
48
import org .junit .jupiter .api .BeforeEach ;
38
49
import org .junit .jupiter .api .DisplayName ;
39
50
import org .junit .jupiter .api .Nested ;
40
51
import org .junit .jupiter .api .Test ;
41
52
import org .junit .jupiter .api .condition .DisabledOnOs ;
42
- import org .junit .jupiter .api .condition .OS ;
43
53
import org .junit .jupiter .api .extension .AnnotatedElementContext ;
44
54
import org .junit .jupiter .api .extension .ExtensionConfigurationException ;
45
55
import org .junit .jupiter .api .extension .ExtensionContext ;
49
59
import org .junit .jupiter .api .io .TempDirFactory ;
50
60
import org .junit .jupiter .engine .AbstractJupiterTestEngineTests ;
51
61
import org .junit .jupiter .engine .execution .NamespaceAwareStore ;
62
+ import org .junit .jupiter .params .ParameterizedTest ;
63
+ import org .junit .jupiter .params .provider .ValueSource ;
52
64
import org .junit .platform .commons .PreconditionViolationException ;
53
65
import org .junit .platform .engine .support .store .NamespacedHierarchicalStore ;
54
66
@@ -65,6 +77,12 @@ class CloseablePathTests extends AbstractJupiterTestEngineTests {
65
77
66
78
private TempDirectory .CloseablePath closeablePath ;
67
79
80
+ @ Target (METHOD )
81
+ @ Retention (RUNTIME )
82
+ @ ValueSource (classes = { File .class , Path .class })
83
+ private @interface ElementTypeSource {
84
+ }
85
+
68
86
@ BeforeEach
69
87
void setUpExtensionContext () {
70
88
var store = new NamespaceAwareStore (new NamespacedHierarchicalStore <>(null ), Namespace .GLOBAL );
@@ -95,72 +113,107 @@ void cleanupRoot() throws IOException {
95
113
delete (root );
96
114
}
97
115
98
- @ Test
99
116
@ DisplayName ("succeeds if the factory returns a directory" )
100
- void factoryReturnsDirectory () throws Exception {
101
- TempDirFactory factory = spy (new Factory (createDirectory (root .resolve ("directory" ))));
117
+ @ ParameterizedTest
118
+ @ ElementTypeSource
119
+ void factoryReturnsDirectoryDynamic (Class <?> elementType ) throws IOException {
120
+ TempDirFactory factory = (elementContext , extensionContext ) -> createDirectory (root .resolve ("directory" ));
102
121
103
- closeablePath = TempDirectory .createTempDir (factory , DEFAULT , elementContext , extensionContext );
122
+ closeablePath = TempDirectory .createTempDir (factory , DEFAULT , elementType , elementContext ,
123
+ extensionContext );
104
124
assertThat (closeablePath .get ()).isDirectory ();
105
125
106
126
delete (closeablePath .get ());
107
127
}
108
128
109
- @ Test
110
129
@ DisplayName ("succeeds if the factory returns a symbolic link to a directory" )
111
- @ DisabledOnOs (OS .WINDOWS )
112
- void factoryReturnsSymbolicLinkToDirectory () throws Exception {
130
+ @ ParameterizedTest
131
+ @ ElementTypeSource
132
+ @ DisabledOnOs (WINDOWS )
133
+ void factoryReturnsSymbolicLinkToDirectory (Class <?> elementType ) throws IOException {
113
134
Path directory = createDirectory (root .resolve ("directory" ));
114
- TempDirFactory factory = spy (new Factory (createSymbolicLink (root .resolve ("symbolicLink" ), directory )));
135
+ TempDirFactory factory = (elementContext ,
136
+ extensionContext ) -> createSymbolicLink (root .resolve ("symbolicLink" ), directory );
115
137
116
- closeablePath = TempDirectory .createTempDir (factory , DEFAULT , elementContext , extensionContext );
138
+ closeablePath = TempDirectory .createTempDir (factory , DEFAULT , elementType , elementContext ,
139
+ extensionContext );
117
140
assertThat (closeablePath .get ()).isDirectory ();
118
141
119
142
delete (closeablePath .get ());
120
143
delete (directory );
121
144
}
122
145
146
+ @ DisplayName ("succeeds if the factory returns a directory on a non-default file system for a Path annotated element" )
123
147
@ Test
148
+ void factoryReturnsDirectoryOnNonDefaultFileSystemWithPath () throws IOException {
149
+ TempDirFactory factory = spy (new JimfsFactory ());
150
+
151
+ closeablePath = TempDirectory .createTempDir (factory , DEFAULT , Path .class , elementContext , extensionContext );
152
+ assertThat (closeablePath .get ()).isDirectory ();
153
+
154
+ delete (closeablePath .get ());
155
+ }
156
+
124
157
@ DisplayName ("fails if the factory returns null" )
125
- void factoryReturnsNull () throws IOException {
158
+ @ ParameterizedTest
159
+ @ ElementTypeSource
160
+ void factoryReturnsNull (Class <?> elementType ) throws IOException {
126
161
TempDirFactory factory = spy (new Factory (null ));
127
162
128
163
assertThatExtensionConfigurationExceptionIsThrownBy (
129
- () -> TempDirectory .createTempDir (factory , DEFAULT , elementContext , extensionContext ));
164
+ () -> TempDirectory .createTempDir (factory , DEFAULT , elementType , elementContext , extensionContext ));
130
165
131
166
verify (factory ).close ();
132
167
}
133
168
134
- @ Test
135
169
@ DisplayName ("fails if the factory returns a file" )
136
- void factoryReturnsFile () throws IOException {
170
+ @ ParameterizedTest
171
+ @ ElementTypeSource
172
+ void factoryReturnsFile (Class <?> elementType ) throws IOException {
137
173
Path file = createFile (root .resolve ("file" ));
138
174
TempDirFactory factory = spy (new Factory (file ));
139
175
140
176
assertThatExtensionConfigurationExceptionIsThrownBy (
141
- () -> TempDirectory .createTempDir (factory , DEFAULT , elementContext , extensionContext ));
177
+ () -> TempDirectory .createTempDir (factory , DEFAULT , elementType , elementContext , extensionContext ));
142
178
143
179
verify (factory ).close ();
144
180
assertThat (file ).doesNotExist ();
145
181
}
146
182
147
- @ Test
148
183
@ DisplayName ("fails if the factory returns a symbolic link to a file" )
149
- @ DisabledOnOs (OS .WINDOWS )
150
- void factoryReturnsSymbolicLinkToFile () throws IOException {
184
+ @ ParameterizedTest
185
+ @ ElementTypeSource
186
+ @ DisabledOnOs (WINDOWS )
187
+ void factoryReturnsSymbolicLinkToFile (Class <?> elementType ) throws IOException {
151
188
Path file = createFile (root .resolve ("file" ));
152
189
Path symbolicLink = createSymbolicLink (root .resolve ("symbolicLink" ), file );
153
190
TempDirFactory factory = spy (new Factory (symbolicLink ));
154
191
155
192
assertThatExtensionConfigurationExceptionIsThrownBy (
156
- () -> TempDirectory .createTempDir (factory , DEFAULT , elementContext , extensionContext ));
193
+ () -> TempDirectory .createTempDir (factory , DEFAULT , elementType , elementContext , extensionContext ));
157
194
158
195
verify (factory ).close ();
159
196
assertThat (symbolicLink ).doesNotExist ();
160
197
161
198
delete (file );
162
199
}
163
200
201
+ @ DisplayName ("fails if the factory returns a directory on a non-default file system for a File annotated element" )
202
+ @ Test
203
+ void factoryReturnsDirectoryOnNonDefaultFileSystemWithFile () throws IOException {
204
+ TempDirFactory factory = spy (new JimfsFactory ());
205
+
206
+ assertThatExceptionOfType (ExtensionConfigurationException .class )//
207
+ .isThrownBy (() -> TempDirectory .createTempDir (factory , DEFAULT , File .class , elementContext ,
208
+ extensionContext ))//
209
+ .withMessage ("Failed to create default temp directory" )//
210
+ .withCauseInstanceOf (PreconditionViolationException .class )//
211
+ .havingCause ().withMessage ("temp directory with non-default file system cannot be injected into "
212
+ + File .class .getName () + " target" );
213
+
214
+ verify (factory ).close ();
215
+ }
216
+
164
217
// Mockito spying a lambda fails with: VM does not support modification of given type
165
218
private record Factory (Path path ) implements TempDirFactory {
166
219
@@ -171,6 +224,22 @@ public Path createTempDirectory(AnnotatedElementContext elementContext, Extensio
171
224
172
225
}
173
226
227
+ private static class JimfsFactory implements TempDirFactory {
228
+
229
+ private final FileSystem fileSystem = Jimfs .newFileSystem (unix ());
230
+
231
+ @ Override
232
+ public Path createTempDirectory (AnnotatedElementContext elementContext , ExtensionContext extensionContext )
233
+ throws Exception {
234
+ return createDirectory (fileSystem .getPath ("/" ).resolve ("directory" ));
235
+ }
236
+
237
+ @ Override
238
+ public void close () throws IOException {
239
+ TempDirFactory .super .close ();
240
+ }
241
+ }
242
+
174
243
private static void assertThatExtensionConfigurationExceptionIsThrownBy (ThrowingCallable callable ) {
175
244
assertThatExceptionOfType (ExtensionConfigurationException .class )//
176
245
.isThrownBy (callable )//
@@ -201,10 +270,13 @@ void cleanupTempDirectory() throws IOException {
201
270
deleteIfExists (closeablePath .get ());
202
271
}
203
272
204
- @ Test
205
273
@ DisplayName ("is done for a cleanup mode of ALWAYS" )
206
- void always () throws IOException {
207
- closeablePath = TempDirectory .createTempDir (factory , ALWAYS , elementContext , extensionContext );
274
+ @ ParameterizedTest
275
+ @ ElementTypeSource
276
+ void always (Class <?> elementType ) throws IOException {
277
+ reset (factory );
278
+
279
+ closeablePath = TempDirectory .createTempDir (factory , ALWAYS , elementType , elementContext , extensionContext );
208
280
assertThat (closeablePath .get ()).isDirectory ();
209
281
210
282
closeablePath .close ();
@@ -213,10 +285,13 @@ void always() throws IOException {
213
285
assertThat (closeablePath .get ()).doesNotExist ();
214
286
}
215
287
216
- @ Test
217
288
@ DisplayName ("is not done for a cleanup mode of NEVER" )
218
- void never () throws IOException {
219
- closeablePath = TempDirectory .createTempDir (factory , NEVER , elementContext , extensionContext );
289
+ @ ParameterizedTest
290
+ @ ElementTypeSource
291
+ void never (Class <?> elementType ) throws IOException {
292
+ reset (factory );
293
+
294
+ closeablePath = TempDirectory .createTempDir (factory , NEVER , elementType , elementContext , extensionContext );
220
295
assertThat (closeablePath .get ()).isDirectory ();
221
296
222
297
closeablePath .close ();
@@ -225,12 +300,16 @@ void never() throws IOException {
225
300
assertThat (closeablePath .get ()).exists ();
226
301
}
227
302
228
- @ Test
229
303
@ DisplayName ("is not done for a cleanup mode of ON_SUCCESS, if there is an exception" )
230
- void onSuccessWithException () throws IOException {
304
+ @ ParameterizedTest
305
+ @ ElementTypeSource
306
+ void onSuccessWithException (Class <?> elementType ) throws IOException {
307
+ reset (factory );
308
+
231
309
when (extensionContext .getExecutionException ()).thenReturn (Optional .of (new Exception ()));
232
310
233
- closeablePath = TempDirectory .createTempDir (factory , ON_SUCCESS , elementContext , extensionContext );
311
+ closeablePath = TempDirectory .createTempDir (factory , ON_SUCCESS , elementType , elementContext ,
312
+ extensionContext );
234
313
assertThat (closeablePath .get ()).isDirectory ();
235
314
236
315
closeablePath .close ();
@@ -239,12 +318,16 @@ void onSuccessWithException() throws IOException {
239
318
assertThat (closeablePath .get ()).exists ();
240
319
}
241
320
242
- @ Test
243
321
@ DisplayName ("is done for a cleanup mode of ON_SUCCESS, if there is no exception" )
244
- void onSuccessWithNoException () throws IOException {
322
+ @ ParameterizedTest
323
+ @ ElementTypeSource
324
+ void onSuccessWithNoException (Class <?> elementType ) throws IOException {
325
+ reset (factory );
326
+
245
327
when (extensionContext .getExecutionException ()).thenReturn (Optional .empty ());
246
328
247
- closeablePath = TempDirectory .createTempDir (factory , ON_SUCCESS , elementContext , extensionContext );
329
+ closeablePath = TempDirectory .createTempDir (factory , ON_SUCCESS , elementType , elementContext ,
330
+ extensionContext );
248
331
assertThat (closeablePath .get ()).isDirectory ();
249
332
250
333
closeablePath .close ();
0 commit comments