Remove update with default configuration.

Default values for Records can now be provided through constructors
that have no parameters.
dev
Exlll 2 years ago
parent 5b9c7754b4
commit d1acb875c2

@ -81,16 +81,16 @@ public final class Example {
var config = new UserConfiguration();
// Save a new instance to the configuration file
YamlConfigurations.saveConfiguration(configFile, UserConfiguration.class, config);
YamlConfigurations.save(configFile, UserConfiguration.class, config);
// Load a new instance from the configuration file
config = YamlConfigurations.loadConfiguration(configFile, UserConfiguration.class);
config = YamlConfigurations.load(configFile, UserConfiguration.class);
System.out.println(config.admin.username);
System.out.println(config.blockedUsers);
// Modify and save the configuration file
config.blockedUsers.add(new User("user3", "pass3"));
YamlConfigurations.saveConfiguration(configFile, UserConfiguration.class, config);
YamlConfigurations.save(configFile, UserConfiguration.class, config);
}
}
```
@ -294,41 +294,40 @@ Config config2 = store.update(configurationFile);
The second way is to use the static methods from the `YamlConfigurations` class.
```java
Config config1 = YamlConfigurations.loadConfiguration(configurationFile, Config.class);
YamlConfigurations.saveConfiguration(configurationFile, Config.class, config1);
Config config2 = YamlConfigurations.updateConfiguration(configurationFile, Config.class);
Config config1 = YamlConfigurations.load(configurationFile, Config.class);
YamlConfigurations.save(configurationFile, Config.class, config1);
Config config2 = YamlConfigurations.update(configurationFile, Config.class);
```
<hr>
Each of these methods has two additional overloads: One that takes a properties object and another
that lets you configure a properties object builder. For example, the overloads for the
`loadYamlConfiguration` method are:
that lets you configure a properties object builder. For example, the overloads of the `load`
method are:
```java
// overload 1
YamlConfigurationProperties properties = YamlConfigurationProperties.newBuilder()
.inputNulls(true)
.outputNulls(false)
.build();
Config c1 = YamlConfigurations.loadConfiguration(configurationFile, Config.class, properties);
YamlConfigurationProperties properties = YamlConfigurationProperties.newBuilder().build();
Config c1 = YamlConfigurations.load(configurationFile, Config.class, properties);
// overload 2
Config c2 = YamlConfigurations.loadConfiguration(
Config c2 = YamlConfigurations.load(
configurationFile,
Config.class,
builder -> builder.inputNulls(true).outputNulls(false)
);
```
All three methods can also be passed a Java record instead of a class. Because you cannot provide
default values for records, the `update` method also has an additional variant which takes a default
configuration:
<hr>
All three methods can also be passed a Java record instead of a class. To provide default values
for records when calling the `update` method, you can add a constructor with no parameters that
initializes its components. This constructor is only called if the configuration file does not
exist.
```java
record User(String name, String email) {}
YamlConfigurationStore<User> store = new YamlConfigurationStore<>(User.class, properties);
User user = store.update(configurationFile, new User("John Doe", "john@doe.com"));
record User(String name, String email) {
User() { this("John Doe", "john@doe.com"); }
}
User user = YamlConfigurations.update(configurationFile, User.class);
```
### Configuration properties
@ -682,8 +681,9 @@ This section contains ideas for upcoming features. If you want any of these to h
please [open an issue](https://github.com/Exlll/ConfigLib/issues/new) where we can discuss the
details.
- Optional fields
- Post load / pre save hooks
- TOML support
- Change the order of fields in parent/child class scenarios
- JSON, TOML, XML support
- Post-load/Pre-save hooks
- More features and control over updating/versioning
- More control over the ordering of fields, especially in parent/child class scenarios
- Recursive definitions
- Shadowing of fields

@ -12,7 +12,7 @@ final class ConfigurationSerializer<T> extends TypeSerializer<T, ConfigurationFi
@Override
public T deserialize(Map<?, ?> element) {
final T result = Reflect.newInstance(type);
final T result = Reflect.callNoParamConstructor(type);
for (final var component : components()) {
final var formattedName = formatter.format(component.componentName());
@ -60,7 +60,7 @@ final class ConfigurationSerializer<T> extends TypeSerializer<T, ConfigurationFi
@Override
T newDefaultInstance() {
return Reflect.newInstance(type);
return Reflect.callNoParamConstructor(type);
}
private static void requireNonPrimitiveFieldType(Field field) {

@ -33,37 +33,28 @@ public interface FileConfigurationStore<T> {
T load(Path configurationFile);
/**
* Updates the configuration file. If the file does not exist, it is created and populated
* with the default values with which the fields of the configuration have been initialized.
* If the configuration is of record type, the default values are chosen to be the default
* values of its component types. Otherwise, if the file exists, a new configuration instance
* is created, initialized with the values taken from the configuration file, and immediately
* saved to reflect possible changes of the configuration type.
* Updates the configuration file.
* <ul>
* <li>
* If the file does not exist, it is created and populated with the default values with which
* the fields of the configuration have been initialized. If the configuration is of record type,
* the default values are either chosen to be the default values of its component types
* (i.e. zero for primitive numbers, null for references, etc) or, if the record defines a
* constructor with no parameters, the values with which this constructor initializes the
* components of the record.
* </li>
* <li>
* Otherwise, if the file exists, a new configuration instance is created, initialized with the
* values taken from the configuration file, and immediately saved to reflect possible changes
* of the configuration type.
* </li>
* </ul>
*
* @param configurationFile the configuration file that is updated
* @return a newly created configuration initialized with values taken from the configuration file
* @throws ConfigurationException if the configuration cannot be deserialized
* @throws NullPointerException if {@code configurationFile} is null
* @throws RuntimeException if loading or saving the configuration throws an exception
* @see #update(Path, Object)
*/
T update(Path configurationFile);
/**
* Updates the configuration file. If the file does not exist, it is created and populated
* with values taken from the {@code defaultConfiguration} object.
* Otherwise, if the file exists, a new configuration instance is created, initialized with the
* values taken from the configuration file, and immediately saved to reflect possible changes
* of the configuration type.
*
* @param configurationFile the configuration file that is updated
* @param defaultConfiguration the default value used when creating a new file
* @return a configuration initialized with values taken from the configuration file or
* the default value if the file was newly created
* @throws ConfigurationException if the configuration cannot be deserialized
* @throws NullPointerException if any argument is null
* @throws RuntimeException if loading or saving the configuration throws an exception
* @see #update(Path)
*/
T update(Path configurationFile, T defaultConfiguration);
}

@ -40,7 +40,7 @@ final class RecordSerializer<R> extends
}
}
return Reflect.newRecord(type, constructorArguments);
return Reflect.callCanonicalConstructor(type, constructorArguments);
}
@Override
@ -67,7 +67,9 @@ final class RecordSerializer<R> extends
@Override
R newDefaultInstance() {
return Reflect.newRecordDefaultValues(type);
return Reflect.hasDefaultConstructor(type)
? Reflect.callNoParamConstructor(type)
: Reflect.callCanonicalConstructorWithDefaultValues(type);
}
private static void requireNonPrimitiveComponentType(RecordComponent component) {

@ -38,33 +38,34 @@ final class Reflect {
return defaultValue;
}
static <T> T newInstance(Class<T> cls) {
static <T> T callNoParamConstructor(Class<T> cls) {
try {
Constructor<T> constructor = cls.getDeclaredConstructor();
constructor.setAccessible(true);
return constructor.newInstance();
} catch (NoSuchMethodException e) {
String msg = "Class " + cls.getSimpleName() + " doesn't have a " +
"no-args constructor.";
String msg = "Type '%s' doesn't have a no-args constructor."
.formatted(cls.getSimpleName());
throw new RuntimeException(msg, e);
} catch (IllegalAccessException e) {
/* This exception should not be thrown because
* we set the constructor to be accessible. */
String msg = "No-args constructor of class " + cls.getSimpleName() +
" not accessible.";
String msg = "No-args constructor of type '%s' not accessible."
.formatted(cls.getSimpleName());
throw new RuntimeException(msg, e);
} catch (InstantiationException e) {
String msg = "Class " + cls.getSimpleName() + " is not instantiable.";
String msg = "Type '%s' is not instantiable.".formatted(cls.getSimpleName());
throw new RuntimeException(msg, e);
} catch (InvocationTargetException e) {
String msg = "Constructor of class " + cls.getSimpleName() + " threw an exception.";
String msg = "No-args constructor of type '%s' threw an exception."
.formatted(cls.getSimpleName());
throw new RuntimeException(msg, e);
}
}
// We could use <R extends Record> as a bound here and for the other methods below
// but that would require casts elsewhere.
static <R> R newRecord(Class<R> recordType, Object... constructorArguments) {
static <R> R callCanonicalConstructor(Class<R> recordType, Object... constructorArguments) {
try {
Constructor<R> constructor = getCanonicalConstructor(requireRecord(recordType));
constructor.setAccessible(true);
@ -79,17 +80,17 @@ final class Reflect {
// cannot happen because records are instantiable
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
String msg = "The canonical constructor of record type '" +
recordType.getSimpleName() + "' threw an exception.";
String msg = "The canonical constructor of record type '%s' threw an exception."
.formatted(recordType.getSimpleName());
throw new RuntimeException(msg, e);
}
}
static <R> R newRecordDefaultValues(Class<R> recordType) {
static <R> R callCanonicalConstructorWithDefaultValues(Class<R> recordType) {
final Object[] args = Arrays.stream(recordParameterTypes(requireRecord(recordType)))
.map(Reflect::getDefaultValue)
.toArray(Object[]::new);
return Reflect.newRecord(recordType, args);
return Reflect.callCanonicalConstructor(recordType, args);
}
static <R> Constructor<R> getCanonicalConstructor(Class<R> recordType)
@ -111,15 +112,21 @@ final class Reflect {
return array;
}
static boolean hasDefaultConstructor(Class<?> type) {
for (Constructor<?> constructor : type.getDeclaredConstructors()) {
if (constructor.getParameterCount() == 0)
return true;
}
return false;
}
static Object getValue(Field field, Object instance) {
try {
field.setAccessible(true);
return field.get(instance);
} catch (IllegalAccessException e) {
/* This exception should not be thrown because
* we set the field to be accessible. */
String msg = "Illegal access of field '" + field + "' " +
"on object " + instance + ".";
/* This exception should not be thrown because we set the field to be accessible. */
String msg = "Illegal access of field '%s' on object %s.".formatted(field, instance);
throw new RuntimeException(msg, e);
}
}
@ -146,10 +153,8 @@ final class Reflect {
field.setAccessible(true);
field.set(instance, value);
} catch (IllegalAccessException e) {
/* This exception should not be thrown because
* we set the field to be accessible. */
String msg = "Illegal access of field '" + field + "' " +
"on object " + instance + ".";
/* This exception should not be thrown because we set the field to be accessible. */
String msg = "Illegal access of field '%s' on object %s.".formatted(field, instance);
throw new RuntimeException(msg, e);
}
}

@ -211,4 +211,22 @@ class RecordSerializerTest {
"the deserializer expects."
);
}
@Test
void newDefaultInstanceWithoutDefaultConstructor() {
record R(int i, String s) {}
R r = newSerializer(R.class).newDefaultInstance();
assertThat(r.i, is(0));
assertThat(r.s, nullValue());
}
@Test
void newDefaultInstanceWithDefaultConstructor() {
record R(int i, String s) {
R() {this(10, "s");}
}
R r = newSerializer(R.class).newDefaultInstance();
assertThat(r.i, is(10));
assertThat(r.s, is("s"));
}
}

@ -40,20 +40,20 @@ class ReflectTest {
}
@Test
void newInstanceRequiresNoArgsCtor() {
void callNoParamConstructorRequiresNoParamCtor() {
assertThrowsRuntimeException(
() -> Reflect.newInstance(B1.class),
"Class B1 doesn't have a no-args constructor."
() -> Reflect.callNoParamConstructor(B1.class),
"Type 'B1' doesn't have a no-args constructor."
);
}
static abstract class B2 {}
@Test
void newInstanceRequiresConcreteClass() {
void callNoParamConstructorRequiresConcreteClass() {
assertThrowsRuntimeException(
() -> Reflect.newInstance(B2.class),
"Class B2 is not instantiable."
() -> Reflect.callNoParamConstructor(B2.class),
"Type 'B2' is not instantiable."
);
}
@ -64,10 +64,10 @@ class ReflectTest {
}
@Test
void newInstanceRequiresNonThrowingCtor() {
void callNoParamConstructorRequiresNonThrowingCtor() {
assertThrowsRuntimeException(
() -> Reflect.newInstance(B3.class),
"Constructor of class B3 threw an exception."
() -> Reflect.callNoParamConstructor(B3.class),
"No-args constructor of type 'B3' threw an exception."
);
}
@ -76,8 +76,8 @@ class ReflectTest {
}
@Test
void newInstance() {
B4 inst = Reflect.newInstance(B4.class);
void callNoParamConstructor() {
B4 inst = Reflect.callNoParamConstructor(B4.class);
assertThat(inst, notNullValue());
assertThat(inst.i, is(10));
}
@ -279,8 +279,8 @@ class ReflectTest {
}
@Test
void newRecord1() {
R1 r = Reflect.newRecord(R1.class, 1, 2f);
void callCanonicalConstructor1() {
R1 r = Reflect.callCanonicalConstructor(R1.class, 1, 2f);
assertThat(r.i, is(1));
assertThat(r.f, is(2f));
}
@ -288,8 +288,8 @@ class ReflectTest {
record R2() {}
@Test
void newRecord2() {
Reflect.newRecord(R2.class);
void callCanonicalConstructor2() {
Reflect.callCanonicalConstructor(R2.class);
}
record R3(String s) {
@ -299,28 +299,28 @@ class ReflectTest {
}
@Test
void newRecordWithThrowingCtor() {
void callCanonicalConstructorWithThrowingCtor() {
assertThrowsRuntimeException(
() -> Reflect.newRecord(R3.class, ""),
() -> Reflect.callCanonicalConstructor(R3.class, ""),
"The canonical constructor of record type 'R3' threw an exception."
);
}
@Test
void newRecordRequiresRecordType() {
void callCanonicalConstructorRequiresRecordType() {
class A {}
assertThrowsConfigurationException(
() -> Reflect.newRecord(A.class),
() -> Reflect.callCanonicalConstructor(A.class),
"Class 'A' must be a record."
);
}
@Test
void newRecordWithDefaultValues() {
void callCanonicalConstructorWithDefaultValues() {
record E() {}
record R(boolean a, char b, byte c, short d, int e, long f, float g, double h,
Boolean i, Character j, Integer k, Float l, E m, R n, Object o) {}
R r = Reflect.newRecordDefaultValues(R.class);
R r = Reflect.callCanonicalConstructorWithDefaultValues(R.class);
assertFalse(r.a);
assertEquals('\0', r.b);
assertEquals(0, r.c);
@ -337,4 +337,14 @@ class ReflectTest {
assertNull(r.n);
assertNull(r.o);
}
@Test
void hasDefaultConstructor() {
record R1(int i) {}
record R2(int i) {
R2() {this(10);}
}
assertFalse(Reflect.hasDefaultConstructor(R1.class));
assertTrue(Reflect.hasDefaultConstructor(R2.class));
}
}

@ -110,16 +110,12 @@ public final class YamlConfigurationStore<T> implements FileConfigurationStore<T
@Override
public T update(Path configurationFile) {
return update(configurationFile, serializer.newDefaultInstance());
}
@Override
public T update(Path configurationFile, T defaultConfiguration) {
if (Files.exists(configurationFile)) {
T configuration = load(configurationFile);
save(configuration, configurationFile);
return configuration;
}
T defaultConfiguration = serializer.newDefaultInstance();
save(defaultConfiguration, configurationFile);
return defaultConfiguration;
}

@ -23,12 +23,9 @@ public final class YamlConfigurations {
* @throws RuntimeException if reading the configuration throws an exception
* @see YamlConfigurationStore#load(Path)
*/
public static <T> T loadConfiguration(
Path configurationFile,
Class<T> configurationType
) {
public static <T> T load(Path configurationFile, Class<T> configurationType) {
final var properties = YamlConfigurationProperties.newBuilder().build();
return loadConfiguration(configurationFile, configurationType, properties);
return load(configurationFile, configurationType, properties);
}
/**
@ -47,14 +44,14 @@ public final class YamlConfigurations {
* @throws RuntimeException if reading the configuration throws an exception
* @see YamlConfigurationStore#load(Path)
*/
public static <T> T loadConfiguration(
public static <T> T load(
Path configurationFile,
Class<T> configurationType,
Consumer<YamlConfigurationProperties.Builder<?>> propertiesConfigurer
) {
final var builder = YamlConfigurationProperties.newBuilder();
propertiesConfigurer.accept(builder);
return loadConfiguration(configurationFile, configurationType, builder.build());
return load(configurationFile, configurationType, builder.build());
}
/**
@ -72,7 +69,7 @@ public final class YamlConfigurations {
* @throws RuntimeException if reading the configuration throws an exception
* @see YamlConfigurationStore#load(Path)
*/
public static <T> T loadConfiguration(
public static <T> T load(
Path configurationFile,
Class<T> configurationType,
YamlConfigurationProperties properties
@ -86,7 +83,6 @@ public final class YamlConfigurations {
* {@code YamlConfigurationProperties} object with default values.
* <p>
* See {@link YamlConfigurationStore#update(Path)} for an explanation of how the update is done.
* done.
*
* @param configurationFile the configuration file that is updated
* @param configurationType the type of configuration
@ -97,12 +93,9 @@ public final class YamlConfigurations {
* @throws RuntimeException if loading or saving the configuration throws an exception
* @see YamlConfigurationStore#update(Path)
*/
public static <T> T updateConfiguration(
Path configurationFile,
Class<T> configurationType
) {
public static <T> T update(Path configurationFile, Class<T> configurationType) {
final var properties = YamlConfigurationProperties.newBuilder().build();
return updateConfiguration(configurationFile, configurationType, properties);
return update(configurationFile, configurationType, properties);
}
/**
@ -122,14 +115,14 @@ public final class YamlConfigurations {
* @throws RuntimeException if loading or saving the configuration throws an exception
* @see YamlConfigurationStore#update(Path)
*/
public static <T> T updateConfiguration(
public static <T> T update(
Path configurationFile,
Class<T> configurationType,
Consumer<YamlConfigurationProperties.Builder<?>> propertiesConfigurer
) {
final var builder = YamlConfigurationProperties.newBuilder();
propertiesConfigurer.accept(builder);
return updateConfiguration(configurationFile, configurationType, builder.build());
return update(configurationFile, configurationType, builder.build());
}
/**
@ -148,7 +141,7 @@ public final class YamlConfigurations {
* @throws RuntimeException if loading or saving the configuration throws an exception
* @see YamlConfigurationStore#update(Path)
*/
public static <T> T updateConfiguration(
public static <T> T update(
Path configurationFile,
Class<T> configurationType,
YamlConfigurationProperties properties
@ -171,13 +164,13 @@ public final class YamlConfigurations {
* @throws RuntimeException if writing the configuration throws an exception
* @see YamlConfigurationStore#save(Object, Path)
*/
public static <T> void saveConfiguration(
public static <T> void save(
Path configurationFile,
Class<T> configurationType,
T configuration
) {
final var properties = YamlConfigurationProperties.newBuilder().build();
saveConfiguration(configurationFile, configurationType, configuration, properties);
save(configurationFile, configurationType, configuration, properties);
}
/**
@ -196,7 +189,7 @@ public final class YamlConfigurations {
* @throws RuntimeException if writing the configuration throws an exception
* @see YamlConfigurationStore#save(Object, Path)
*/
public static <T> void saveConfiguration(
public static <T> void save(
Path configurationFile,
Class<T> configurationType,
T configuration,
@ -204,7 +197,7 @@ public final class YamlConfigurations {
) {
final var builder = YamlConfigurationProperties.newBuilder();
propertiesConfigurer.accept(builder);
saveConfiguration(configurationFile, configurationType, configuration, builder.build());
save(configurationFile, configurationType, configuration, builder.build());
}
/**
@ -222,7 +215,7 @@ public final class YamlConfigurations {
* @throws RuntimeException if writing the configuration throws an exception
* @see YamlConfigurationStore#save(Object, Path)
*/
public static <T> void saveConfiguration(
public static <T> void save(
Path configurationFile,
Class<T> configurationType,
T configuration,

@ -294,6 +294,28 @@ class YamlConfigurationStoreTest {
assertNull(config.s);
}
@Test
void updateCreatesConfigurationFileIfItDoesNotExistRecordNoParamCtor() {
record R(int i, char c, String s) {
R() {this(10, 'c', "s");}
}
YamlConfigurationStore<R> store = newDefaultStore(R.class);
assertFalse(Files.exists(yamlFile));
R config = store.update(yamlFile);
assertEquals(
"""
i: 10
c: c
s: s\
""",
readFile(yamlFile)
);
assertEquals(10, config.i);
assertEquals('c', config.c);
assertEquals("s", config.s);
}
@Test
void updateLoadsConfigurationFileIfItDoesExist() throws IOException {
YamlConfigurationStore<E> store = newDefaultStore(E.class);
@ -338,82 +360,6 @@ class YamlConfigurationStoreTest {
assertEquals("i: 20\nj: 0", readFile(yamlFile));
}
@Test
void updateWithDefaultCreatesConfigurationFileIfItDoesNotExist() {
final YamlConfigurationStore<E> store = newDefaultStore(E.class);
final E defaultConfig = new E(20, 21);
assertFalse(Files.exists(yamlFile));
E config = store.update(yamlFile, defaultConfig);
assertEquals("i: 20\nj: 21", readFile(yamlFile));
assertSame(defaultConfig, config);
}
@Test
void updateWithDefaultCreatesConfigurationFileIfItDoesNotExistRecord() {
record R(int i, char c, String s) {}
final YamlConfigurationStore<R> store = new YamlConfigurationStore<>(
R.class,
YamlConfigurationProperties.newBuilder().outputNulls(true).build()
);
final R defaultConfig = new R(1, 'a', "s");
assertFalse(Files.exists(yamlFile));
R config = store.update(yamlFile, defaultConfig);
assertEquals("i: 1\nc: a\ns: s", readFile(yamlFile));
assertSame(defaultConfig, config);
}
@Test
void updateWithDefaultLoadsConfigurationFileIfItDoesExist() throws IOException {
final YamlConfigurationStore<E> store = newDefaultStore(E.class);
final E defaultConfig = new E(100, 200);
Files.writeString(yamlFile, "i: 20");
E config = store.update(yamlFile, defaultConfig);
assertEquals(20, config.i);
assertEquals(11, config.j);
assertNotSame(defaultConfig, config);
}
@Test
void updateWithDefaultLoadsConfigurationFileIfItDoesExistRecord() throws IOException {
record R(int i, int j) {}
final YamlConfigurationStore<R> store = newDefaultStore(R.class);
final R defaultConfig = new R(100, 200);
Files.writeString(yamlFile, "i: 20");
R config = store.update(yamlFile, defaultConfig);
assertEquals(20, config.i);
assertEquals(0, config.j);
}
@Test
void updateWithDefaultUpdatesFile() throws IOException {
final YamlConfigurationStore<E> store = newDefaultStore(E.class);
final E defaultConfig = new E(100, 200);
Files.writeString(yamlFile, "i: 20\nk: 30");
E config = store.update(yamlFile, defaultConfig);
assertEquals(20, config.i);
assertEquals(11, config.j);
assertEquals("i: 20\nj: 11", readFile(yamlFile));
}
@Test
void updateWithDefaultUpdatesFileRecord() throws IOException {
record R(int i, int j) {}
final YamlConfigurationStore<R> store = newDefaultStore(R.class);
final R defaultConfig = new R(100, 200);
Files.writeString(yamlFile, "i: 20\nk: 30");
R config = store.update(yamlFile, defaultConfig);
assertEquals(20, config.i);
assertEquals(0, config.j);
assertEquals("i: 20\nj: 0", readFile(yamlFile));
}
private static <T> YamlConfigurationStore<T> newDefaultStore(Class<T> configType) {
YamlConfigurationProperties properties = YamlConfigurationProperties.newBuilder().build();
return new YamlConfigurationStore<>(configType, properties);

@ -31,17 +31,24 @@ class YamlConfigurationsTest {
private static final class Config {
int i = 10;
int j = 11;
public Config() {}
public Config(int i, int j) {
this.i = i;
this.j = j;
}
}
@Test
void saveYamlConfiguration1() {
Config configuration = new Config();
YamlConfigurations.saveConfiguration(yamlFile, Config.class, configuration);
YamlConfigurations.save(yamlFile, Config.class, configuration);
assertEquals("i: 10\nj: 11", TestUtils.readFile(yamlFile));
configuration.i = 20;
YamlConfigurations.saveConfiguration(yamlFile, Config.class, configuration);
YamlConfigurations.save(yamlFile, Config.class, configuration);
assertEquals("i: 20\nj: 11", TestUtils.readFile(yamlFile));
}
@ -49,7 +56,7 @@ class YamlConfigurationsTest {
void saveYamlConfiguration2() {
Config configuration = new Config();
YamlConfigurations.saveConfiguration(
YamlConfigurations.save(
yamlFile, Config.class, configuration,
builder -> builder.setFieldFilter(includeI)
);
@ -60,7 +67,7 @@ class YamlConfigurationsTest {
void saveYamlConfiguration3() {
Config configuration = new Config();
YamlConfigurations.saveConfiguration(
YamlConfigurations.save(
yamlFile, Config.class, configuration,
YamlConfigurationProperties.newBuilder().setFieldFilter(includeI).build()
);
@ -70,18 +77,18 @@ class YamlConfigurationsTest {
@Test
void loadYamlConfiguration1() {
writeString("i: 20\nk: 30");
Config config = YamlConfigurations.loadConfiguration(yamlFile, Config.class);
Config config = YamlConfigurations.load(yamlFile, Config.class);
assertConfigEquals(config, 20, 11);
writeString("i: 20\nj: 30");
config = YamlConfigurations.loadConfiguration(yamlFile, Config.class);
config = YamlConfigurations.load(yamlFile, Config.class);
assertConfigEquals(config, 20, 30);
}
@Test
void loadYamlConfiguration2() {
writeString("i: 20\nj: 30");
Config config = YamlConfigurations.loadConfiguration(
Config config = YamlConfigurations.load(
yamlFile, Config.class,
builder -> builder.setFieldFilter(includeI)
);
@ -92,7 +99,7 @@ class YamlConfigurationsTest {
void loadYamlConfiguration3() {
writeString("i: 20\nj: 30");
Config config = YamlConfigurations.loadConfiguration(
Config config = YamlConfigurations.load(
yamlFile, Config.class,
YamlConfigurationProperties.newBuilder().setFieldFilter(includeI).build()
);
@ -102,19 +109,19 @@ class YamlConfigurationsTest {
@Test
void updateYamlConfiguration1() {
Config config = YamlConfigurations.updateConfiguration(yamlFile, Config.class);
Config config = YamlConfigurations.update(yamlFile, Config.class);
assertConfigEquals(config, 10, 11);
assertEquals("i: 10\nj: 11", TestUtils.readFile(yamlFile));
writeString("i: 20\nk: 30");
config = YamlConfigurations.updateConfiguration(yamlFile, Config.class);
config = YamlConfigurations.update(yamlFile, Config.class);
assertConfigEquals(config, 20, 11);
assertEquals("i: 20\nj: 11", TestUtils.readFile(yamlFile));
}
@Test
void updateYamlConfiguration2() {
Config config = YamlConfigurations.updateConfiguration(
Config config = YamlConfigurations.update(
yamlFile, Config.class,
builder -> builder.setFieldFilter(includeI)
);
@ -124,7 +131,7 @@ class YamlConfigurationsTest {
@Test
void updateYamlConfiguration3() {
Config config = YamlConfigurations.updateConfiguration(
Config config = YamlConfigurations.update(
yamlFile, Config.class,
YamlConfigurationProperties.newBuilder().setFieldFilter(includeI).build()
);

@ -475,7 +475,11 @@ class YamlFileWriterTest {
}
<T> void writeConfig(Class<T> cls, Consumer<YamlConfigurationProperties.Builder<?>> configurer) {
YamlFileWriterArguments args = argsFromConfig(cls, Reflect.newInstance(cls), configurer);
YamlFileWriterArguments args = argsFromConfig(
cls,
Reflect.callNoParamConstructor(cls),
configurer
);
YamlFileWriter writer = new YamlFileWriter(yamlFile, args.properties);
writer.writeYaml(args.yaml, args.nodes);
}

Loading…
Cancel
Save