From d1acb875c2505471ba982e4916b6630748418001 Mon Sep 17 00:00:00 2001 From: Exlll Date: Sun, 24 Jul 2022 21:15:17 +0200 Subject: [PATCH] Remove update with default configuration. Default values for Records can now be provided through constructors that have no parameters. --- README.md | 52 +++++----- .../configlib/ConfigurationSerializer.java | 4 +- .../configlib/FileConfigurationStore.java | 41 +++----- .../de/exlll/configlib/RecordSerializer.java | 6 +- .../main/java/de/exlll/configlib/Reflect.java | 45 +++++---- .../exlll/configlib/RecordSerializerTest.java | 18 ++++ .../java/de/exlll/configlib/ReflectTest.java | 52 ++++++---- .../configlib/YamlConfigurationStore.java | 6 +- .../exlll/configlib/YamlConfigurations.java | 37 +++---- .../configlib/YamlConfigurationStoreTest.java | 98 +++++-------------- .../configlib/YamlConfigurationsTest.java | 31 +++--- .../exlll/configlib/YamlFileWriterTest.java | 6 +- 12 files changed, 184 insertions(+), 212 deletions(-) diff --git a/README.md b/README.md index 19f1aa6..f02c5f1 100644 --- a/README.md +++ b/README.md @@ -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); ``` -
- 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: +
+ +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 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 diff --git a/configlib-core/src/main/java/de/exlll/configlib/ConfigurationSerializer.java b/configlib-core/src/main/java/de/exlll/configlib/ConfigurationSerializer.java index 6d27458..92dbbed 100644 --- a/configlib-core/src/main/java/de/exlll/configlib/ConfigurationSerializer.java +++ b/configlib-core/src/main/java/de/exlll/configlib/ConfigurationSerializer.java @@ -12,7 +12,7 @@ final class ConfigurationSerializer extends TypeSerializer 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 extends TypeSerializer { 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. + *
    + *
  • + * 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. + *
  • + *
  • + * 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 * @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); } diff --git a/configlib-core/src/main/java/de/exlll/configlib/RecordSerializer.java b/configlib-core/src/main/java/de/exlll/configlib/RecordSerializer.java index 9124b55..2a5f2ae 100644 --- a/configlib-core/src/main/java/de/exlll/configlib/RecordSerializer.java +++ b/configlib-core/src/main/java/de/exlll/configlib/RecordSerializer.java @@ -40,7 +40,7 @@ final class RecordSerializer extends } } - return Reflect.newRecord(type, constructorArguments); + return Reflect.callCanonicalConstructor(type, constructorArguments); } @Override @@ -67,7 +67,9 @@ final class RecordSerializer extends @Override R newDefaultInstance() { - return Reflect.newRecordDefaultValues(type); + return Reflect.hasDefaultConstructor(type) + ? Reflect.callNoParamConstructor(type) + : Reflect.callCanonicalConstructorWithDefaultValues(type); } private static void requireNonPrimitiveComponentType(RecordComponent component) { diff --git a/configlib-core/src/main/java/de/exlll/configlib/Reflect.java b/configlib-core/src/main/java/de/exlll/configlib/Reflect.java index 5f22836..8550661 100644 --- a/configlib-core/src/main/java/de/exlll/configlib/Reflect.java +++ b/configlib-core/src/main/java/de/exlll/configlib/Reflect.java @@ -38,33 +38,34 @@ final class Reflect { return defaultValue; } - static T newInstance(Class cls) { + static T callNoParamConstructor(Class cls) { try { Constructor 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 as a bound here and for the other methods below // but that would require casts elsewhere. - static R newRecord(Class recordType, Object... constructorArguments) { + static R callCanonicalConstructor(Class recordType, Object... constructorArguments) { try { Constructor 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 newRecordDefaultValues(Class recordType) { + static R callCanonicalConstructorWithDefaultValues(Class 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 Constructor getCanonicalConstructor(Class 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); } } diff --git a/configlib-core/src/test/java/de/exlll/configlib/RecordSerializerTest.java b/configlib-core/src/test/java/de/exlll/configlib/RecordSerializerTest.java index 1971102..2394a9d 100644 --- a/configlib-core/src/test/java/de/exlll/configlib/RecordSerializerTest.java +++ b/configlib-core/src/test/java/de/exlll/configlib/RecordSerializerTest.java @@ -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")); + } } \ No newline at end of file diff --git a/configlib-core/src/test/java/de/exlll/configlib/ReflectTest.java b/configlib-core/src/test/java/de/exlll/configlib/ReflectTest.java index 1b9c1f8..3b110b0 100644 --- a/configlib-core/src/test/java/de/exlll/configlib/ReflectTest.java +++ b/configlib-core/src/test/java/de/exlll/configlib/ReflectTest.java @@ -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)); + } } \ No newline at end of file diff --git a/configlib-yaml/src/main/java/de/exlll/configlib/YamlConfigurationStore.java b/configlib-yaml/src/main/java/de/exlll/configlib/YamlConfigurationStore.java index a53386d..c22e896 100644 --- a/configlib-yaml/src/main/java/de/exlll/configlib/YamlConfigurationStore.java +++ b/configlib-yaml/src/main/java/de/exlll/configlib/YamlConfigurationStore.java @@ -110,16 +110,12 @@ public final class YamlConfigurationStore implements FileConfigurationStore T loadConfiguration( - Path configurationFile, - Class configurationType - ) { + public static T load(Path configurationFile, Class 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 loadConfiguration( + public static T load( Path configurationFile, Class configurationType, Consumer> 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 loadConfiguration( + public static T load( Path configurationFile, Class configurationType, YamlConfigurationProperties properties @@ -86,7 +83,6 @@ public final class YamlConfigurations { * {@code YamlConfigurationProperties} object with default values. *

* 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 updateConfiguration( - Path configurationFile, - Class configurationType - ) { + public static T update(Path configurationFile, Class 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 updateConfiguration( + public static T update( Path configurationFile, Class configurationType, Consumer> 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 updateConfiguration( + public static T update( Path configurationFile, Class 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 void saveConfiguration( + public static void save( Path configurationFile, Class 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 void saveConfiguration( + public static void save( Path configurationFile, Class 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 void saveConfiguration( + public static void save( Path configurationFile, Class configurationType, T configuration, diff --git a/configlib-yaml/src/test/java/de/exlll/configlib/YamlConfigurationStoreTest.java b/configlib-yaml/src/test/java/de/exlll/configlib/YamlConfigurationStoreTest.java index 2dd0c10..bbca600 100644 --- a/configlib-yaml/src/test/java/de/exlll/configlib/YamlConfigurationStoreTest.java +++ b/configlib-yaml/src/test/java/de/exlll/configlib/YamlConfigurationStoreTest.java @@ -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 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 store = newDefaultStore(E.class); @@ -338,82 +360,6 @@ class YamlConfigurationStoreTest { assertEquals("i: 20\nj: 0", readFile(yamlFile)); } - @Test - void updateWithDefaultCreatesConfigurationFileIfItDoesNotExist() { - final YamlConfigurationStore 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 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 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 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 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 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 YamlConfigurationStore newDefaultStore(Class configType) { YamlConfigurationProperties properties = YamlConfigurationProperties.newBuilder().build(); return new YamlConfigurationStore<>(configType, properties); diff --git a/configlib-yaml/src/test/java/de/exlll/configlib/YamlConfigurationsTest.java b/configlib-yaml/src/test/java/de/exlll/configlib/YamlConfigurationsTest.java index 23e42ab..93d6a39 100644 --- a/configlib-yaml/src/test/java/de/exlll/configlib/YamlConfigurationsTest.java +++ b/configlib-yaml/src/test/java/de/exlll/configlib/YamlConfigurationsTest.java @@ -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() ); diff --git a/configlib-yaml/src/test/java/de/exlll/configlib/YamlFileWriterTest.java b/configlib-yaml/src/test/java/de/exlll/configlib/YamlFileWriterTest.java index 6435c62..75c9fcc 100644 --- a/configlib-yaml/src/test/java/de/exlll/configlib/YamlFileWriterTest.java +++ b/configlib-yaml/src/test/java/de/exlll/configlib/YamlFileWriterTest.java @@ -475,7 +475,11 @@ class YamlFileWriterTest { } void writeConfig(Class cls, Consumer> 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); }