Skip to content

Commit

Permalink
Add configuration parameter for Jimfs default configuration
Browse files Browse the repository at this point in the history
Closes #1.
  • Loading branch information
scordio committed Sep 8, 2024
1 parent 1162d17 commit 2a4e0a1
Show file tree
Hide file tree
Showing 6 changed files with 466 additions and 133 deletions.
50 changes: 37 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ testImplementation("io.github.scordio:jimfs-junit-jupiter:${jimfsJunitJupiterVer

### JimfsTempDirFactory

The simplest possible usage is to set the
The simplest usage is to set the
[`factory`](https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/io/TempDir.html#factory())
attribute of `@TempDir` to `JimfsTempDirFactory`:

Expand All @@ -67,14 +67,13 @@ void test(@TempDir(factory = JimfsTempDirFactory.class) Path tempDir) {
```

`tempDir` is resolved into an in-memory temporary directory based on Jimfs, appropriately configured for the current
operating system.
platform.

### @JimfsTempDir

`@JimfsTempDir`, a `@TempDir`
[composed annotation](https://junit.org/junit5/docs/current/user-guide/#writing-tests-meta-annotations),
can be used as a drop-in replacement for
`@TempDir(factory = JimfsTempDirFactory.class)`:
can be used as a drop-in replacement for `@TempDir(factory = JimfsTempDirFactory.class)`:

```java
@Test
Expand All @@ -85,16 +84,17 @@ void test(@JimfsTempDir Path tempDir) {

The default behavior of the annotation is equivalent to using `JimfsTempDirFactory` directly:
`tempDir` is resolved into an in-memory temporary directory based on Jimfs, appropriately configured for the current
operating system.
platform.

For better control over the underlying in-memory file system,
`@JimfsTempDir` offers an optional `value` attribute that can be set to the desired configuration, one of:
* `FOR_CURRENT_PLATFORM`: appropriate to the current operating system (default)
For better control over the underlying in-memory file system, `@JimfsTempDir` offers an optional `value` attribute
that can be set to the desired configuration, one of:
* `DEFAULT`: based on the corresponding [configuration parameter](#default-jimfs-configuration) (default)
* `FOR_CURRENT_PLATFORM`: appropriate to the current platform
* `OS_X`: for a Mac OS X-like file system
* `UNIX`: for a UNIX-like file system
* `WINDOWS`: for a Windows-like file system

For example, the following defines a Windows-like temporary directory regardless of the operating system the test
For example, the following defines a Windows-like temporary directory regardless of the platform the test
is running on:

```java
Expand All @@ -104,11 +104,16 @@ void test(@JimfsTempDir(WINDOWS) Path tempDir) {
}
```

### Default Configuration
### Configuration Parameters

Jimfs JUnit Jupiter supports JUnit
[configuration parameters](https://junit.org/junit5/docs/current/user-guide/#running-tests-config-params).

#### Default `@TempDir` Factory

The `junit.jupiter.tempdir.factory.default` configuration parameter sets the default factory to use, expecting its
fully qualified class name.

The `junit.jupiter.tempdir.factory.default`
[configuration parameter](https://junit.org/junit5/docs/current/user-guide/#running-tests-config-params)
can be used to specify the fully qualified class name of the factory to be used by default.
For example, the following configures `JimfsTempDirFactory`:

```properties
Expand All @@ -118,6 +123,25 @@ junit.jupiter.tempdir.factory.default=io.github.scordio.jimfs.junit.jupiter.Jimf
The factory will be used for all `@TempDir` annotations unless the `factory` attribute of the annotation
specifies a different type.

#### Default Jimfs Configuration

The `jimfs.junit.jupiter.tempdir.configuration.default` configuration parameter sets the default Jimfs configuration
to use, expecting one of the following (case-insensitive):
* `FOR_CURRENT_PLATFORM`: appropriate to the current platform (default)
* `OS_X`: for a Mac OS X-like file system
* `UNIX`: for a UNIX-like file system
* `WINDOWS`: for a Windows-like file system

For example, the following defines a Windows-like temporary directory regardless of the platform the test
is running on:

```properties
jimfs.junit.jupiter.tempdir.configuration.default=windows
```

All Jimfs-based temporary directories will be configured accordingly unless `@JimfsTempDir` is used and
its `value` attribute is set.

### Limitations

Jimfs JUnit Jupiter only supports annotated fields or parameters of type `Path`, as Jimfs is a non-default file
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,25 @@
@TempDir(factory = JimfsTempDirFactory.class)
public @interface JimfsTempDir {

/**
* Configuration parameter to set the default {@link Configuration Configuration} for the
* in-memory file system.
*
* <p>If this configuration parameter is not set, the default is {@link
* Configuration#FOR_CURRENT_PLATFORM}.
*
* @since 0.2.0
*/
String DEFAULT_CONFIGURATION_PARAMETER_NAME = "jimfs.junit.jupiter.tempdir.configuration.default";

/**
* Configuration for the in-memory file system.
*
* <p>Defaults to {@link Configuration#FOR_CURRENT_PLATFORM}.
*
* @return the configuration to use for the in-memory file system
*/
Configuration value() default Configuration.FOR_CURRENT_PLATFORM;
Configuration value() default Configuration.DEFAULT;

/**
* Enumeration of configurations for the in-memory file system.
Expand All @@ -56,7 +67,14 @@
*/
enum Configuration {
/**
* Configuration appropriate to the current operating system.
* Default configuration.
*
* @see #DEFAULT_CONFIGURATION_PARAMETER_NAME
* @since 0.2.0
*/
DEFAULT(com.google.common.jimfs.Configuration::forCurrentPlatform),
/**
* Configuration appropriate to the current platform.
*
* @see com.google.common.jimfs.Configuration#forCurrentPlatform()
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Locale;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
import org.junit.jupiter.api.extension.AnnotatedElementContext;
import org.junit.jupiter.api.extension.ExtensionContext;
Expand All @@ -31,28 +33,33 @@
* {@link TempDirFactory} implementation that creates an in-memory temporary directory via {@link
* Jimfs}, using {@value DEFAULT_PREFIX} as the name prefix.
*
* <p>If used as a standalone factory within the {@link org.junit.jupiter.api.io.TempDir}
* annotation, or set as value for the {@value DEFAULT_FACTORY_PROPERTY_NAME} configuration
* property, the factory configures the underlying file system {@link
* Configuration#forCurrentPlatform() appropriately for the current operating system}.
* <p>When used as a standalone factory within the {@link org.junit.jupiter.api.io.TempDir}
* annotation, or set as value for the {@value
* org.junit.jupiter.api.io.TempDir#DEFAULT_FACTORY_PROPERTY_NAME} configuration parameter, the
* factory configures the underlying file system appropriately for the {@link
* com.google.common.jimfs.Configuration#forCurrentPlatform() current platform}.
*
* <p>For better control over the underlying in-memory file system, consider using the {@link
* JimfsTempDir} composed annotation and its {@link JimfsTempDir#value() value} attribute.
* <p>For better control over the underlying in-memory file system, consider using one of the
* following options:
*
* <ul>
* <li>The {@link JimfsTempDir} composed annotation and its {@link JimfsTempDir#value() value}
* attribute.
* <li>The {@value JimfsTempDir#DEFAULT_CONFIGURATION_PARAMETER_NAME} configuration parameter.
* </ul>
*
* <p>Please note that only annotated fields or parameters of type {@link java.nio.file.Path} are
* supported as Jimfs is a non-default file system, and {@link java.io.File} instances are
* associated with the default file system only.
*
* @see Jimfs#newFileSystem(Configuration)
* @see Configuration#forCurrentPlatform()
* @see Jimfs#newFileSystem(com.google.common.jimfs.Configuration)
* @see com.google.common.jimfs.Configuration#forCurrentPlatform()
*/
public final class JimfsTempDirFactory implements TempDirFactory {

private static final String DEFAULT_PREFIX = "junit-";

@SuppressWarnings("unused")
private static final String DEFAULT_FACTORY_PROPERTY_NAME =
org.junit.jupiter.api.io.TempDir.DEFAULT_FACTORY_PROPERTY_NAME;
private static final Function<String, JimfsTempDir.Configuration> CONFIGURATION_TRANSFORMER =
value -> JimfsTempDir.Configuration.valueOf(value.trim().toUpperCase(Locale.ROOT));

private FileSystem fileSystem;

Expand All @@ -69,14 +76,27 @@ public Path createTempDirectory(
Supplier<Configuration> configuration =
annotation
.map(JimfsTempDir::value)
.filter(JimfsTempDirFactory::isNotDefaultConfiguration)
.map(JimfsTempDir.Configuration::getConfiguration)
.orElse(Configuration::forCurrentPlatform);
.orElseGet(
() ->
extensionContext
.getConfigurationParameter(
JimfsTempDir.DEFAULT_CONFIGURATION_PARAMETER_NAME,
CONFIGURATION_TRANSFORMER)
.filter(JimfsTempDirFactory::isNotDefaultConfiguration)
.map(JimfsTempDir.Configuration::getConfiguration)
.orElse(Configuration::forCurrentPlatform));

fileSystem = Jimfs.newFileSystem(configuration.get());
Path root = fileSystem.getRootDirectories().iterator().next();
return Files.createTempDirectory(root, DEFAULT_PREFIX);
}

private static boolean isNotDefaultConfiguration(JimfsTempDir.Configuration value) {
return value != JimfsTempDir.Configuration.DEFAULT;
}

/** {@inheritDoc} */
@Override
public void close() throws IOException {
Expand Down
Loading

0 comments on commit 2a4e0a1

Please sign in to comment.