e284bb1215
Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: fb23cbb3 Define surefire plugin version d022084a Define ordering for MetadataStoreTest 99a7f6f0 PR-910: Match generic max absorption attribute name style with the rest c7390d71 PR-909: Update tests to JUnit 5 CraftBukkit Changes: f0661c351 PR-1230: Move unstructured PDC NBT serialisation to SNBT 452fcb599 PR-1256: Update tests to JUnit 5
235 Zeilen
10 KiB
Diff
235 Zeilen
10 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Shane Freeder <theboyetronic@gmail.com>
|
|
Date: Sun, 17 Mar 2019 23:04:30 +0000
|
|
Subject: [PATCH] Test changes
|
|
|
|
- convert to mockito for mocking of types
|
|
- Allow use of TYPE_USE annotations
|
|
- Ignore package-private methods for nullability annotations
|
|
- Add excludes for classes which don't pass
|
|
- Disable stupid BukkitMirrorTest
|
|
|
|
Co-authored-by: Riley Park <rileysebastianpark@gmail.com>
|
|
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
|
|
|
|
diff --git a/src/test/java/io/papermc/paper/testing/EmptyTag.java b/src/test/java/io/papermc/paper/testing/EmptyTag.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..77154095cfb8b259bdb318e8ff40cb6f559ebc18
|
|
--- /dev/null
|
|
+++ b/src/test/java/io/papermc/paper/testing/EmptyTag.java
|
|
@@ -0,0 +1,31 @@
|
|
+package io.papermc.paper.testing;
|
|
+
|
|
+import java.util.Collections;
|
|
+import java.util.Set;
|
|
+import org.bukkit.Keyed;
|
|
+import org.bukkit.NamespacedKey;
|
|
+import org.bukkit.Tag;
|
|
+import org.jetbrains.annotations.NotNull;
|
|
+
|
|
+public record EmptyTag(NamespacedKey key) implements Tag<Keyed> {
|
|
+
|
|
+ @SuppressWarnings("deprecation")
|
|
+ public EmptyTag() {
|
|
+ this(NamespacedKey.randomKey());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public @NotNull NamespacedKey getKey() {
|
|
+ return this.key;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isTagged(@NotNull final Keyed item) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public @NotNull Set<Keyed> getValues() {
|
|
+ return Collections.emptySet();
|
|
+ }
|
|
+}
|
|
diff --git a/src/test/java/org/bukkit/AnnotationTest.java b/src/test/java/org/bukkit/AnnotationTest.java
|
|
index 64e7aef6220097edefdff3b98a771b988365930d..abadff47166722fdc756afdbc6ac7242b6bd4fb0 100644
|
|
--- a/src/test/java/org/bukkit/AnnotationTest.java
|
|
+++ b/src/test/java/org/bukkit/AnnotationTest.java
|
|
@@ -29,7 +29,13 @@ public class AnnotationTest {
|
|
"Lorg/jetbrains/annotations/Nullable;",
|
|
"Lorg/jetbrains/annotations/NotNull;",
|
|
"Lorg/jetbrains/annotations/Contract;",
|
|
- "Lorg/bukkit/UndefinedNullability;"
|
|
+ "Lorg/bukkit/UndefinedNullability;",
|
|
+ // Paper start
|
|
+ "Lorg/checkerframework/checker/nullness/qual/MonotonicNonNull;",
|
|
+ "Lorg/checkerframework/checker/nullness/qual/NonNull;",
|
|
+ "Lorg/checkerframework/checker/nullness/qual/Nullable;",
|
|
+ "Lorg/checkerframework/checker/nullness/qual/PolyNull;",
|
|
+ // Paper end
|
|
};
|
|
|
|
private static final String[] EXCLUDED_CLASSES = {
|
|
@@ -40,7 +46,17 @@ public class AnnotationTest {
|
|
"org/bukkit/util/io/Wrapper",
|
|
"org/bukkit/plugin/java/PluginClassLoader",
|
|
// Generic functional interface
|
|
- "org/bukkit/util/Consumer"
|
|
+ "org/bukkit/util/Consumer",
|
|
+ // Paper start
|
|
+ // Timings history is broken in terms of nullability due to guavas Function defining that the param is NonNull
|
|
+ "co/aikar/timings/TimingHistory$2",
|
|
+ "co/aikar/timings/TimingHistory$2$1",
|
|
+ "co/aikar/timings/TimingHistory$2$1$1",
|
|
+ "co/aikar/timings/TimingHistory$2$1$2",
|
|
+ "co/aikar/timings/TimingHistory$3",
|
|
+ "co/aikar/timings/TimingHistory$4",
|
|
+ "co/aikar/timings/TimingHistoryEntry$1"
|
|
+ // Paper end
|
|
};
|
|
|
|
@Test
|
|
@@ -67,14 +83,40 @@ public class AnnotationTest {
|
|
}
|
|
|
|
if (mustBeAnnotated(Type.getReturnType(method.desc)) && !isWellAnnotated(method.invisibleAnnotations)) {
|
|
+ // Paper start - Allow use of TYPE_USE annotations
|
|
+ boolean warn = true;
|
|
+ if (isWellAnnotated(method.visibleTypeAnnotations)) {
|
|
+ warn = false;
|
|
+ } else if (method.invisibleTypeAnnotations != null) {
|
|
+ dance: for (final org.objectweb.asm.tree.TypeAnnotationNode invisibleTypeAnnotation : method.invisibleTypeAnnotations) {
|
|
+ final org.objectweb.asm.TypeReference ref = new org.objectweb.asm.TypeReference(invisibleTypeAnnotation.typeRef);
|
|
+ if (ref.getSort() == org.objectweb.asm.TypeReference.METHOD_RETURN && java.util.Arrays.asList(ACCEPTED_ANNOTATIONS).contains(invisibleTypeAnnotation.desc)) {
|
|
+ warn = false;
|
|
+ break dance; // cha cha real smooth
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ if (warn)
|
|
+ // Paper end
|
|
warn(errors, clazz, method, "return value");
|
|
}
|
|
|
|
Type[] paramTypes = Type.getArgumentTypes(method.desc);
|
|
List<ParameterNode> parameters = method.parameters;
|
|
|
|
+ dancing: // Paper
|
|
for (int i = 0; i < paramTypes.length; i++) {
|
|
if (mustBeAnnotated(paramTypes[i]) ^ isWellAnnotated(method.invisibleParameterAnnotations == null ? null : method.invisibleParameterAnnotations[i])) {
|
|
+ // Paper start
|
|
+ if (method.invisibleTypeAnnotations != null) {
|
|
+ for (final org.objectweb.asm.tree.TypeAnnotationNode invisibleTypeAnnotation : method.invisibleTypeAnnotations) {
|
|
+ final org.objectweb.asm.TypeReference ref = new org.objectweb.asm.TypeReference(invisibleTypeAnnotation.typeRef);
|
|
+ if (ref.getSort() == org.objectweb.asm.TypeReference.METHOD_FORMAL_PARAMETER && ref.getTypeParameterIndex() == i && java.util.Arrays.asList(ACCEPTED_ANNOTATIONS).contains(invisibleTypeAnnotation.desc)) {
|
|
+ continue dancing;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ // Paper end - Allow use of TYPE_USE annotations
|
|
ParameterNode paramNode = parameters == null ? null : parameters.get(i);
|
|
String paramName = paramNode == null ? null : paramNode.name;
|
|
|
|
@@ -91,13 +133,18 @@ public class AnnotationTest {
|
|
|
|
Collections.sort(errors);
|
|
|
|
- System.out.println(errors.size() + " missing annotation(s):");
|
|
+ StringBuilder builder = new StringBuilder()
|
|
+ .append("There ")
|
|
+ .append(errors.size() != 1 ? "are " : "is ")
|
|
+ .append(errors.size())
|
|
+ .append(" missing annotation")
|
|
+ .append(errors.size() != 1 ? "s:\n" : ":\n");
|
|
+
|
|
for (String message : errors) {
|
|
- System.out.print("\t");
|
|
- System.out.println(message);
|
|
+ builder.append("\t").append(message).append("\n");
|
|
}
|
|
|
|
- fail("There " + errors.size() + " are missing annotation(s)");
|
|
+ fail(builder.toString());
|
|
}
|
|
|
|
private static void collectClasses(@NotNull File from, @NotNull Map<String, ClassNode> to) throws IOException {
|
|
@@ -140,6 +187,11 @@ public class AnnotationTest {
|
|
// Exceptions are excluded
|
|
return false;
|
|
}
|
|
+ // Paper start
|
|
+ if (isInternal(clazz.invisibleAnnotations)) {
|
|
+ return false;
|
|
+ }
|
|
+ // Paper end
|
|
|
|
for (String excludedClass : EXCLUDED_CLASSES) {
|
|
if (excludedClass.equals(clazz.name)) {
|
|
@@ -152,7 +204,7 @@ public class AnnotationTest {
|
|
|
|
private static boolean isMethodIncluded(@NotNull ClassNode clazz, @NotNull MethodNode method, @NotNull Map<String, ClassNode> allClasses) {
|
|
// Exclude private, synthetic and deprecated methods
|
|
- if ((method.access & (Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_DEPRECATED)) != 0) {
|
|
+ if ((method.access & (Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_DEPRECATED)) != 0 || (method.access & (Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED | Opcodes.ACC_PUBLIC)) == 0) { // Paper - ignore package-private
|
|
return false;
|
|
}
|
|
|
|
@@ -170,11 +222,30 @@ public class AnnotationTest {
|
|
if ("<init>".equals(method.name) && isAnonymous(clazz)) {
|
|
return false;
|
|
}
|
|
+ // Paper start
|
|
+ if (isInternal(method.invisibleAnnotations)) {
|
|
+ return false;
|
|
+ }
|
|
+ // Paper end
|
|
|
|
return true;
|
|
}
|
|
+ // Paper start
|
|
+ private static boolean isInternal(List<? extends AnnotationNode> annotations) {
|
|
+ if (annotations == null) {
|
|
+ return false;
|
|
+ }
|
|
+ for (AnnotationNode node : annotations) {
|
|
+ if (node.desc.equals("Lorg/jetbrains/annotations/ApiStatus$Internal;")) {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+ }
|
|
+ // Paper end
|
|
|
|
- private static boolean isWellAnnotated(@Nullable List<AnnotationNode> annotations) {
|
|
+ private static boolean isWellAnnotated(@Nullable List<? extends AnnotationNode> annotations) { // Paper
|
|
if (annotations == null) {
|
|
return false;
|
|
}
|
|
diff --git a/src/test/java/org/bukkit/BukkitMirrorTest.java b/src/test/java/org/bukkit/BukkitMirrorTest.java
|
|
index 89ca06ebecdaadd5dfc7bc74473ca15ad36f6eff..a07d35a6615e788361ac4c8b8954a2876d1306b2 100644
|
|
--- a/src/test/java/org/bukkit/BukkitMirrorTest.java
|
|
+++ b/src/test/java/org/bukkit/BukkitMirrorTest.java
|
|
@@ -12,6 +12,7 @@ import org.junit.jupiter.params.provider.MethodSource;
|
|
public class BukkitMirrorTest {
|
|
|
|
public static Stream<Arguments> data() {
|
|
+ if (true) return Stream.of(); // Paper
|
|
return Stream.of(Server.class.getDeclaredMethods())
|
|
.map(method -> {
|
|
try {
|
|
diff --git a/src/test/java/org/bukkit/support/TestServer.java b/src/test/java/org/bukkit/support/TestServer.java
|
|
index 79173d6ed844f1e640e3aa745a9b560ec5e6a2bc..73ec679ac0d1f398b417bd174b47f9af93351e27 100644
|
|
--- a/src/test/java/org/bukkit/support/TestServer.java
|
|
+++ b/src/test/java/org/bukkit/support/TestServer.java
|
|
@@ -61,6 +61,11 @@ public final class TestServer {
|
|
UnsafeValues unsafeValues = mock(withSettings().stubOnly());
|
|
when(instance.getUnsafe()).thenReturn(unsafeValues);
|
|
|
|
+ // Paper start - testing changes
|
|
+ when(instance.getTag(anyString(), any(NamespacedKey.class), any())).thenAnswer(ignored -> new io.papermc.paper.testing.EmptyTag());
|
|
+ when(instance.getScoreboardCriteria(anyString())).thenReturn(null);
|
|
+ // Paper end - testing changes
|
|
+
|
|
Bukkit.setServer(instance);
|
|
}
|
|
|