forked from public-mirrors/ConfigLib
better support for custom classes
parent
0dca3f614f
commit
0e9b474db1
@ -1,5 +1,5 @@
|
||||
name: ConfigLib
|
||||
author: Exlll
|
||||
|
||||
version: 1.1.0
|
||||
version: 1.2.0
|
||||
main: de.exlll.configlib.ConfigLib
|
@ -1,5 +1,5 @@
|
||||
name: ConfigLib
|
||||
author: Exlll
|
||||
|
||||
version: 1.1.0
|
||||
version: 1.2.0
|
||||
main: de.exlll.configlib.ConfigLib
|
@ -0,0 +1,69 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
final class CommentAdder {
|
||||
private final Comments comments;
|
||||
private StringBuilder builder;
|
||||
|
||||
CommentAdder(Comments comments) {
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
String addComments(String serializedMap) {
|
||||
builder = new StringBuilder();
|
||||
addClassComments();
|
||||
addMap(serializedMap);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private void addClassComments() {
|
||||
List<String> clsComments = comments.getClassComments();
|
||||
if (!clsComments.isEmpty()) {
|
||||
addComments(clsComments);
|
||||
builder.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
private void addComments(List<String> comments) {
|
||||
for (String comment : comments) {
|
||||
builder.append("# ");
|
||||
builder.append(comment);
|
||||
builder.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
private void addMap(String map) {
|
||||
String[] lines = map.split("\n");
|
||||
for (String line : lines) {
|
||||
addLine(line);
|
||||
}
|
||||
}
|
||||
|
||||
private void addLine(String line) {
|
||||
addLineComments(line);
|
||||
builder.append(line);
|
||||
builder.append('\n');
|
||||
}
|
||||
|
||||
private void addLineComments(String line) {
|
||||
if (!line.contains(":")) {
|
||||
return;
|
||||
}
|
||||
List<String> comments = getLineComments(line);
|
||||
addComments(comments);
|
||||
}
|
||||
|
||||
private List<String> getLineComments(String line) {
|
||||
Map<String, List<String>> entries = comments.getFieldComments();
|
||||
for (Map.Entry<String, List<String>> entry : entries.entrySet()) {
|
||||
String s = entry.getKey() + ":";
|
||||
if (line.startsWith(s)) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Scanner;
|
||||
|
||||
enum ConfigReader {
|
||||
;
|
||||
|
||||
static String read(Path path) throws IOException {
|
||||
try (Scanner scanner = new Scanner(path)) {
|
||||
scanner.useDelimiter("\\z");
|
||||
return scanner.next();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
enum ConfigWriter {
|
||||
;
|
||||
|
||||
static void write(Path path, String text) throws IOException {
|
||||
try (Writer writer = Files.newBufferedWriter(path)) {
|
||||
writer.write(text);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
enum ConfigurationFieldFilter implements Predicate<Field> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public boolean test(Field field) {
|
||||
int modifiers = field.getModifiers();
|
||||
boolean fst = Modifier.isFinal(modifiers) ||
|
||||
Modifier.isStatic(modifiers) ||
|
||||
Modifier.isTransient(modifiers);
|
||||
return !(field.isSynthetic() || fst);
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Scanner;
|
||||
|
||||
final class ConfigurationReader {
|
||||
private final Path path;
|
||||
|
||||
ConfigurationReader(Path path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
String read() throws IOException {
|
||||
try (Scanner scanner = new Scanner(path)) {
|
||||
return scanner.useDelimiter("\\z").next();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
final class ConfigurationWriter {
|
||||
private final Path configPath;
|
||||
private final Comments comments;
|
||||
private Writer writer;
|
||||
|
||||
ConfigurationWriter(Path configPath, Comments comments) {
|
||||
this.configPath = configPath;
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
void write(String dump) throws IOException {
|
||||
writer = Files.newBufferedWriter(configPath);
|
||||
|
||||
writeClassComments();
|
||||
writeDump(dump);
|
||||
|
||||
writer.close();
|
||||
}
|
||||
|
||||
private void writeClassComments() throws IOException {
|
||||
List<String> classComments = comments.getClassComments();
|
||||
if (!classComments.isEmpty()) {
|
||||
writeComments(classComments);
|
||||
writer.write('\n');
|
||||
}
|
||||
}
|
||||
|
||||
private void writeComments(List<String> comments) throws IOException {
|
||||
for (String comment : comments) {
|
||||
writer.write("# ");
|
||||
writer.write(comment);
|
||||
writer.write('\n');
|
||||
}
|
||||
}
|
||||
|
||||
private void writeDump(String dump) throws IOException {
|
||||
String[] dumpLines = dump.split("\n");
|
||||
for (String dumpLine : dumpLines) {
|
||||
writeLine(dumpLine);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeLine(String line) throws IOException {
|
||||
writeFieldComment(line);
|
||||
writer.write(line);
|
||||
writer.write('\n');
|
||||
}
|
||||
|
||||
private void writeFieldComment(String line) throws IOException {
|
||||
if (!line.contains(":")) {
|
||||
return;
|
||||
}
|
||||
Optional<List<String>> cmts = getFieldComments(line);
|
||||
if (cmts.isPresent()) {
|
||||
writeComments(cmts.get());
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<List<String>> getFieldComments(String line) {
|
||||
return comments.getCommentsByFieldNames()
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> line.startsWith(entry.getKey() + ":"))
|
||||
.map(Map.Entry::getValue)
|
||||
.findAny();
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
enum FieldFilter implements Predicate<Field> {
|
||||
INSTANCE;
|
||||
|
||||
/**
|
||||
* Tests if a field is not final, static, synthetic and transient.
|
||||
*
|
||||
* @param field Field that is tested
|
||||
* @return true if {@code field} is not final, static, synthetic or transient
|
||||
*/
|
||||
@Override
|
||||
public boolean test(Field field) {
|
||||
int mods = field.getModifiers();
|
||||
boolean fst = Modifier.isFinal(mods) ||
|
||||
Modifier.isStatic(mods) ||
|
||||
Modifier.isTransient(mods);
|
||||
return !fst && !field.isSynthetic();
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
final class FilteredFieldStreamSupplier implements Supplier<Stream<Field>> {
|
||||
private final Class<?> cls;
|
||||
private final Supplier<Stream<Field>> streamSupplier;
|
||||
|
||||
FilteredFieldStreamSupplier(Class<?> cls, Predicate<Field> fieldFilter) {
|
||||
Objects.requireNonNull(cls);
|
||||
Objects.requireNonNull(fieldFilter);
|
||||
this.cls = cls;
|
||||
Field[] fields = cls.getDeclaredFields();
|
||||
streamSupplier = () -> Arrays.stream(fields).filter(fieldFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Field> get() {
|
||||
return streamSupplier.get();
|
||||
}
|
||||
|
||||
public List<Class<?>> fieldTypes() {
|
||||
return streamSupplier.get().map(Field::getType)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<Field> toList() {
|
||||
return streamSupplier.get().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public Class<?> getSupplyingClass() {
|
||||
return cls;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
final class FilteredFields implements Iterable<Field> {
|
||||
private final List<Field> filteredFields;
|
||||
|
||||
FilteredFields(Field[] fields, Predicate<Field> filter) {
|
||||
Objects.requireNonNull(fields);
|
||||
Objects.requireNonNull(filter);
|
||||
|
||||
this.filteredFields = Arrays.stream(fields)
|
||||
.filter(filter)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
static FilteredFields of(Class<?> cls) {
|
||||
Field[] fields = cls.getDeclaredFields();
|
||||
return new FilteredFields(fields, FieldFilter.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Field> iterator() {
|
||||
return filteredFields.iterator();
|
||||
}
|
||||
}
|
@ -1,68 +1,62 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.TypeDescription;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.Constructor;
|
||||
import org.yaml.snakeyaml.nodes.Tag;
|
||||
import org.yaml.snakeyaml.constructor.BaseConstructor;
|
||||
import org.yaml.snakeyaml.parser.ParserException;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
import org.yaml.snakeyaml.resolver.Resolver;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
final class YamlSerializer {
|
||||
static final Set<Class<?>> DEFAULT_CLASSES = new HashSet<>();
|
||||
static final DumperOptions DUMPER_OPTIONS = new DumperOptions();
|
||||
private final Constructor constructor = new Constructor();
|
||||
private final Representer representer = new Representer();
|
||||
private final Yaml yaml = new Yaml(constructor, representer, DUMPER_OPTIONS);
|
||||
private final Set<Class<?>> knownClasses = new HashSet<>();
|
||||
private final Yaml yaml;
|
||||
|
||||
static {
|
||||
Class<?>[] classes = {
|
||||
Boolean.class, Long.class, Integer.class, Short.class, Byte.class,
|
||||
Double.class, Float.class, String.class, Character.class
|
||||
};
|
||||
DEFAULT_CLASSES.addAll(Arrays.asList(classes));
|
||||
|
||||
DUMPER_OPTIONS.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
DUMPER_OPTIONS.setIndent(2);
|
||||
/**
|
||||
* @param baseConstructor BaseConstructor which is used to configure the {@code Yaml} object.
|
||||
* @param representer Representer which is used to configure the {@code Yaml} object.
|
||||
* @param dumperOptions DumperOptions which is used to configure the {@code Yaml} object.
|
||||
* @param resolver Resolver which is used to configure the {@code Yaml} object.
|
||||
* @see org.yaml.snakeyaml.constructor.BaseConstructor
|
||||
* @see org.yaml.snakeyaml.representer.Representer
|
||||
* @see org.yaml.snakeyaml.DumperOptions
|
||||
* @see org.yaml.snakeyaml.resolver.Resolver
|
||||
*/
|
||||
YamlSerializer(BaseConstructor baseConstructor,
|
||||
Representer representer,
|
||||
DumperOptions dumperOptions,
|
||||
Resolver resolver) {
|
||||
Objects.requireNonNull(baseConstructor);
|
||||
Objects.requireNonNull(representer);
|
||||
Objects.requireNonNull(dumperOptions);
|
||||
Objects.requireNonNull(resolver);
|
||||
yaml = new Yaml(baseConstructor, representer, dumperOptions, resolver);
|
||||
}
|
||||
|
||||
String serialize(Map<String, Object> mapToDump) {
|
||||
mapToDump.forEach((fieldName, fieldValue) -> addTagIfClassUnknown(fieldValue.getClass()));
|
||||
return yaml.dump(mapToDump);
|
||||
/**
|
||||
* Serializes a Map.
|
||||
*
|
||||
* @param map Map to serialize
|
||||
* @return a serialized representation of the Map
|
||||
* @throws NullPointerException if {@code map} is null.
|
||||
*/
|
||||
String serialize(Map<String, ?> map) {
|
||||
return yaml.dump(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ParserException if invalid YAML
|
||||
* @throws ClassCastException if parsed Object is not a {@code Map}
|
||||
* Deserializes a serialized Map.
|
||||
*
|
||||
* @param serializedMap a serialized YAML representation of a Map
|
||||
* @return deserialized Map
|
||||
* @throws ClassCastException if {@code serializedMap} doesn't represent a Map
|
||||
* @throws NullPointerException if {@code serializedMap} is null
|
||||
* @throws ParserException if {@code serializedMap} is invalid YAML
|
||||
*/
|
||||
Map<String, Object> deserialize(String stringToLoad) {
|
||||
Map<String, Object> deserialize(String serializedMap) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> map = (Map<String, Object>) yaml.load(stringToLoad);
|
||||
Map<String, Object> map = (Map<String, Object>) yaml.load(serializedMap);
|
||||
return map;
|
||||
}
|
||||
|
||||
void addTagIfClassUnknown(Class<?> valueClass) {
|
||||
if (!isKnown(valueClass)) {
|
||||
knownClasses.add(valueClass);
|
||||
Tag tag = new Tag("!" + valueClass.getSimpleName());
|
||||
constructor.addTypeDescription(new TypeDescription(valueClass, tag));
|
||||
representer.addClassTag(valueClass, tag);
|
||||
}
|
||||
}
|
||||
|
||||
boolean isDefaultInstance(Class<?> c) {
|
||||
return Set.class.isAssignableFrom(c) || Map.class.isAssignableFrom(c) ||
|
||||
List.class.isAssignableFrom(c);
|
||||
}
|
||||
|
||||
boolean isDefaultClass(Class<?> c) {
|
||||
return DEFAULT_CLASSES.contains(c);
|
||||
}
|
||||
|
||||
boolean isKnown(Class<?> cls) {
|
||||
return knownClasses.contains(cls) || isDefaultClass(cls) || isDefaultInstance(cls);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class CommentAdderTest {
|
||||
@Test
|
||||
public void adderAddsComments() throws Exception {
|
||||
String originalText = "i: 0\n" +
|
||||
"j: 0\n" +
|
||||
"k: 0\n";
|
||||
String commentedText = "# a\n" +
|
||||
"# b\n\n" +
|
||||
"# c\n" +
|
||||
"i: 0\n" +
|
||||
"# d\n" +
|
||||
"# e\n" +
|
||||
"j: 0\n" +
|
||||
"k: 0\n";
|
||||
Comments comments = new Comments(CommentsTest.TestClass.class);
|
||||
CommentAdder adder = new CommentAdder(comments);
|
||||
assertThat(adder.addComments(originalText), is(commentedText));
|
||||
}
|
||||
}
|
@ -1,88 +1,31 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import com.google.common.jimfs.Jimfs;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class CommentsTest {
|
||||
@Rule
|
||||
public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
private static final FileSystem fs = Jimfs.newFileSystem();
|
||||
private static final Predicate<Field> TRUE = x -> true;
|
||||
|
||||
@Test
|
||||
public void factoryRequiresNonNullSupplier() throws Exception {
|
||||
exception.expect(NullPointerException.class);
|
||||
Comments.from(null);
|
||||
@Comment({"a", "b"})
|
||||
public static final class TestClass {
|
||||
@Comment("c")
|
||||
private int i;
|
||||
@Comment({"d", "e"})
|
||||
private int j;
|
||||
private int k;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void factoryReturnsNotNull() throws Exception {
|
||||
Comments comments = Comments.from(new FilteredFieldStreamSupplier(
|
||||
getClass(), TRUE));
|
||||
assertThat(comments, notNullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void factoryReturnsCommentsWithClassComments() throws Exception {
|
||||
Comments comments = Comments.from(new FilteredFieldStreamSupplier(
|
||||
TestClassWithComment.class, TRUE));
|
||||
|
||||
List<String> classComments = Collections.singletonList("This is a class comment.");
|
||||
assertThat(comments.getClassComments(), is(classComments));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void factoryReturnsCommentsWithFilteredFieldComments() throws Exception {
|
||||
Comments comments = Comments.from(new FilteredFieldStreamSupplier(
|
||||
TestClass.class, TRUE));
|
||||
|
||||
/* Fields which don't have a Comment annotation are filtered out. */
|
||||
Map<String, List<String>> commentsByFieldName = new HashMap<>();
|
||||
commentsByFieldName.put("field1", Collections.singletonList("Field1"));
|
||||
commentsByFieldName.put("field2", Arrays.asList("Field2", "field2"));
|
||||
|
||||
assertThat(comments.getCommentsByFieldNames(), is(commentsByFieldName));
|
||||
}
|
||||
public void getCommentsReturnsComments() throws Exception {
|
||||
Comments comments = new Comments(TestClass.class);
|
||||
|
||||
@Test
|
||||
public void getCommentsReturnsEmptyListIfNotCommentsPresent() throws Exception {
|
||||
List<String> comments = Comments.getComments(TestClassWithoutComment.class);
|
||||
|
||||
assertThat(comments, is(Collections.emptyList()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCommentsReturnsCommentsAsList() throws Exception {
|
||||
List<String> comments = Comments.getComments(TestClassWithComment.class);
|
||||
|
||||
assertThat(comments, is(Collections.singletonList("This is a class comment.")));
|
||||
}
|
||||
|
||||
|
||||
@Comment("This is a class comment.")
|
||||
private static final class TestClassWithComment {
|
||||
}
|
||||
|
||||
private static final class TestClassWithoutComment {
|
||||
}
|
||||
assertThat(comments.getClassComments(), is(Arrays.asList("a", "b")));
|
||||
|
||||
private static final class TestClass {
|
||||
@Comment("Field1")
|
||||
private int field1;
|
||||
@Comment({"Field2", "field2"})
|
||||
private int field2;
|
||||
private int field3;
|
||||
assertThat(comments.getFieldComments().get("i"), is(Collections.singletonList("c")));
|
||||
assertThat(comments.getFieldComments().get("j"), is(Arrays.asList("d", "e")));
|
||||
assertThat(comments.getFieldComments().get("k"), nullValue());
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import com.google.common.jimfs.Jimfs;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class ConfigReadWriteTest {
|
||||
|
||||
@Test
|
||||
public void readWrite() throws Exception {
|
||||
FileSystem fs = Jimfs.newFileSystem();
|
||||
Path p = fs.getPath("/path/p");
|
||||
Files.createDirectories(p.getParent());
|
||||
|
||||
String text = "Hello\nWorld\n";
|
||||
ConfigWriter.write(p, text);
|
||||
|
||||
String read = ConfigReader.read(p);
|
||||
assertThat(read, is(text));
|
||||
|
||||
fs.close();
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class ConfigurationFieldFilterTest {
|
||||
private static final Supplier<Stream<Field>> streamSupplier = new FilteredFieldStreamSupplier(
|
||||
TestClass.class, ConfigurationFieldFilter.INSTANCE);
|
||||
private Stream<Field> fieldSupplier;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
fieldSupplier = streamSupplier.get();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterFiltersSyntheticFields() throws Exception {
|
||||
Supplier<Stream<Field>> streamSupplier = new FilteredFieldStreamSupplier(
|
||||
TestClassSynthetic.class, ConfigurationFieldFilter.INSTANCE);
|
||||
|
||||
streamSupplier.get().forEach(field -> assertThat(field.isSynthetic(), is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterFiltersFinalFields() throws Exception {
|
||||
fieldSupplier.forEach(field -> assertThat(
|
||||
Modifier.isFinal(field.getModifiers()), is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterFiltersStaticFields() throws Exception {
|
||||
fieldSupplier.forEach(field -> assertThat(
|
||||
Modifier.isStatic(field.getModifiers()), is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterFiltersTransientFields() throws Exception {
|
||||
fieldSupplier.forEach(field -> assertThat(
|
||||
Modifier.isTransient(field.getModifiers()), is(false)));
|
||||
}
|
||||
|
||||
private static final class TestClass {
|
||||
/* filtered fields */
|
||||
private static int a;
|
||||
private final int b = 1;
|
||||
private transient int c;
|
||||
|
||||
/* not filtered fields */
|
||||
private int d;
|
||||
protected int e;
|
||||
int f;
|
||||
public int g;
|
||||
double h;
|
||||
volatile int i;
|
||||
}
|
||||
|
||||
private final class TestClassSynthetic {
|
||||
int a;
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import com.google.common.jimfs.Jimfs;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class ConfigurationReaderTest {
|
||||
private static final FileSystem fs = Jimfs.newFileSystem();
|
||||
private ConfigurationReader reader;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
Path configPath = fs.getPath("/config.yml");
|
||||
Writer writer = Files.newBufferedWriter(configPath);
|
||||
writer.write(TestConfiguration.CONFIG_AS_STRING);
|
||||
writer.close();
|
||||
reader = new ConfigurationReader(configPath);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readFileReadsFile() throws Exception {
|
||||
assertThat(reader.read(), is(TestConfiguration.CONFIG_AS_STRING));
|
||||
}
|
||||
}
|
@ -1,137 +1,49 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import com.google.common.jimfs.Jimfs;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class ConfigurationTest {
|
||||
@Rule
|
||||
public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
private static final FileSystem fs = Jimfs.newFileSystem();
|
||||
private Path filePath;
|
||||
private FileSystem fileSystem;
|
||||
private Path configPath;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
filePath = fs.getPath("/dir1/dir2/file1");
|
||||
Files.deleteIfExists(filePath);
|
||||
Files.deleteIfExists(filePath.getParent());
|
||||
fileSystem = Jimfs.newFileSystem();
|
||||
configPath = fileSystem.getPath("/a/b/config.yml");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorRequiresNonNullPath() throws Exception {
|
||||
exception.expect(NullPointerException.class);
|
||||
new Configuration(null) {
|
||||
};
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
fileSystem.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveCreatesParentDirectories() throws Exception {
|
||||
Path dirPath = filePath.getParent();
|
||||
|
||||
assertThat(Files.notExists(dirPath), is(true));
|
||||
|
||||
new Configuration(filePath) {
|
||||
}.save();
|
||||
|
||||
assertThat(Files.exists(dirPath), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveDoesntThrowExceptionIfDirectoryAlreadyCreated() throws Exception {
|
||||
Configuration configuration = new Configuration(filePath) {
|
||||
};
|
||||
configuration.save();
|
||||
configuration.save();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void save() throws Exception {
|
||||
new TestConfiguration(filePath).save();
|
||||
|
||||
String config = new ConfigurationReader(filePath).read();
|
||||
|
||||
assertThat(config, is(TestConfiguration.CONFIG_AS_STRING));
|
||||
TestConfiguration cfg = new TestConfiguration(configPath);
|
||||
assertThat(Files.exists(configPath.getParent()), is(false));
|
||||
|
||||
cfg.save();
|
||||
assertThat(Files.exists(configPath.getParent()), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void load() throws Exception {
|
||||
new OriginalTestClass(filePath).save();
|
||||
ChangedTestClass cls = new ChangedTestClass(filePath);
|
||||
cls.loadAndSave();
|
||||
|
||||
assertThat(cls.a, is(0));
|
||||
assertThat(cls.b, is(1));
|
||||
assertThat(cls.c, is(4));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadAndSaveSavesFile() throws Exception {
|
||||
new OriginalTestClass(filePath).loadAndSave();
|
||||
|
||||
assertThat(Files.exists(filePath), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postLoadHookExecutedAfterLoad() throws Exception {
|
||||
HookTestClass cls = new HookTestClass(filePath);
|
||||
cls.save();
|
||||
assertThat(cls.hookCalled, is(false));
|
||||
cls.load();
|
||||
assertThat(cls.hookCalled, is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postLoadHookExecutedAfterLoadAndSaveIfPathNotExists() throws Exception {
|
||||
HookTestClass cls = new HookTestClass(filePath);
|
||||
assertThat(cls.hookCalled, is(false));
|
||||
cls.loadAndSave();
|
||||
assertThat(cls.hookCalled, is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postLoadHookExecutedAfterLoadAndSaveIfPathExists() throws Exception {
|
||||
HookTestClass cls = new HookTestClass(filePath);
|
||||
cls.save();
|
||||
assertThat(cls.hookCalled, is(false));
|
||||
cls.loadAndSave();
|
||||
assertThat(cls.hookCalled, is(true));
|
||||
}
|
||||
|
||||
private static final class HookTestClass extends Configuration {
|
||||
private transient boolean hookCalled;
|
||||
|
||||
public HookTestClass(Path configPath) {
|
||||
super(configPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postLoadHook() {
|
||||
hookCalled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class OriginalTestClass extends Configuration {
|
||||
private int a = 0;
|
||||
private int b = 1;
|
||||
|
||||
public OriginalTestClass(Path configPath) {super(configPath);}
|
||||
}
|
||||
|
||||
private static final class ChangedTestClass extends Configuration {
|
||||
private int a = 2;
|
||||
private int b = 3;
|
||||
private int c = 4;
|
||||
public void saveWritesConfig() throws Exception {
|
||||
TestConfiguration cfg = new TestConfiguration(configPath);
|
||||
assertThat(Files.exists(configPath), is(false));
|
||||
|
||||
public ChangedTestClass(Path configPath) {super(configPath);}
|
||||
cfg.save();
|
||||
assertThat(Files.exists(configPath), is(true));
|
||||
assertThat(ConfigReader.read(configPath), is(TestConfiguration.CONFIG_AS_TEXT));
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import com.google.common.jimfs.Jimfs;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class ConfigurationWriterTest {
|
||||
private static final FileSystem fs = Jimfs.newFileSystem();
|
||||
private Path configPath;
|
||||
private ConfigurationWriter writer;
|
||||
private String dump;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
configPath = fs.getPath("/config.yml");
|
||||
FilteredFieldStreamSupplier streamSupplier = new FilteredFieldStreamSupplier(
|
||||
TestConfiguration.class, ConfigurationFieldFilter.INSTANCE);
|
||||
Comments comments = Comments.from(streamSupplier);
|
||||
FieldMapper mapper = new FieldMapper(streamSupplier);
|
||||
Map<String, Object> valuesByFieldNames = mapper.mapFieldNamesToValues(
|
||||
new TestConfiguration(configPath));
|
||||
dump = new YamlSerializer().serialize(valuesByFieldNames);
|
||||
writer = new ConfigurationWriter(configPath, comments);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void write() throws Exception {
|
||||
writer.write(dump);
|
||||
String read = new ConfigurationReader(configPath).read();
|
||||
|
||||
assertThat(read, is(TestConfiguration.CONFIG_AS_STRING));
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class FieldFilterTest {
|
||||
|
||||
@Test
|
||||
public void filterTestsFields() throws Exception {
|
||||
Predicate<Field> test = FieldFilter.INSTANCE;
|
||||
Class<?> cls = TestClass.class;
|
||||
|
||||
assertThat(cls.getDeclaredFields().length, is(9));
|
||||
|
||||
assertThat(test.test(cls.getDeclaredField("a")), is(false));
|
||||
assertThat(test.test(cls.getDeclaredField("b")), is(false));
|
||||
assertThat(test.test(cls.getDeclaredField("c")), is(false));
|
||||
assertThat(test.test(cls.getDeclaredField("d")), is(true));
|
||||
assertThat(test.test(cls.getDeclaredField("e")), is(true));
|
||||
assertThat(test.test(cls.getDeclaredField("f")), is(true));
|
||||
assertThat(test.test(cls.getDeclaredField("g")), is(true));
|
||||
assertThat(test.test(cls.getDeclaredField("h")), is(true));
|
||||
assertThat(test.test(cls.getDeclaredField("i")), is(true));
|
||||
|
||||
cls = TestClassSynthetic.class;
|
||||
assertThat(test.test(cls.getDeclaredField("a")), is(true));
|
||||
assertThat(test.test(cls.getDeclaredField("this$0")), is(false));
|
||||
}
|
||||
|
||||
private static final class TestClass {
|
||||
/* filtered fields */
|
||||
private static int a;
|
||||
private final int b = 1;
|
||||
private transient int c;
|
||||
|
||||
/* not filtered fields */
|
||||
private int d;
|
||||
protected int e;
|
||||
int f;
|
||||
public int g;
|
||||
double h;
|
||||
volatile int i;
|
||||
}
|
||||
|
||||
private final class TestClassSynthetic {
|
||||
int a;
|
||||
}
|
||||
}
|
@ -1,61 +1,133 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class FieldMapperTest {
|
||||
@Rule
|
||||
public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
private static final FilteredFieldStreamSupplier streamSupplier =
|
||||
new FilteredFieldStreamSupplier(TestClass.class, x -> true);
|
||||
private static final FieldMapper mapper = new FieldMapper(streamSupplier);
|
||||
@Test
|
||||
public void instanceTopMapCreatesMap() throws Exception {
|
||||
TestClass t = new TestClass();
|
||||
Map<String, Object> map = FieldMapper.instanceToMap(t);
|
||||
|
||||
assertThat(map.get("i"), is(1));
|
||||
assertThat(map.get("i"), instanceOf(Integer.class));
|
||||
|
||||
assertThat(map.get("z"), is(0));
|
||||
assertThat(map.get("z"), instanceOf(Integer.class));
|
||||
|
||||
assertThat(map.get("d"), is(2.0));
|
||||
assertThat(map.get("d"), instanceOf(Double.class));
|
||||
|
||||
assertThat(map.get("s"), is("s"));
|
||||
assertThat(map.get("s"), instanceOf(String.class));
|
||||
|
||||
assertThat(map.get("c"), is('c'));
|
||||
assertThat(map.get("c"), instanceOf(Character.class));
|
||||
|
||||
assertThat(map.get("strings"), is(Arrays.asList("1", "2")));
|
||||
assertThat(map.get("strings"), instanceOf(List.class));
|
||||
|
||||
Map<String, Integer> intMap = new HashMap<>();
|
||||
intMap.put("a", 1);
|
||||
intMap.put("b", 2);
|
||||
assertThat(map.get("objects"), is(intMap));
|
||||
assertThat(map.get("objects"), instanceOf(Map.class));
|
||||
|
||||
Map<String, Object> bMap = new HashMap<>();
|
||||
bMap.put("j", -1);
|
||||
bMap.put("t", "t");
|
||||
assertThat(map.get("b"), is(bMap));
|
||||
assertThat(map.get("b"), instanceOf(Map.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorRequiresNonNullSupplier() throws Exception {
|
||||
exception.expect(NullPointerException.class);
|
||||
new FieldMapper(null);
|
||||
public void instanceFromMapKeepsDefaultValues() throws Exception {
|
||||
TestClass t = new TestClass();
|
||||
FieldMapper.instanceFromMap(t, new HashMap<>());
|
||||
assertThat(t.z, is(0));
|
||||
assertThat(t.i, is(1));
|
||||
assertThat(t.s, is("s"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mapFieldNamesToValues() throws Exception {
|
||||
TestClass testClass = new TestClass();
|
||||
Map<String, Object> valuesByFieldNames = new LinkedHashMap<>();
|
||||
public void instanceFromMapSetsValues() throws Exception {
|
||||
TestClass t = new TestClass();
|
||||
|
||||
valuesByFieldNames.put("field1", "field1");
|
||||
valuesByFieldNames.put("field2", 2);
|
||||
valuesByFieldNames.put("field3", "field3");
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("z", 2);
|
||||
map.put("i", 10);
|
||||
map.put("c", 'q');
|
||||
map.put("s", "t");
|
||||
map.put("strings", Arrays.asList("99", "100", "101"));
|
||||
|
||||
assertThat(valuesByFieldNames, is(mapper.mapFieldNamesToValues(testClass)));
|
||||
Map<String, Object> objects = new HashMap<>();
|
||||
objects.put("a", 100);
|
||||
objects.put("b", 200);
|
||||
objects.put("c", 300);
|
||||
objects.put("d", 400);
|
||||
map.put("objects", objects);
|
||||
|
||||
Map<String, Object> bMap = new HashMap<>();
|
||||
bMap.put("j", 20);
|
||||
bMap.put("t", "v");
|
||||
map.put("b", bMap);
|
||||
|
||||
|
||||
FieldMapper.instanceFromMap(t, map);
|
||||
assertThat(t.z, is(2));
|
||||
assertThat(t.i, is(10));
|
||||
assertThat(t.c, is('q'));
|
||||
assertThat(t.s, is("t"));
|
||||
assertThat(t.strings, is(Arrays.asList("99", "100", "101")));
|
||||
assertThat(t.objects, is(objects));
|
||||
assertThat(t.b.j, is(20));
|
||||
assertThat(t.b.t, is("v"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mapValuesToFields() throws Exception {
|
||||
Map<String, Object> valuesByFieldNames = new HashMap<>();
|
||||
valuesByFieldNames.put("field1", "new");
|
||||
valuesByFieldNames.put("field2", 10);
|
||||
public void getValueGetsValue() throws Exception {
|
||||
TestClass testClass = new TestClass();
|
||||
|
||||
Field s = TestClass.class.getDeclaredField("s");
|
||||
assertThat(FieldMapper.getValue(s, testClass), is("s"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setValueSetsValue() throws Exception {
|
||||
TestClass testClass = new TestClass();
|
||||
mapper.mapValuesToFields(valuesByFieldNames, testClass);
|
||||
|
||||
assertThat(testClass.field1, is("new"));
|
||||
assertThat(testClass.field2, is(10));
|
||||
assertThat(testClass.field3, is("field3"));
|
||||
Field s = TestClass.class.getDeclaredField("s");
|
||||
FieldMapper.setValue(s, testClass, "t");
|
||||
assertThat(testClass.s, is("t"));
|
||||
}
|
||||
|
||||
private static final class TestClass {
|
||||
@Comment("Comment1")
|
||||
private String field1 = "field1";
|
||||
@Comment({"Comment2", "Comment3"})
|
||||
private int field2 = 2;
|
||||
private String field3 = "field3";
|
||||
private int z;
|
||||
private int i = 1;
|
||||
private double d = 2.0;
|
||||
private String s = "s";
|
||||
private List<String> strings = Arrays.asList("1", "2");
|
||||
private Map<String, Object> objects = new HashMap<>();
|
||||
private char c = 'c';
|
||||
private TestClassB b = new TestClassB();
|
||||
|
||||
public TestClass() {
|
||||
objects.put("a", 1);
|
||||
objects.put("b", 2);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class TestClassB {
|
||||
private int j = -1;
|
||||
private String t = "t";
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class FilteredFieldStreamSupplierTest {
|
||||
@Rule
|
||||
public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void constructorRequiresNonNullPredicate() throws Exception {
|
||||
exception.expect(NullPointerException.class);
|
||||
new FilteredFieldStreamSupplier(getClass(), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorRequiresNonNullClass() throws Exception {
|
||||
exception.expect(NullPointerException.class);
|
||||
new FilteredFieldStreamSupplier(null, field -> true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supplierReturnsStream() throws Exception {
|
||||
Supplier<Stream<Field>> supplier = new FilteredFieldStreamSupplier(
|
||||
getClass(), field -> true);
|
||||
|
||||
Stream<Field> fieldStream = supplier.get();
|
||||
|
||||
assertThat(fieldStream, is(notNullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supplierApplysFilter() throws Exception {
|
||||
Supplier<Stream<Field>> supplier = new FilteredFieldStreamSupplier(
|
||||
TestClass.class, field -> !Modifier.isPublic(field.getModifiers()));
|
||||
|
||||
Stream<Field> fieldStream = supplier.get();
|
||||
|
||||
assertThat(fieldStream.count(), is(3L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toListReturnsFieldsAsList() throws Exception {
|
||||
FilteredFieldStreamSupplier supplier = new FilteredFieldStreamSupplier(
|
||||
TestClass.class, field -> true);
|
||||
|
||||
List<Field> fields = supplier.toList();
|
||||
|
||||
assertThat(fields.get(0), is(TestClass.class.getDeclaredField("i")));
|
||||
assertThat(fields.get(1), is(TestClass.class.getDeclaredField("j")));
|
||||
assertThat(fields.get(2), is(TestClass.class.getDeclaredField("k")));
|
||||
assertThat(fields.get(3), is(TestClass.class.getDeclaredField("l")));
|
||||
}
|
||||
|
||||
private static final class TestClass {
|
||||
public int i;
|
||||
protected int j;
|
||||
int k;
|
||||
private int l;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class FilteredFieldsTest {
|
||||
@Rule
|
||||
public ExpectedException expectedException = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void constructorRequiresNonNullArray() throws Exception {
|
||||
expectedException.expect(NullPointerException.class);
|
||||
new FilteredFields(null, field -> true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorRequiresNonNullPredicate() throws Exception {
|
||||
expectedException.expect(NullPointerException.class);
|
||||
new FilteredFields(FilteredFields.class.getDeclaredFields(), null);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorAppliesFilter() throws Exception {
|
||||
FilteredFields ff = new FilteredFields(
|
||||
TestClass.class.getDeclaredFields(), field -> {
|
||||
int mods = field.getModifiers();
|
||||
return Modifier.isPublic(mods);
|
||||
});
|
||||
|
||||
for (Field f : ff) {
|
||||
int mods = f.getModifiers();
|
||||
assertThat(Modifier.isPublic(mods), is(true));
|
||||
}
|
||||
}
|
||||
|
||||
private static final class TestClass {
|
||||
private int a;
|
||||
protected int b;
|
||||
int c;
|
||||
public int d;
|
||||
}
|
||||
|
||||
}
|
@ -1,119 +1,110 @@
|
||||
package de.exlll.configlib;
|
||||
|
||||
import com.google.common.jimfs.Jimfs;
|
||||
import de.exlll.configlib.configs.CustomConfiguration;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.yaml.snakeyaml.parser.ParserException;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.constructor.Constructor;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
import org.yaml.snakeyaml.resolver.Resolver;
|
||||
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.hasItem;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class YamlSerializerTest {
|
||||
@Rule
|
||||
public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void deserializeRequiresValidYaml() throws Exception {
|
||||
exception.expect(ParserException.class);
|
||||
new YamlSerializer().deserialize("{a");
|
||||
public ExpectedException expectedException = ExpectedException.none();
|
||||
private DumperOptions dumperOptions;
|
||||
private Map<String, Object> map;
|
||||
private String serializedMap;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
dumperOptions = new DumperOptions();
|
||||
dumperOptions.setIndent(2);
|
||||
dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
|
||||
map = new HashMap<>();
|
||||
map.put("1", 1);
|
||||
map.put("2", 2.2);
|
||||
map.put("3", "3");
|
||||
map.put("4", new ArrayList<>());
|
||||
map.put("5", Arrays.asList("5", "5", "5"));
|
||||
map.put("6", new HashMap<>());
|
||||
|
||||
Map<String, Object> subMap = new HashMap<>();
|
||||
subMap.put("1", 1);
|
||||
subMap.put("2", 2.2);
|
||||
subMap.put("3", "3");
|
||||
subMap.put("4", new ArrayList<>());
|
||||
subMap.put("5", Arrays.asList("5", "5", "5"));
|
||||
subMap.put("6", new HashMap<>());
|
||||
|
||||
map.put("7", subMap);
|
||||
|
||||
serializedMap = "'1': 1\n" +
|
||||
"'2': 2.2\n" +
|
||||
"'3': '3'\n" +
|
||||
"'4': []\n" +
|
||||
"'5':\n" +
|
||||
"- '5'\n" +
|
||||
"- '5'\n" +
|
||||
"- '5'\n" +
|
||||
"'6': {}\n" +
|
||||
"'7':\n" +
|
||||
" '1': 1\n" +
|
||||
" '2': 2.2\n" +
|
||||
" '3': '3'\n" +
|
||||
" '4': []\n" +
|
||||
" '5':\n" +
|
||||
" - '5'\n" +
|
||||
" - '5'\n" +
|
||||
" - '5'\n" +
|
||||
" '6': {}\n";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deserializeReturnsMaps() throws Exception {
|
||||
Map<String, Object> actual = new YamlSerializer()
|
||||
.deserialize("a: 1\nb: c");
|
||||
|
||||
Map<String, Object> expected = new HashMap<>();
|
||||
expected.put("a", 1);
|
||||
expected.put("b", "c");
|
||||
|
||||
assertThat(actual, is(expected));
|
||||
public void constructorRequiresNonNullBaseConstructor() throws Exception {
|
||||
expectedException.expect(NullPointerException.class);
|
||||
new YamlSerializer(null, new Representer(), new DumperOptions(), new Resolver());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isDefaultClassReturnsOnlyTrueForDefaultClasses() throws Exception {
|
||||
Class<?>[] classes = {
|
||||
Boolean.class, Long.class, Integer.class, Short.class, Byte.class,
|
||||
Double.class, Float.class, String.class, Character.class
|
||||
};
|
||||
|
||||
assertThat(YamlSerializer.DEFAULT_CLASSES.size(), is(9));
|
||||
|
||||
YamlSerializer serializer = new YamlSerializer();
|
||||
for (Class<?> cls : classes) {
|
||||
assertThat(serializer.isDefaultClass(cls), is(true));
|
||||
}
|
||||
public void constructorRequiresNonNullRepresenter() throws Exception {
|
||||
expectedException.expect(NullPointerException.class);
|
||||
new YamlSerializer(new Constructor(), new Representer(), null, new Resolver());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isDefaultInstanceChecksDefaultInstances() throws Exception {
|
||||
YamlSerializer serializer = new YamlSerializer();
|
||||
|
||||
assertThat(serializer.isDefaultInstance(HashMap.class), is(true));
|
||||
assertThat(serializer.isDefaultInstance(HashSet.class), is(true));
|
||||
assertThat(serializer.isDefaultInstance(ArrayList.class), is(true));
|
||||
assertThat(serializer.isDefaultInstance(Object.class), is(false));
|
||||
public void constructorRequiresNonNullDumperOptions() throws Exception {
|
||||
expectedException.expect(NullPointerException.class);
|
||||
new YamlSerializer(new Constructor(), null, new DumperOptions(), new Resolver());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tagAddedIfUnknown() throws Exception {
|
||||
YamlSerializer serializer = new YamlSerializer();
|
||||
Class<?> unknown = Unknown.class;
|
||||
|
||||
assertThat(serializer.isKnown(unknown), is(false));
|
||||
serializer.addTagIfClassUnknown(unknown);
|
||||
assertThat(serializer.isKnown(unknown), is(true));
|
||||
public void constructorRequiresNonNullResolver() throws Exception {
|
||||
expectedException.expect(NullPointerException.class);
|
||||
new YamlSerializer(new Constructor(), new Representer(), new DumperOptions(), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serializeAddsUnknownTags() throws Exception {
|
||||
YamlSerializer serializer = new YamlSerializer();
|
||||
Class<?> unknown = Unknown.class;
|
||||
assertThat(serializer.isKnown(unknown), is(false));
|
||||
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
serializer.serialize(map);
|
||||
assertThat(serializer.isKnown(unknown), is(false));
|
||||
|
||||
map.put("", new Unknown());
|
||||
serializer.serialize(map);
|
||||
assertThat(serializer.isKnown(unknown), is(true));
|
||||
public void serialize() throws Exception {
|
||||
String s = new YamlSerializer(
|
||||
new Constructor(), new Representer(), dumperOptions, new Resolver()
|
||||
).serialize(map);
|
||||
assertThat(s, is(serializedMap));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serializeSerializesCustomObjects() throws Exception {
|
||||
try (FileSystem system = Jimfs.newFileSystem()) {
|
||||
Path path = system.getPath("/a");
|
||||
|
||||
CustomConfiguration saveConfig = new CustomConfiguration(path);
|
||||
// cs1
|
||||
saveConfig.getCs1().getMap().put("NEW KEY", Collections.singletonList("NEW VALUE"));
|
||||
saveConfig.getCs1().getO1().setS1("NEW VALUE 1");
|
||||
// cs2
|
||||
saveConfig.getCs2().getO2().setS2("NEW VALUE 2");
|
||||
saveConfig.getCs2().setI1(Integer.MAX_VALUE);
|
||||
// config
|
||||
saveConfig.setConfig("NEW CONFIG");
|
||||
saveConfig.save();
|
||||
|
||||
CustomConfiguration loadConfig = new CustomConfiguration(path);
|
||||
loadConfig.load();
|
||||
|
||||
assertThat(loadConfig.getCs1().getMap().get("NEW KEY"), hasItem("NEW VALUE"));
|
||||
assertThat(loadConfig.getCs1().getO1().getS1(), is("NEW VALUE 1"));
|
||||
assertThat(loadConfig.getCs2().getO2().getS2(), is("NEW VALUE 2"));
|
||||
assertThat(loadConfig.getCs2().getI1(), is(Integer.MAX_VALUE));
|
||||
assertThat(loadConfig.getConfig(), is("NEW CONFIG"));
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Unknown {
|
||||
public void deserialize() throws Exception {
|
||||
assertThat(new YamlSerializer(
|
||||
new Constructor(), new Representer(), dumperOptions, new Resolver()
|
||||
).deserialize(serializedMap), is(map));
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package de.exlll.configlib.configs;
|
||||
|
||||
import de.exlll.configlib.Configuration;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class CustomConfiguration extends Configuration {
|
||||
private String config = "config1";
|
||||
private CustomSection cs1 = new CustomSection();
|
||||
private CustomSection cs2 = new CustomSection();
|
||||
|
||||
public CustomConfiguration(Path configPath) {
|
||||
super(configPath);
|
||||
}
|
||||
|
||||
public String getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public void setConfig(String config1) {
|
||||
this.config = config1;
|
||||
}
|
||||
|
||||
public CustomSection getCs1() {
|
||||
return cs1;
|
||||
}
|
||||
|
||||
public void setCs1(CustomSection cs1) {
|
||||
this.cs1 = cs1;
|
||||
}
|
||||
|
||||
public CustomSection getCs2() {
|
||||
return cs2;
|
||||
}
|
||||
|
||||
public void setCs2(CustomSection cs2) {
|
||||
this.cs2 = cs2;
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package de.exlll.configlib.configs;
|
||||
|
||||
public class CustomObject {
|
||||
private String s1 = "s1";
|
||||
private String s2 = "s2";
|
||||
|
||||
public String getS1() {
|
||||
return s1;
|
||||
}
|
||||
|
||||
public void setS1(String s1) {
|
||||
this.s1 = s1;
|
||||
}
|
||||
|
||||
public String getS2() {
|
||||
return s2;
|
||||
}
|
||||
|
||||
public void setS2(String s2) {
|
||||
this.s2 = s2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CustomObject{" +
|
||||
"s1='" + s1 + '\'' +
|
||||
", s2='" + s2 + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
package de.exlll.configlib.configs;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CustomSection {
|
||||
private Map<String, List<String>> map = new HashMap<>();
|
||||
private String s1 = "s1";
|
||||
private int i1 = 1;
|
||||
private CustomObject o1 = new CustomObject();
|
||||
private CustomObject o2 = new CustomObject();
|
||||
|
||||
public CustomSection() {
|
||||
map.put("xa", Arrays.asList("x1", "x2"));
|
||||
map.put("ya", Arrays.asList("y1", "y2"));
|
||||
map.put("za", Arrays.asList("z1", "z2"));
|
||||
}
|
||||
|
||||
public Map<String, List<String>> getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
public void setMap(Map<String, List<String>> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public String getS1() {
|
||||
return s1;
|
||||
}
|
||||
|
||||
public void setS1(String s1) {
|
||||
this.s1 = s1;
|
||||
}
|
||||
|
||||
public int getI1() {
|
||||
return i1;
|
||||
}
|
||||
|
||||
public void setI1(int i1) {
|
||||
this.i1 = i1;
|
||||
}
|
||||
|
||||
public CustomObject getO1() {
|
||||
return o1;
|
||||
}
|
||||
|
||||
public void setO1(CustomObject o1) {
|
||||
this.o1 = o1;
|
||||
}
|
||||
|
||||
public CustomObject getO2() {
|
||||
return o2;
|
||||
}
|
||||
|
||||
public void setO2(CustomObject o2) {
|
||||
this.o2 = o2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CustomSection{" +
|
||||
"map=" + map +
|
||||
", s1='" + s1 + '\'' +
|
||||
", i1=" + i1 +
|
||||
", o1=" + o1 +
|
||||
", o2=" + o2 +
|
||||
'}';
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue