-
Notifications
You must be signed in to change notification settings - Fork 20
Description
Foreword
These days, I spend a lot of time testing the behavior of the BeanProperty.
As I read in the wiki:
ConfigMe will never return a bean in which a field is null. If it does not succeed to set a field's value, the mapping is considered to have failed and the default object is used. It is therefore important to initialize fields as shown with the country name above if you don't want the absence of one field to make ConfigMe ignore all fields and use the default bean object provided on initialization.
And
As with all other properties, bean properties never resolve to null, i.e. when you do settingsManager.getProperty(property) it is guaranteed to never return null.
But I think I broke these rules in a simple way, let me explain:
I have two bean classes called A and B, where B is used twice in A like the following code:
@Getter @Setter // lombok
public class A {
private B b1;
private B b2;
}
...
@Getter @Setter // lombok
public class B {
private boolean enabled;
private String value;
}I have defined a SettingsHolder class that has only one property:
public class ConfigHolder implements SettingsHolder {
private static final A DEF_VALUE;
static {
B b1 = new B();
b1.setEnabled(true);
b1.setValue("");
B b2 = new B();
b2.setEnabled(true);
b2.setValue("");
DEF_VALUE = new A();
DEF_VALUE.setB1(b1);
DEF_VALUE.setB2(b2);
}
public static final BeanProperty<A> TEST_PROP =
newBeanProperty(A.class, "a", DEF_VALUE);
}As you can see, the DEF_VALUE has no null references.
The tests
So, I have created the following unit test to put under pressure the BeanProperty.
@Test
void test() {
// first file load
File yamlFile = new File(tempDir.toFile(), "test.yml");
SettingsManager settingsManager =
SettingsManagerBuilder
.withYamlFile(yamlFile)
.configurationData(ConfigHolder.class)
.useDefaultMigrationService()
.create();
B b1 = new B();
b1.setEnabled(true);
b1.setValue("test1");
// I don't set B2, so the Bean will be serialized without B2.
A a = new A();
a.setB1(b1);
// At this time, ConfigMe should not save the Bean that has
// a null reference, but ok it is serialized without that null field.
settingsManager.setProperty(ConfigHolder.TEST_PROP, a);
settingsManager.save();
// Read A from the current settings manager
a = settingsManager.getProperty(ConfigHolder.TEST_PROP);
Assertions.assertNotNull(a); // Ok
Assertions.assertNotNull(a.getB1()); // Ok
Assertions.assertEquals("test1", a.getB1().getValue()); // Ok
Assertions.assertNull(a.getB2()); // Ok as I expected.
// Now try to reload the configuration by recreating the new settings manager instance.
settingsManager =
SettingsManagerBuilder
.withYamlFile(yamlFile)
.configurationData(ConfigHolder.class)
.useDefaultMigrationService()
.create();
// Read again A but this time from the new settings manager instance.
a = settingsManager.getProperty(ConfigHolder.TEST_PROP);
// What is expected: The reader won't recognize
// the Bean (A), and it will set the default value.
Assertions.assertNotNull(a); // Ok
Assertions.assertNotNull(a.getB1()); // Ok
Assertions.assertEquals("", a.getB1().getValue()); // Ok
Assertions.assertNotNull(a.getB2()); // Ok
Assertions.assertEquals("", a.getB2().getValue()); // Ok
} Considerations
So, did I lose all the data just because of a missing field? Is that correct?
Imagine a user who misses a simple detail while setting up the bean. Will he lose all the data due to that mistake? Perhaps this should be revisited.
Thanks a lot ljacqu 💯