mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2025-03-01 18:21:13 +01:00
#347 Create enum property + consistency tests
This commit is contained in:
parent
204a564a9a
commit
acda03bb40
@ -0,0 +1,44 @@
|
|||||||
|
package fr.xephi.authme.settings.domain;
|
||||||
|
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum property type.
|
||||||
|
* @param <E> The enum class
|
||||||
|
*/
|
||||||
|
class EnumPropertyType<E extends Enum<E>> extends PropertyType<E> {
|
||||||
|
|
||||||
|
private Class<E> clazz;
|
||||||
|
|
||||||
|
public EnumPropertyType(Class<E> clazz) {
|
||||||
|
this.clazz = clazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E getFromFile(Property<E> property, YamlConfiguration configuration) {
|
||||||
|
String textValue = configuration.getString(property.getPath());
|
||||||
|
if (textValue == null) {
|
||||||
|
return property.getDefaultValue();
|
||||||
|
}
|
||||||
|
E mappedValue = mapToEnum(textValue);
|
||||||
|
return mappedValue != null ? mappedValue : property.getDefaultValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<String> asYaml(E value) {
|
||||||
|
return asList("'" + value + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
private E mapToEnum(String value) {
|
||||||
|
for (E entry : clazz.getEnumConstants()) {
|
||||||
|
if (entry.name().equalsIgnoreCase(value)) {
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -32,7 +32,7 @@ public class Property<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static <E extends Enum<E>> Property<E> newProperty(Class<E> clazz, String path, E defaultValue) {
|
public static <E extends Enum<E>> Property<E> newProperty(Class<E> clazz, String path, E defaultValue) {
|
||||||
return new Property<>(new PropertyType.EnumProperty<>(clazz), path, defaultValue);
|
return new Property<>(new EnumPropertyType<>(clazz), path, defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----
|
// -----
|
||||||
|
@ -143,40 +143,4 @@ public abstract class PropertyType<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Enum property.
|
|
||||||
* @param <E> The enum class
|
|
||||||
*/
|
|
||||||
static final class EnumProperty<E extends Enum<E>> extends PropertyType<E> {
|
|
||||||
private Class<E> clazz;
|
|
||||||
|
|
||||||
public EnumProperty(Class<E> clazz) {
|
|
||||||
this.clazz = clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public E getFromFile(Property<E> property, YamlConfiguration configuration) {
|
|
||||||
String textValue = configuration.getString(property.getPath());
|
|
||||||
if (textValue == null) {
|
|
||||||
return property.getDefaultValue();
|
|
||||||
}
|
|
||||||
E mappedValue = mapToEnum(textValue);
|
|
||||||
return mappedValue != null ? mappedValue : property.getDefaultValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<String> asYaml(E value) {
|
|
||||||
return asList("'" + value + "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
private E mapToEnum(String value) {
|
|
||||||
for (E entry : clazz.getEnumConstants()) {
|
|
||||||
if (entry.name().equalsIgnoreCase(value)) {
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,106 @@
|
|||||||
|
package fr.xephi.authme.settings.custom;
|
||||||
|
|
||||||
|
import fr.xephi.authme.ReflectionTestUtils;
|
||||||
|
import fr.xephi.authme.settings.domain.Property;
|
||||||
|
import fr.xephi.authme.settings.domain.SettingsClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for {@link SettingsClass} implementations.
|
||||||
|
*/
|
||||||
|
public class SettingsClassConsistencyTest {
|
||||||
|
|
||||||
|
private static final String SETTINGS_FOLDER = "src/main/java/fr/xephi/authme/settings/custom";
|
||||||
|
private static List<Class<? extends SettingsClass>> classes;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void scanForSettingsClasses() {
|
||||||
|
File settingsFolder = new File(SETTINGS_FOLDER);
|
||||||
|
File[] filesInFolder = settingsFolder.listFiles();
|
||||||
|
if (filesInFolder == null || filesInFolder.length == 0) {
|
||||||
|
throw new IllegalStateException("Could not read folder '" + SETTINGS_FOLDER + "'. Is it correct?");
|
||||||
|
}
|
||||||
|
|
||||||
|
classes = new ArrayList<>();
|
||||||
|
for (File file : filesInFolder) {
|
||||||
|
Class<? extends SettingsClass> clazz = getSettingsClassFromFile(file);
|
||||||
|
if (clazz != null) {
|
||||||
|
classes.add(clazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("Found " + classes.size() + " SettingsClass implementations");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure that all {@link Property} instances we define are in public, static, final fields.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void shouldHavePublicStaticFinalFields() {
|
||||||
|
for (Class<?> clazz : classes) {
|
||||||
|
Field[] fields = clazz.getDeclaredFields();
|
||||||
|
for (Field field : fields) {
|
||||||
|
if (Property.class.isAssignableFrom(field.getType())) {
|
||||||
|
String fieldName = "Field " + clazz.getSimpleName() + "#" + field.getName();
|
||||||
|
assertThat(fieldName + "should be public, static, and final",
|
||||||
|
isValidConstantField(field), equalTo(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure that no properties use the same path.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void shouldHaveUniquePaths() {
|
||||||
|
Set<String> paths = new HashSet<>();
|
||||||
|
for (Class<?> clazz : classes) {
|
||||||
|
Field[] fields = clazz.getDeclaredFields();
|
||||||
|
for (Field field : fields) {
|
||||||
|
if (Property.class.isAssignableFrom(field.getType())) {
|
||||||
|
Property<?> property =
|
||||||
|
(Property<?>) ReflectionTestUtils.getFieldValue(clazz, null, field.getName());
|
||||||
|
if (paths.contains(property.getPath())) {
|
||||||
|
fail("Path '" + property.getPath() + "' should be used by only one constant");
|
||||||
|
}
|
||||||
|
paths.add(property.getPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isValidConstantField(Field field) {
|
||||||
|
int modifiers = field.getModifiers();
|
||||||
|
return Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Class<? extends SettingsClass> getSettingsClassFromFile(File file) {
|
||||||
|
String fileName = file.getPath();
|
||||||
|
String className = fileName
|
||||||
|
.substring("src/main/java/".length(), fileName.length() - ".java".length())
|
||||||
|
.replace(File.separator, ".");
|
||||||
|
try {
|
||||||
|
Class<?> clazz = SettingsClassConsistencyTest.class.getClassLoader().loadClass(className);
|
||||||
|
if (SettingsClass.class.isAssignableFrom(clazz)) {
|
||||||
|
return (Class<? extends SettingsClass>) clazz;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
throw new IllegalStateException("Could not load class '" + className + "'", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
package fr.xephi.authme.settings.domain;
|
||||||
|
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.mockito.BDDMockito.given;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for {@link EnumPropertyType}.
|
||||||
|
*/
|
||||||
|
public class EnumPropertyTypeTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReturnCorrectEnumValue() {
|
||||||
|
// given
|
||||||
|
PropertyType<TestEnum> propertyType = new EnumPropertyType<>(TestEnum.class);
|
||||||
|
Property<TestEnum> property = Property.newProperty(TestEnum.class, "enum.path", TestEnum.ENTRY_C);
|
||||||
|
YamlConfiguration configuration = mock(YamlConfiguration.class);
|
||||||
|
given(configuration.getString(property.getPath())).willReturn("Entry_B");
|
||||||
|
|
||||||
|
// when
|
||||||
|
TestEnum result = propertyType.getFromFile(property, configuration);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result, equalTo(TestEnum.ENTRY_B));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldFallBackToDefaultForInvalidValue() {
|
||||||
|
// given
|
||||||
|
PropertyType<TestEnum> propertyType = new EnumPropertyType<>(TestEnum.class);
|
||||||
|
Property<TestEnum> property = Property.newProperty(TestEnum.class, "enum.path", TestEnum.ENTRY_C);
|
||||||
|
YamlConfiguration configuration = mock(YamlConfiguration.class);
|
||||||
|
given(configuration.getString(property.getPath())).willReturn("Bogus");
|
||||||
|
|
||||||
|
// when
|
||||||
|
TestEnum result = propertyType.getFromFile(property, configuration);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result, equalTo(TestEnum.ENTRY_C));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldFallBackToDefaultForNonExistentValue() {
|
||||||
|
// given
|
||||||
|
PropertyType<TestEnum> propertyType = new EnumPropertyType<>(TestEnum.class);
|
||||||
|
Property<TestEnum> property = Property.newProperty(TestEnum.class, "enum.path", TestEnum.ENTRY_C);
|
||||||
|
YamlConfiguration configuration = mock(YamlConfiguration.class);
|
||||||
|
given(configuration.getString(property.getPath())).willReturn(null);
|
||||||
|
|
||||||
|
// when
|
||||||
|
TestEnum result = propertyType.getFromFile(property, configuration);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result, equalTo(TestEnum.ENTRY_C));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private enum TestEnum {
|
||||||
|
|
||||||
|
ENTRY_A,
|
||||||
|
|
||||||
|
ENTRY_B,
|
||||||
|
|
||||||
|
ENTRY_C
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user