forked from jzitnik/twodcraft
test(annotations): New @RequireAnnotation
New annotation @RequireAnnotation can be used on annotations so that all classes with that specific annotation must also have another annotation. If this is not true, test will not pass. This annotation takes array of annotations.
This commit is contained in:
parent
e1190f7e6a
commit
53a3ae43f3
5
.idea/misc.xml
generated
5
.idea/misc.xml
generated
@ -1,5 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="EntryPointsManager">
|
||||||
|
<writeAnnotations>
|
||||||
|
<writeAnnotation name="cz.jzitnik.game.annotations.AutoTransient" />
|
||||||
|
</writeAnnotations>
|
||||||
|
</component>
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="MavenProjectsManager">
|
<component name="MavenProjectsManager">
|
||||||
<option name="originalFiles">
|
<option name="originalFiles">
|
||||||
|
@ -7,6 +7,7 @@ import java.lang.annotation.ElementType;
|
|||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
|
@RequireAnnotation(BlockRegistry.class)
|
||||||
public @interface BlockDropPercentage {
|
public @interface BlockDropPercentage {
|
||||||
int value();
|
int value();
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,6 @@ import java.lang.annotation.ElementType;
|
|||||||
|
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@RequireAnnotation(BlockRegistry.class)
|
||||||
public @interface BreakableByWater {
|
public @interface BreakableByWater {
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,6 @@ import java.lang.annotation.ElementType;
|
|||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
|
@RequireAnnotation(BlockRegistry.class)
|
||||||
public @interface BreaksByPlace {
|
public @interface BreaksByPlace {
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,6 @@ import java.lang.annotation.ElementType;
|
|||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
|
@RequireAnnotation(BlockRegistry.class)
|
||||||
public @interface BreaksFalling {
|
public @interface BreaksFalling {
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import java.lang.annotation.*;
|
|||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
@Repeatable(CustomDrops.class)
|
@Repeatable(CustomDrops.class)
|
||||||
|
@RequireAnnotation(BlockRegistry.class)
|
||||||
public @interface CustomDrop {
|
public @interface CustomDrop {
|
||||||
String tool();
|
String tool();
|
||||||
String drops();
|
String drops();
|
||||||
|
@ -7,6 +7,7 @@ import java.lang.annotation.ElementType;
|
|||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
|
@RequireAnnotation(ItemRegistry.class)
|
||||||
public @interface Fuel {
|
public @interface Fuel {
|
||||||
double value();
|
double value();
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,6 @@ import java.lang.annotation.ElementType;
|
|||||||
|
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@RequireAnnotation(BlockRegistry.class)
|
||||||
public @interface PlaceOnSolid {
|
public @interface PlaceOnSolid {
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,6 @@ import java.lang.annotation.ElementType;
|
|||||||
|
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@RequireAnnotation(BlockRegistry.class)
|
||||||
public @interface PlaceOnSolidNoHandler {
|
public @interface PlaceOnSolidNoHandler {
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
package cz.jzitnik.game.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
@Target(ElementType.ANNOTATION_TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface RequireAnnotation {
|
||||||
|
Class<? extends Annotation>[] value();
|
||||||
|
}
|
@ -7,5 +7,6 @@ import java.lang.annotation.ElementType;
|
|||||||
|
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@RequireAnnotation(BlockRegistry.class)
|
||||||
public @interface ResetDataOnMine {
|
public @interface ResetDataOnMine {
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,6 @@ import java.lang.annotation.ElementType;
|
|||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
|
@RequireAnnotation(BlockRegistry.class)
|
||||||
public @interface Sapling {
|
public @interface Sapling {
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import java.lang.annotation.ElementType;
|
|||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
|
@RequireAnnotation(ItemRegistry.class)
|
||||||
public @interface Smeltable {
|
public @interface Smeltable {
|
||||||
String value();
|
String value();
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import cz.jzitnik.game.annotations.CraftingRecipeRegistry;
|
|||||||
|
|
||||||
@CraftingRecipeRegistry(
|
@CraftingRecipeRegistry(
|
||||||
recipe = {
|
recipe = {
|
||||||
"Allium", "_", "_",
|
"allium", "_", "_",
|
||||||
"_", "_", "_",
|
"_", "_", "_",
|
||||||
"_", "_", "_"
|
"_", "_", "_"
|
||||||
},
|
},
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
package cz.jzitnik.game.handlers.place;
|
package cz.jzitnik.game.handlers.place;
|
||||||
|
|
||||||
import cz.jzitnik.game.annotations.BlockDropPercentage;
|
import cz.jzitnik.game.annotations.*;
|
||||||
import cz.jzitnik.game.annotations.BlockRegistry;
|
|
||||||
import cz.jzitnik.game.annotations.PlaceOnSolid;
|
|
||||||
import cz.jzitnik.game.annotations.ResetDataOnMine;
|
|
||||||
import cz.jzitnik.game.entities.items.ItemBlockSupplier;
|
import cz.jzitnik.game.entities.items.ItemBlockSupplier;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.reflections.Reflections;
|
import org.reflections.Reflections;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@ -27,7 +25,6 @@ class PlaceHandlerTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("All blocks in annotation @PlaceHandler must exist")
|
@DisplayName("All blocks in annotation @PlaceHandler must exist")
|
||||||
void allBlocksMustExist() {
|
void allBlocksMustExist() {
|
||||||
@ -43,47 +40,55 @@ class PlaceHandlerTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
/*@Test
|
||||||
@DisplayName("All blocks annotated with @PlaceOnSolid must be also annotated with @BlockRegistry")
|
@DisplayName("All blocks must be annotated with @BlockRegistry if they are annotated with certain other annotations")
|
||||||
void placeOnSolidTest() {
|
void checkAnnotationsWithBlockRegistry() {
|
||||||
Reflections reflections = new Reflections("cz.jzitnik.game.entities.items.registry.blocks");
|
// Define annotations and their names
|
||||||
Set<Class<?>> handlerClasses = reflections
|
Object[][] annotationsToCheck = {
|
||||||
.getTypesAnnotatedWith(PlaceOnSolid.class);
|
{PlaceOnSolid.class, "@PlaceOnSolid"},
|
||||||
|
{ResetDataOnMine.class, "@ResetDataOnMine"},
|
||||||
|
{BlockDropPercentage.class, "@BlockDropPercentage"},
|
||||||
|
{BreakableByWater.class, "@BreakableByWater"},
|
||||||
|
{BreaksByPlace.class, "@BreaksByPlace"},
|
||||||
|
{BreaksFalling.class, "@BreaksFalling"},
|
||||||
|
{Fuel.class, "@Fuel"},
|
||||||
|
{Smeltable.class, "@Smeltable"},
|
||||||
|
};
|
||||||
|
|
||||||
for (Class<?> clazz : handlerClasses) {
|
// Loop through each annotation and check for @BlockRegistry
|
||||||
boolean hasAnnotation = clazz.isAnnotationPresent(BlockRegistry.class);
|
for (Object[] annotationData : annotationsToCheck) {
|
||||||
assertTrue(hasAnnotation, "Class " + clazz.getName() + " is annotated with @PlaceOnSolid but does not have annotation @BlockRegistry");
|
Class<?> annotationClass = (Class<?>) annotationData[0];
|
||||||
|
String annotationName = (String) annotationData[1];
|
||||||
|
checkBlockRegistryAnnotationForClassesWithAnnotation(annotationClass, annotationName);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void checkAnnotationValidity() {
|
||||||
|
Reflections reflections = new Reflections("cz.jzitnik.game");
|
||||||
|
|
||||||
|
Set<Class<?>> annotations = reflections.getTypesAnnotatedWith(RequireAnnotation.class);
|
||||||
|
|
||||||
|
for (Class<?> annotation : annotations) {
|
||||||
|
if (!annotation.isAnnotation()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<Class<?>> classes = reflections.getTypesAnnotatedWith((Class<? extends Annotation>) annotation);
|
||||||
|
var anot = annotation.getAnnotation(RequireAnnotation.class);
|
||||||
|
|
||||||
|
for (Class<?> clazz : classes) {
|
||||||
|
for (Class<? extends Annotation> annotationRequired : anot.value()) {
|
||||||
|
if (!clazz.isAnnotationPresent(annotationRequired)) {
|
||||||
|
fail("All classes annotated with @" + annotation.getSimpleName() + " must be also annotated with @" + annotationRequired.getSimpleName() + " but class " + clazz.getName() + " isn't.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("All blocks annotated with @ResetDataOnMine must be also annotated with @BlockRegistry")
|
@DisplayName("All blocks annotated with @ResetDataOnMine must have data class.")
|
||||||
void resetDataOnMineTest() {
|
|
||||||
Reflections reflections = new Reflections("cz.jzitnik.game.entities.items.registry.blocks");
|
|
||||||
Set<Class<?>> handlerClasses = reflections
|
|
||||||
.getTypesAnnotatedWith(ResetDataOnMine.class);
|
|
||||||
|
|
||||||
for (Class<?> clazz : handlerClasses) {
|
|
||||||
boolean hasAnnotation = clazz.isAnnotationPresent(BlockRegistry.class);
|
|
||||||
assertTrue(hasAnnotation, "Class " + clazz.getName() + " is annotated with @ResetDataOnMine but does not have annotation @BlockRegistry");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("All blocks annotated with @BlockDropPercentage must be also annotated with @BlockRegistry")
|
|
||||||
void blockDropPercentageTest() {
|
|
||||||
Reflections reflections = new Reflections("cz.jzitnik.game.entities.items.registry.blocks");
|
|
||||||
Set<Class<?>> handlerClasses = reflections
|
|
||||||
.getTypesAnnotatedWith(BlockDropPercentage.class);
|
|
||||||
|
|
||||||
for (Class<?> clazz : handlerClasses) {
|
|
||||||
boolean hasAnnotation = clazz.isAnnotationPresent(BlockRegistry.class);
|
|
||||||
assertTrue(hasAnnotation, "Class " + clazz.getName() + " is annotated with @BlockDropPercentage but does not have annotation @BlockRegistry");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("All blocks annotated with @ResetDataOnMine must have data class with default constructor")
|
|
||||||
void dataOnMineHasDataTest() {
|
void dataOnMineHasDataTest() {
|
||||||
Reflections reflections = new Reflections("cz.jzitnik.game.entities.items.registry.blocks");
|
Reflections reflections = new Reflections("cz.jzitnik.game.entities.items.registry.blocks");
|
||||||
Set<Class<?>> handlerClasses = reflections
|
Set<Class<?>> handlerClasses = reflections
|
||||||
|
Loading…
x
Reference in New Issue
Block a user