Merge remote-tracking branch 'origin/master'

This commit is contained in:
GaLi 2025-08-10 17:33:34 +08:00
commit bcae5ffca6
5 changed files with 0 additions and 1232 deletions

View File

@ -1,104 +0,0 @@
package com.extendedae_plus.command;
import com.extendedae_plus.test.PatternUploadUtilTestRunner;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
/**
* 测试样板上传工具的游戏内命令
* 使用方法: /extendedae_plus test_pattern_upload
*/
public class TestPatternUploadCommand {
/**
* 注册命令
*/
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
dispatcher.register(
Commands.literal("extendedae_plus")
.then(Commands.literal("test_pattern_upload")
.requires(source -> source.hasPermission(2)) // 需要OP权限
.executes(TestPatternUploadCommand::executeTest)
)
.then(Commands.literal("test_offline")
.requires(source -> source.hasPermission(2))
.executes(TestPatternUploadCommand::executeOfflineTest)
)
);
}
/**
* 执行游戏内测试
*/
private static int executeTest(CommandContext<CommandSourceStack> context) {
CommandSourceStack source = context.getSource();
try {
if (source.getEntity() instanceof ServerPlayer player) {
source.sendSuccess(() -> Component.literal("开始测试 ExtendedAEPatternUploadUtil..."), true);
// 在单独的线程中运行测试避免阻塞游戏
new Thread(() -> {
try {
PatternUploadUtilTestRunner.runInGameTest(player);
// 测试完成后发送消息
player.getServer().execute(() -> {
source.sendSuccess(() -> Component.literal("ExtendedAEPatternUploadUtil 测试完成!查看控制台获取详细结果。"), true);
});
} catch (Exception e) {
player.getServer().execute(() -> {
source.sendFailure(Component.literal("测试过程中发生异常: " + e.getMessage()));
});
}
}).start();
return 1;
} else {
source.sendFailure(Component.literal("此命令只能由玩家执行"));
return 0;
}
} catch (Exception e) {
source.sendFailure(Component.literal("命令执行失败: " + e.getMessage()));
return 0;
}
}
/**
* 执行离线测试
*/
private static int executeOfflineTest(CommandContext<CommandSourceStack> context) {
CommandSourceStack source = context.getSource();
try {
source.sendSuccess(() -> Component.literal("开始离线测试 ExtendedAEPatternUploadUtil..."), true);
// 在单独的线程中运行离线测试
new Thread(() -> {
try {
PatternUploadUtilTestRunner.runOfflineTest();
// 测试完成后发送消息
source.getServer().execute(() -> {
source.sendSuccess(() -> Component.literal("ExtendedAEPatternUploadUtil 离线测试完成!查看控制台获取详细结果。"), true);
});
} catch (Exception e) {
source.getServer().execute(() -> {
source.sendFailure(Component.literal("离线测试过程中发生异常: " + e.getMessage()));
});
}
}).start();
return 1;
} catch (Exception e) {
source.sendFailure(Component.literal("命令执行失败: " + e.getMessage()));
return 0;
}
}
}

View File

@ -1,453 +0,0 @@
package com.extendedae_plus.test;
import com.extendedae_plus.util.ExtendedAEPatternUploadUtil;
import appeng.api.inventories.InternalInventory;
import appeng.api.crafting.PatternDetailsHelper;
import appeng.helpers.patternprovider.PatternContainer;
import appeng.menu.implementations.PatternAccessTermMenu;
import com.glodblock.github.extendedae.container.ContainerExPatternTerminal;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.AbstractContainerMenu;
import java.util.ArrayList;
import java.util.List;
/**
* ExtendedAEPatternUploadUtil 测试类
* 用于验证样板上传工具的各项功能
*/
public class ExtendedAEPatternUploadUtilTest {
// 测试结果记录
private static final List<TestResult> testResults = new ArrayList<>();
/**
* 运行所有测试
*/
public static void runAllTests() {
System.out.println("=== ExtendedAEPatternUploadUtil 功能测试开始 ===");
// 清空之前的测试结果
testResults.clear();
// 运行各项测试
testGetPatternAccessMenu();
testIsExtendedAETerminal();
testUploadPatternToProvider();
testUploadMultiplePatterns();
testHasEnoughSlots();
testGetAvailableSlots();
testGetProviderDisplayName();
testIsProviderAvailable();
testGetTerminalTypeDescription();
// 输出测试结果
printTestResults();
System.out.println("=== ExtendedAEPatternUploadUtil 功能测试完成 ===");
}
/**
* 测试获取样板访问终端菜单
*/
private static void testGetPatternAccessMenu() {
System.out.println("\n[测试] getPatternAccessMenu()");
try {
// 测试1: 空玩家
TestResult result1 = new TestResult("getPatternAccessMenu - null player");
try {
PatternAccessTermMenu menu = ExtendedAEPatternUploadUtil.getPatternAccessMenu(null);
result1.success = (menu == null);
result1.message = "空玩家测试: " + (result1.success ? "通过" : "失败");
} catch (Exception e) {
result1.success = false;
result1.message = "空玩家测试异常: " + e.getMessage();
}
testResults.add(result1);
// 测试2: 模拟玩家但无容器菜单
TestResult result2 = new TestResult("getPatternAccessMenu - no container");
try {
MockServerPlayer mockPlayer = new MockServerPlayer();
mockPlayer.containerMenu = null;
PatternAccessTermMenu menu = ExtendedAEPatternUploadUtil.getPatternAccessMenu(mockPlayer);
result2.success = (menu == null);
result2.message = "无容器菜单测试: " + (result2.success ? "通过" : "失败");
} catch (Exception e) {
result2.success = false;
result2.message = "无容器菜单测试异常: " + e.getMessage();
}
testResults.add(result2);
// 测试3: 模拟ExtendedAE终端
TestResult result3 = new TestResult("getPatternAccessMenu - ExtendedAE terminal");
try {
MockServerPlayer mockPlayer = new MockServerPlayer();
mockPlayer.containerMenu = new MockContainerExPatternTerminal();
PatternAccessTermMenu menu = ExtendedAEPatternUploadUtil.getPatternAccessMenu(mockPlayer);
result3.success = (menu != null && menu instanceof ContainerExPatternTerminal);
result3.message = "ExtendedAE终端测试: " + (result3.success ? "通过" : "失败");
} catch (Exception e) {
result3.success = false;
result3.message = "ExtendedAE终端测试异常: " + e.getMessage();
}
testResults.add(result3);
System.out.println("getPatternAccessMenu() 测试完成");
} catch (Exception e) {
TestResult errorResult = new TestResult("getPatternAccessMenu - 总体测试");
errorResult.success = false;
errorResult.message = "测试过程中发生异常: " + e.getMessage();
testResults.add(errorResult);
}
}
/**
* 测试ExtendedAE终端检测
*/
private static void testIsExtendedAETerminal() {
System.out.println("\n[测试] isExtendedAETerminal()");
try {
// 测试1: ExtendedAE终端
TestResult result1 = new TestResult("isExtendedAETerminal - ExtendedAE");
try {
MockServerPlayer mockPlayer = new MockServerPlayer();
mockPlayer.containerMenu = new MockContainerExPatternTerminal();
boolean isExtended = ExtendedAEPatternUploadUtil.isExtendedAETerminal(mockPlayer);
result1.success = isExtended;
result1.message = "ExtendedAE终端检测: " + (result1.success ? "通过" : "失败");
} catch (Exception e) {
result1.success = false;
result1.message = "ExtendedAE终端检测异常: " + e.getMessage();
}
testResults.add(result1);
// 测试2: 原版AE2终端
TestResult result2 = new TestResult("isExtendedAETerminal - vanilla AE2");
try {
MockServerPlayer mockPlayer = new MockServerPlayer();
mockPlayer.containerMenu = new MockPatternAccessTermMenu();
boolean isExtended = ExtendedAEPatternUploadUtil.isExtendedAETerminal(mockPlayer);
result2.success = !isExtended;
result2.message = "原版AE2终端检测: " + (result2.success ? "通过" : "失败");
} catch (Exception e) {
result2.success = false;
result2.message = "原版AE2终端检测异常: " + e.getMessage();
}
testResults.add(result2);
System.out.println("isExtendedAETerminal() 测试完成");
} catch (Exception e) {
TestResult errorResult = new TestResult("isExtendedAETerminal - 总体测试");
errorResult.success = false;
errorResult.message = "测试过程中发生异常: " + e.getMessage();
testResults.add(errorResult);
}
}
/**
* 测试样板上传功能
*/
private static void testUploadPatternToProvider() {
System.out.println("\n[测试] uploadPatternToProvider()");
TestResult result = new TestResult("uploadPatternToProvider");
try {
// 创建模拟环境
MockServerPlayer mockPlayer = new MockServerPlayer();
mockPlayer.containerMenu = new MockContainerExPatternTerminal();
// 模拟背包中有物品
ItemStack testItem = new ItemStack(Items.PAPER); // 使用纸张作为测试物品
mockPlayer.getInventory().setItem(0, testItem);
// 测试上传由于依赖真实的AE2环境这里主要测试参数验证
boolean uploadResult = ExtendedAEPatternUploadUtil.uploadPatternToProvider(mockPlayer, 0, 1L);
// 由于缺少真实的样板和网络环境预期会失败但不应该崩溃
result.success = true; // 只要没有异常就算成功
result.message = "样板上传测试: 参数验证通过,无异常抛出";
} catch (Exception e) {
result.success = false;
result.message = "样板上传测试异常: " + e.getMessage();
}
testResults.add(result);
System.out.println("uploadPatternToProvider() 测试完成");
}
/**
* 测试批量上传功能
*/
private static void testUploadMultiplePatterns() {
System.out.println("\n[测试] uploadMultiplePatterns()");
TestResult result = new TestResult("uploadMultiplePatterns");
try {
MockServerPlayer mockPlayer = new MockServerPlayer();
mockPlayer.containerMenu = new MockContainerExPatternTerminal();
int[] slotIndices = {0, 1, 2};
int uploadCount = ExtendedAEPatternUploadUtil.uploadMultiplePatterns(mockPlayer, slotIndices, 1L);
result.success = true; // 只要没有异常就算成功
result.message = "批量上传测试: 参数验证通过,返回结果: " + uploadCount;
} catch (Exception e) {
result.success = false;
result.message = "批量上传测试异常: " + e.getMessage();
}
testResults.add(result);
System.out.println("uploadMultiplePatterns() 测试完成");
}
/**
* 测试槽位检查功能
*/
private static void testHasEnoughSlots() {
System.out.println("\n[测试] hasEnoughSlots()");
TestResult result = new TestResult("hasEnoughSlots");
try {
MockPatternAccessTermMenu mockMenu = new MockPatternAccessTermMenu();
boolean hasSlots = ExtendedAEPatternUploadUtil.hasEnoughSlots(1L, mockMenu, 5);
result.success = true; // 只要没有异常就算成功
result.message = "槽位检查测试: 参数验证通过,结果: " + hasSlots;
} catch (Exception e) {
result.success = false;
result.message = "槽位检查测试异常: " + e.getMessage();
}
testResults.add(result);
System.out.println("hasEnoughSlots() 测试完成");
}
/**
* 测试获取可用槽位数量
*/
private static void testGetAvailableSlots() {
System.out.println("\n[测试] getAvailableSlots()");
TestResult result = new TestResult("getAvailableSlots");
try {
MockPatternAccessTermMenu mockMenu = new MockPatternAccessTermMenu();
int availableSlots = ExtendedAEPatternUploadUtil.getAvailableSlots(1L, mockMenu);
result.success = true; // 只要没有异常就算成功
result.message = "获取可用槽位测试: 参数验证通过,结果: " + availableSlots;
} catch (Exception e) {
result.success = false;
result.message = "获取可用槽位测试异常: " + e.getMessage();
}
testResults.add(result);
System.out.println("getAvailableSlots() 测试完成");
}
/**
* 测试获取供应器显示名称
*/
private static void testGetProviderDisplayName() {
System.out.println("\n[测试] getProviderDisplayName()");
TestResult result = new TestResult("getProviderDisplayName");
try {
MockPatternAccessTermMenu mockMenu = new MockPatternAccessTermMenu();
String displayName = ExtendedAEPatternUploadUtil.getProviderDisplayName(1L, mockMenu);
result.success = (displayName != null && !displayName.isEmpty());
result.message = "获取显示名称测试: " + (result.success ? "通过" : "失败") + ",结果: " + displayName;
} catch (Exception e) {
result.success = false;
result.message = "获取显示名称测试异常: " + e.getMessage();
}
testResults.add(result);
System.out.println("getProviderDisplayName() 测试完成");
}
/**
* 测试供应器可用性检查
*/
private static void testIsProviderAvailable() {
System.out.println("\n[测试] isProviderAvailable()");
TestResult result = new TestResult("isProviderAvailable");
try {
MockPatternAccessTermMenu mockMenu = new MockPatternAccessTermMenu();
boolean isAvailable = ExtendedAEPatternUploadUtil.isProviderAvailable(1L, mockMenu);
result.success = true; // 只要没有异常就算成功
result.message = "供应器可用性测试: 参数验证通过,结果: " + isAvailable;
} catch (Exception e) {
result.success = false;
result.message = "供应器可用性测试异常: " + e.getMessage();
}
testResults.add(result);
System.out.println("isProviderAvailable() 测试完成");
}
/**
* 测试获取终端类型描述
*/
private static void testGetTerminalTypeDescription() {
System.out.println("\n[测试] getTerminalTypeDescription()");
try {
// 测试ExtendedAE终端
TestResult result1 = new TestResult("getTerminalTypeDescription - ExtendedAE");
try {
MockServerPlayer mockPlayer = new MockServerPlayer();
mockPlayer.containerMenu = new MockContainerExPatternTerminal();
String description = ExtendedAEPatternUploadUtil.getTerminalTypeDescription(mockPlayer);
result1.success = description.contains("ExtendedAE");
result1.message = "ExtendedAE终端描述: " + description;
} catch (Exception e) {
result1.success = false;
result1.message = "ExtendedAE终端描述异常: " + e.getMessage();
}
testResults.add(result1);
// 测试原版AE2终端
TestResult result2 = new TestResult("getTerminalTypeDescription - AE2");
try {
MockServerPlayer mockPlayer = new MockServerPlayer();
mockPlayer.containerMenu = new MockPatternAccessTermMenu();
String description = ExtendedAEPatternUploadUtil.getTerminalTypeDescription(mockPlayer);
result2.success = description.contains("AE2");
result2.message = "AE2终端描述: " + description;
} catch (Exception e) {
result2.success = false;
result2.message = "AE2终端描述异常: " + e.getMessage();
}
testResults.add(result2);
System.out.println("getTerminalTypeDescription() 测试完成");
} catch (Exception e) {
TestResult errorResult = new TestResult("getTerminalTypeDescription - 总体测试");
errorResult.success = false;
errorResult.message = "测试过程中发生异常: " + e.getMessage();
testResults.add(errorResult);
}
}
/**
* 打印测试结果
*/
private static void printTestResults() {
System.out.println("\n=== 测试结果汇总 ===");
int totalTests = testResults.size();
int passedTests = 0;
int failedTests = 0;
for (TestResult result : testResults) {
String status = result.success ? "✅ 通过" : "❌ 失败";
System.out.println(String.format("%-40s %s - %s", result.testName, status, result.message));
if (result.success) {
passedTests++;
} else {
failedTests++;
}
}
System.out.println("\n=== 统计信息 ===");
System.out.println("总测试数: " + totalTests);
System.out.println("通过: " + passedTests);
System.out.println("失败: " + failedTests);
System.out.println("通过率: " + String.format("%.1f%%", (double) passedTests / totalTests * 100));
if (failedTests == 0) {
System.out.println("🎉 所有测试通过!");
} else {
System.out.println("⚠️ 有 " + failedTests + " 个测试失败,请检查相关功能");
}
}
/**
* 测试结果记录类
*/
private static class TestResult {
String testName;
boolean success;
String message;
TestResult(String testName) {
this.testName = testName;
this.success = false;
this.message = "";
}
}
/**
* 模拟ServerPlayer类
*/
private static class MockServerPlayer extends ServerPlayer {
public AbstractContainerMenu containerMenu;
private Inventory inventory;
public MockServerPlayer() {
super(null, null, null);
this.inventory = new Inventory(null);
}
@Override
public Inventory getInventory() {
return inventory;
}
@Override
public void sendSystemMessage(Component message) {
// 模拟发送消息实际测试中不输出
System.out.println("[模拟消息] " + message.getString());
}
}
/**
* 模拟ExtendedAE样板终端类
*/
private static class MockContainerExPatternTerminal extends ContainerExPatternTerminal {
public MockContainerExPatternTerminal() {
super(-1, null, null);
}
@Override
public boolean stillValid(net.minecraft.world.entity.player.Player player) {
return true;
}
}
/**
* 模拟PatternAccessTermMenu类
*/
private static class MockPatternAccessTermMenu extends PatternAccessTermMenu {
public MockPatternAccessTermMenu() {
super(-1, null, null);
}
}
/**
* 主测试入口
*/
public static void main(String[] args) {
runAllTests();
}
}

View File

@ -1,297 +0,0 @@
package com.extendedae_plus.test;
import com.extendedae_plus.util.ExtendedAEPatternUploadUtil;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import java.util.ArrayList;
import java.util.List;
/**
* ExtendedAEPatternUploadUtil 简化测试运行器
* 专注于测试核心逻辑和边界情况
*/
public class PatternUploadUtilTestRunner {
private static final List<String> testResults = new ArrayList<>();
private static int passedTests = 0;
private static int totalTests = 0;
/**
* 运行所有可行的测试
*/
public static void runTests(ServerPlayer player) {
System.out.println("=== ExtendedAEPatternUploadUtil 测试开始 ===");
System.out.println("注意: 某些测试需要真实的游戏环境才能完全验证");
testResults.clear();
passedTests = 0;
totalTests = 0;
// 基础功能测试
testNullSafety();
testTerminalTypeDetection(player);
testUtilityMethods(player);
testParameterValidation();
// 打印结果
printResults();
System.out.println("=== ExtendedAEPatternUploadUtil 测试完成 ===");
}
/**
* 测试空值安全性
*/
private static void testNullSafety() {
System.out.println("\n[测试组] 空值安全性测试");
// 测试1: getPatternAccessMenu with null
runTest("getPatternAccessMenu(null)", () -> {
try {
var result = ExtendedAEPatternUploadUtil.getPatternAccessMenu(null);
return result == null; // 应该返回null而不是抛异常
} catch (Exception e) {
return false;
}
});
// 测试2: isExtendedAETerminal with null
runTest("isExtendedAETerminal(null)", () -> {
try {
var result = ExtendedAEPatternUploadUtil.isExtendedAETerminal(null);
return !result; // 应该返回false而不是抛异常
} catch (Exception e) {
return false;
}
});
// 测试3: getTerminalTypeDescription with null
runTest("getTerminalTypeDescription(null)", () -> {
try {
var result = ExtendedAEPatternUploadUtil.getTerminalTypeDescription(null);
return result != null && result.contains("未知");
} catch (Exception e) {
return false;
}
});
}
/**
* 测试终端类型检测
*/
private static void testTerminalTypeDetection(ServerPlayer player) {
System.out.println("\n[测试组] 终端类型检测测试");
if (player == null) {
addTestResult("终端类型检测", false, "需要真实玩家对象");
return;
}
// 测试当前终端类型检测
runTest("当前终端类型检测", () -> {
try {
boolean isExtended = ExtendedAEPatternUploadUtil.isExtendedAETerminal(player);
String description = ExtendedAEPatternUploadUtil.getTerminalTypeDescription(player);
var menu = ExtendedAEPatternUploadUtil.getPatternAccessMenu(player);
System.out.println(" - 是否ExtendedAE终端: " + isExtended);
System.out.println(" - 终端类型描述: " + description);
System.out.println(" - 获取到的菜单: " + (menu != null ? menu.getClass().getSimpleName() : "null"));
return true; // 只要不抛异常就算通过
} catch (Exception e) {
System.out.println(" - 异常: " + e.getMessage());
return false;
}
});
}
/**
* 测试工具方法
*/
private static void testUtilityMethods(ServerPlayer player) {
System.out.println("\n[测试组] 工具方法测试");
if (player == null) {
addTestResult("工具方法测试", false, "需要真实玩家对象");
return;
}
// 测试获取样板访问菜单
runTest("获取样板访问菜单", () -> {
try {
var menu = ExtendedAEPatternUploadUtil.getPatternAccessMenu(player);
System.out.println(" - 菜单类型: " + (menu != null ? menu.getClass().getSimpleName() : "无菜单"));
return true;
} catch (Exception e) {
System.out.println(" - 异常: " + e.getMessage());
return false;
}
});
// 测试供应器显示名称使用模拟ID
runTest("获取供应器显示名称", () -> {
try {
var menu = ExtendedAEPatternUploadUtil.getPatternAccessMenu(player);
if (menu != null) {
String displayName = ExtendedAEPatternUploadUtil.getProviderDisplayName(1L, menu);
System.out.println(" - 显示名称: " + displayName);
return displayName != null && !displayName.isEmpty();
} else {
System.out.println(" - 跳过: 无可用菜单");
return true;
}
} catch (Exception e) {
System.out.println(" - 异常: " + e.getMessage());
return false;
}
});
// 测试供应器可用性检查
runTest("检查供应器可用性", () -> {
try {
var menu = ExtendedAEPatternUploadUtil.getPatternAccessMenu(player);
if (menu != null) {
boolean isAvailable = ExtendedAEPatternUploadUtil.isProviderAvailable(1L, menu);
System.out.println(" - 供应器可用性: " + isAvailable);
return true;
} else {
System.out.println(" - 跳过: 无可用菜单");
return true;
}
} catch (Exception e) {
System.out.println(" - 异常: " + e.getMessage());
return false;
}
});
}
/**
* 测试参数验证
*/
private static void testParameterValidation() {
System.out.println("\n[测试组] 参数验证测试");
// 测试无效槽位索引
runTest("无效槽位索引处理", () -> {
try {
// 这些调用应该优雅地处理无效参数
boolean result1 = ExtendedAEPatternUploadUtil.uploadPatternToProvider(null, -1, 1L);
boolean result2 = ExtendedAEPatternUploadUtil.uploadPatternToProvider(null, 999, 1L);
// 预期都应该返回false而不是抛异常
return !result1 && !result2;
} catch (Exception e) {
System.out.println(" - 异常: " + e.getMessage());
return false;
}
});
// 测试无效供应器ID
runTest("无效供应器ID处理", () -> {
try {
boolean result = ExtendedAEPatternUploadUtil.uploadPatternToProvider(null, 0, -1L);
return !result; // 应该返回false
} catch (Exception e) {
System.out.println(" - 异常: " + e.getMessage());
return false;
}
});
// 测试批量上传空数组
runTest("批量上传空数组", () -> {
try {
int[] emptyArray = {};
int result = ExtendedAEPatternUploadUtil.uploadMultiplePatterns(null, emptyArray, 1L);
return result == 0; // 应该返回0
} catch (Exception e) {
System.out.println(" - 异常: " + e.getMessage());
return false;
}
});
}
/**
* 运行单个测试
*/
private static void runTest(String testName, TestFunction test) {
totalTests++;
try {
boolean passed = test.run();
if (passed) {
passedTests++;
addTestResult(testName, true, "通过");
} else {
addTestResult(testName, false, "失败");
}
} catch (Exception e) {
addTestResult(testName, false, "异常: " + e.getMessage());
}
}
/**
* 添加测试结果
*/
private static void addTestResult(String testName, boolean passed, String message) {
String status = passed ? "" : "";
String result = String.format(" %s %-30s - %s", status, testName, message);
testResults.add(result);
System.out.println(result);
}
/**
* 打印测试结果汇总
*/
private static void printResults() {
System.out.println("\n=== 测试结果汇总 ===");
double successRate = totalTests > 0 ? (double) passedTests / totalTests * 100 : 0;
System.out.println("总测试数: " + totalTests);
System.out.println("通过数: " + passedTests);
System.out.println("失败数: " + (totalTests - passedTests));
System.out.println("成功率: " + String.format("%.1f%%", successRate));
if (passedTests == totalTests) {
System.out.println("🎉 所有测试通过!");
} else {
System.out.println("⚠️ 有测试失败,请检查上述详细信息");
}
System.out.println("\n=== 使用建议 ===");
System.out.println("1. 在游戏中打开样板访问终端后运行测试以获得更完整的结果");
System.out.println("2. 确保背包中有编码样板进行上传测试");
System.out.println("3. 连接到AE2网络以测试供应器相关功能");
}
/**
* 测试函数接口
*/
@FunctionalInterface
private interface TestFunction {
boolean run() throws Exception;
}
/**
* 游戏内测试命令入口
* 可以通过命令或其他方式调用
*/
public static void runInGameTest(ServerPlayer player) {
System.out.println("开始游戏内测试...");
System.out.println("玩家: " + (player != null ? player.getName().getString() : "null"));
System.out.println("当前容器: " + (player != null && player.containerMenu != null ?
player.containerMenu.getClass().getSimpleName() : ""));
runTests(player);
}
/**
* 离线测试入口
*/
public static void runOfflineTest() {
System.out.println("开始离线测试(功能有限)...");
runTests(null);
}
}

View File

@ -1,149 +0,0 @@
# ExtendedAEPatternUploadUtil 测试指南
## 📋 测试文件说明
### 1. `ExtendedAEPatternUploadUtilTest.java`
- **完整的单元测试类**
- 包含所有功能的详细测试用例
- 使用模拟对象进行测试
- 适合开发环境中的自动化测试
### 2. `PatternUploadUtilTestRunner.java` ⭐ **推荐**
- **实用的测试运行器**
- 专注于核心功能验证
- 支持游戏内和离线测试
- 更容易编译和运行
### 3. `TestPatternUploadCommand.java`
- **游戏内测试命令**
- 通过命令直接在游戏中测试
- 需要OP权限执行
## 🚀 如何运行测试
### 方法一:游戏内命令测试(推荐)
1. **注册命令**需要在你的主mod类中添加
```java
@SubscribeEvent
public static void onServerStarting(ServerStartingEvent event) {
TestPatternUploadCommand.register(event.getServer().getCommands().getDispatcher());
}
```
2. **在游戏中执行**
```
/extendedae_plus test_pattern_upload # 完整测试(需要打开样板终端)
/extendedae_plus test_offline # 离线测试(基础功能)
```
### 方法二:直接调用测试运行器
在你的代码中任何地方调用:
```java
// 游戏内测试需要ServerPlayer对象
PatternUploadUtilTestRunner.runInGameTest(player);
// 离线测试
PatternUploadUtilTestRunner.runOfflineTest();
```
### 方法三:编译并运行完整测试
如果你想运行完整的单元测试:
```java
ExtendedAEPatternUploadUtilTest.runAllTests();
```
## 🧪 测试内容
### 基础功能测试
- ✅ 空值安全性检查
- ✅ 终端类型检测ExtendedAE vs 原版AE2
- ✅ 参数验证
- ✅ 错误处理
### 核心功能测试
- ✅ 获取样板访问终端菜单
- ✅ 样板上传功能
- ✅ 批量上传功能
- ✅ 槽位检查功能
- ✅ 供应器可用性检查
### 兼容性测试
- ✅ ExtendedAE扩展样板管理终端支持
- ✅ 原版AE2样板访问终端支持
- ✅ 反射字段访问稳定性
## 📊 测试结果解读
### 成功示例
```
✅ getPatternAccessMenu(null) - 通过
✅ 当前终端类型检测 - 通过
✅ 获取样板访问菜单 - 通过
```
### 失败示例
```
❌ uploadPatternToProvider - 失败: 背包槽位为空
❌ 供应器可用性检查 - 异常: 无法访问网络
```
## 🎯 最佳测试实践
### 1. 游戏内测试准备
- 确保连接到AE2网络
- 打开样板访问终端或ExtendedAE扩展样板管理终端
- 背包中准备一些编码样板
- 确保有可用的样板供应器
### 2. 测试环境
- **开发环境**:使用 `ExtendedAEPatternUploadUtilTest`
- **游戏测试**:使用命令 `/extendedae_plus test_pattern_upload`
- **快速验证**:使用 `PatternUploadUtilTestRunner.runOfflineTest()`
### 3. 调试建议
- 查看控制台输出获取详细信息
- 失败的测试会显示具体错误原因
- 某些功能需要真实的AE2网络环境才能完全测试
## 🔧 故障排除
### 常见问题
1. **编译错误**
- 确保所有依赖项正确导入
- 检查AE2和ExtendedAE版本兼容性
2. **运行时异常**
- 确保在正确的环境中运行测试
- 某些测试需要真实的游戏环境
3. **测试失败**
- 检查是否打开了正确的终端
- 确保网络连接正常
- 验证背包中有有效的样板
### 调试模式
在测试运行器中,所有异常都会被捕获并显示,帮助你快速定位问题。
## 📈 测试覆盖率
当前测试覆盖了以下功能:
- [x] 基础API调用100%
- [x] 错误处理100%
- [x] 参数验证100%
- [x] 终端兼容性100%
- [x] 反射访问90%
- [x] 网络交互(需要真实环境)
## 🎉 使用建议
1. **开发阶段**:使用离线测试快速验证基础逻辑
2. **集成测试**:使用游戏内命令测试完整功能
3. **发布前**:运行完整测试套件确保稳定性
---
**注意**某些高级功能如实际的样板上传需要完整的AE2网络环境才能正确测试。基础的参数验证和错误处理可以在任何环境中测试。

View File

@ -1,229 +0,0 @@
package com.extendedae_plus.test;
import com.extendedae_plus.util.ExtendedAEPatternUploadUtil;
/**
* 独立的ExtendedAEPatternUploadUtil测试类
* 避免Minecraft Bootstrap依赖专注于逻辑测试
*/
public class StandalonePatternUploadTest {
private static int totalTests = 0;
private static int passedTests = 0;
/**
* 运行所有可以独立运行的测试
*/
public static void runStandaloneTests() {
System.out.println("=== ExtendedAEPatternUploadUtil 独立测试开始 ===");
System.out.println("注意: 这些测试不需要完整的Minecraft环境");
totalTests = 0;
passedTests = 0;
// 基础逻辑测试
testNullSafety();
testParameterValidation();
testUtilityMethods();
// 输出结果
printResults();
System.out.println("=== ExtendedAEPatternUploadUtil 独立测试完成 ===");
}
/**
* 测试空值安全性
*/
private static void testNullSafety() {
System.out.println("\n[测试组] 空值安全性测试");
// 测试1: getPatternAccessMenu with null
runTest("getPatternAccessMenu(null)", () -> {
try {
var result = ExtendedAEPatternUploadUtil.getPatternAccessMenu(null);
return result == null; // 应该返回null而不是抛异常
} catch (Exception e) {
System.out.println(" 异常: " + e.getMessage());
return false;
}
});
// 测试2: isExtendedAETerminal with null
runTest("isExtendedAETerminal(null)", () -> {
try {
var result = ExtendedAEPatternUploadUtil.isExtendedAETerminal(null);
return !result; // 应该返回false而不是抛异常
} catch (Exception e) {
System.out.println(" 异常: " + e.getMessage());
return false;
}
});
// 测试3: getTerminalTypeDescription with null
runTest("getTerminalTypeDescription(null)", () -> {
try {
var result = ExtendedAEPatternUploadUtil.getTerminalTypeDescription(null);
return result != null && result.contains("未知");
} catch (Exception e) {
System.out.println(" 异常: " + e.getMessage());
return false;
}
});
}
/**
* 测试参数验证
*/
private static void testParameterValidation() {
System.out.println("\n[测试组] 参数验证测试");
// 测试无效槽位索引
runTest("无效槽位索引处理", () -> {
try {
// 这些调用应该优雅地处理无效参数
boolean result1 = ExtendedAEPatternUploadUtil.uploadPatternToProvider(null, -1, 1L);
boolean result2 = ExtendedAEPatternUploadUtil.uploadPatternToProvider(null, 999, 1L);
// 预期都应该返回false而不是抛异常
return !result1 && !result2;
} catch (Exception e) {
System.out.println(" 异常: " + e.getMessage());
return false;
}
});
// 测试无效供应器ID
runTest("无效供应器ID处理", () -> {
try {
boolean result = ExtendedAEPatternUploadUtil.uploadPatternToProvider(null, 0, -1L);
return !result; // 应该返回false
} catch (Exception e) {
System.out.println(" 异常: " + e.getMessage());
return false;
}
});
// 测试批量上传空数组
runTest("批量上传空数组", () -> {
try {
int[] emptyArray = {};
int result = ExtendedAEPatternUploadUtil.uploadMultiplePatterns(null, emptyArray, 1L);
return result == 0; // 应该返回0
} catch (Exception e) {
System.out.println(" 异常: " + e.getMessage());
return false;
}
});
}
/**
* 测试工具方法不依赖Minecraft对象的部分
*/
private static void testUtilityMethods() {
System.out.println("\n[测试组] 工具方法测试");
// 测试供应器显示名称null菜单
runTest("获取供应器显示名称(null菜单)", () -> {
try {
String displayName = ExtendedAEPatternUploadUtil.getProviderDisplayName(1L, null);
return displayName != null && !displayName.isEmpty();
} catch (Exception e) {
System.out.println(" 异常: " + e.getMessage());
return false;
}
});
// 测试供应器可用性检查null菜单
runTest("检查供应器可用性(null菜单)", () -> {
try {
boolean isAvailable = ExtendedAEPatternUploadUtil.isProviderAvailable(1L, null);
return !isAvailable; // null菜单应该返回false
} catch (Exception e) {
System.out.println(" 异常: " + e.getMessage());
return false;
}
});
// 测试获取可用槽位null菜单
runTest("获取可用槽位(null菜单)", () -> {
try {
int availableSlots = ExtendedAEPatternUploadUtil.getAvailableSlots(1L, null);
return availableSlots == -1; // null菜单应该返回-1
} catch (Exception e) {
System.out.println(" 异常: " + e.getMessage());
return false;
}
});
// 测试检查足够槽位null菜单
runTest("检查足够槽位(null菜单)", () -> {
try {
boolean hasSlots = ExtendedAEPatternUploadUtil.hasEnoughSlots(1L, null, 5);
return !hasSlots; // null菜单应该返回false
} catch (Exception e) {
System.out.println(" 异常: " + e.getMessage());
return false;
}
});
}
/**
* 运行单个测试
*/
private static void runTest(String testName, TestFunction test) {
totalTests++;
try {
boolean passed = test.run();
if (passed) {
passedTests++;
System.out.println("" + testName + " - 通过");
} else {
System.out.println("" + testName + " - 失败");
}
} catch (Exception e) {
System.out.println("" + testName + " - 异常: " + e.getMessage());
}
}
/**
* 打印测试结果
*/
private static void printResults() {
System.out.println("\n=== 测试结果汇总 ===");
double successRate = totalTests > 0 ? (double) passedTests / totalTests * 100 : 0;
System.out.println("总测试数: " + totalTests);
System.out.println("通过数: " + passedTests);
System.out.println("失败数: " + (totalTests - passedTests));
System.out.println("成功率: " + String.format("%.1f%%", successRate));
if (passedTests == totalTests) {
System.out.println("🎉 所有独立测试通过!");
} else {
System.out.println("⚠️ 有测试失败,请检查实现");
}
System.out.println("\n=== 测试说明 ===");
System.out.println("✅ 这些测试验证了基础逻辑和错误处理");
System.out.println("✅ 所有空值安全检查都已通过");
System.out.println("✅ 参数验证机制工作正常");
System.out.println(" 完整功能测试需要在游戏环境中进行");
}
/**
* 测试函数接口
*/
@FunctionalInterface
private interface TestFunction {
boolean run() throws Exception;
}
/**
* 主测试入口
*/
public static void main(String[] args) {
runStandaloneTests();
}
}