PaperMC/patches/api/Test-changes.patch
Nassim Jahnke 358877e2e2 Updated Upstream (Bukkit/CraftBukkit)
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
2023-09-24 17:16:58 +10:00

234 lines
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..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/test/java/io/papermc/paper/testing/EmptyTag.java
@@ -0,0 +0,0 @@
+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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/test/java/org/bukkit/AnnotationTest.java
+++ b/src/test/java/org/bukkit/AnnotationTest.java
@@ -0,0 +0,0 @@ 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 = {
@@ -0,0 +0,0 @@ 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
@@ -0,0 +0,0 @@ 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;
@@ -0,0 +0,0 @@ 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 {
@@ -0,0 +0,0 @@ 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)) {
@@ -0,0 +0,0 @@ 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;
}
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/test/java/org/bukkit/BukkitMirrorTest.java
+++ b/src/test/java/org/bukkit/BukkitMirrorTest.java
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/test/java/org/bukkit/support/TestServer.java
+++ b/src/test/java/org/bukkit/support/TestServer.java
@@ -0,0 +0,0 @@ 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);
}