mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2025-07-23 23:55:33 +02:00
Merge master into endgame branch to prepare merge for beta 2.2.000 update
This commit is contained in:
@@ -1,17 +0,0 @@
|
||||
package com.gmail.nossr50;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
//TODO: Move generic test stuff here
|
||||
public class TestUtil {
|
||||
public static void recursiveDelete(@NotNull File directoryToBeDeleted) {
|
||||
if (directoryToBeDeleted.isDirectory()) {
|
||||
for (File file : directoryToBeDeleted.listFiles()) {
|
||||
recursiveDelete(file);
|
||||
}
|
||||
}
|
||||
directoryToBeDeleted.delete();
|
||||
}
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
package com.gmail.nossr50.database;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class FlatFileDataProcessorTest {
|
||||
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
@Test
|
||||
void testGetExpectedValueType() {
|
||||
for (int i = 0; i < FlatFileDatabaseManager.DATA_ENTRY_COUNT; i++) {
|
||||
FlatFileDataProcessor.getExpectedValueType(i);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
@Test
|
||||
void testGetExpectedValueTypeException() {
|
||||
Assertions.assertThrows(IndexOutOfBoundsException.class, () -> {
|
||||
for (int i = 0; i < FlatFileDatabaseManager.DATA_ENTRY_COUNT + 1; i++) {
|
||||
FlatFileDataProcessor.getExpectedValueType(i);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,856 @@
|
||||
package com.gmail.nossr50.database;
|
||||
|
||||
import com.gmail.nossr50.database.flatfile.LeaderboardStatus;
|
||||
import com.gmail.nossr50.datatypes.database.DatabaseType;
|
||||
import com.gmail.nossr50.datatypes.player.PlayerProfile;
|
||||
import com.gmail.nossr50.datatypes.player.UniqueDataType;
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
|
||||
import com.gmail.nossr50.util.skills.SkillTools;
|
||||
import com.google.common.io.Files;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Filter;
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
//This class uses JUnit5/Jupiter
|
||||
class FlatFileDatabaseManagerTest {
|
||||
|
||||
public static final @NotNull String TEST_FILE_NAME = "test.mcmmo.users";
|
||||
public static final @NotNull String BAD_FILE_LINE_ONE = "mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:";
|
||||
public static final @NotNull String BAD_DATA_FILE_LINE_TWENTY_THREE = "nossr51:baddata:::baddata:baddata:640:baddata:1000:1000:1000:baddata:baddata:baddata:baddata:16:0:500:20273:0:0:0:0::1000:0:0:baddata:1593543012:0:0:0:0::1000:0:0:baddata:IGNORED:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1:0:";
|
||||
public static final @NotNull String DB_BADDATA = "baddatadb.users";
|
||||
public static final @NotNull String DB_HEALTHY = "healthydb.users";
|
||||
public static final @NotNull String HEALTHY_DB_LINE_1 = "nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:IGNORED:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999:2020:";
|
||||
public static final @NotNull String HEALTHY_DB_LINE_ONE_UUID_STR = "588fe472-1c82-4c4e-9aa1-7eefccb277e3";
|
||||
public static final String DB_MISSING_LAST_LOGIN = "missinglastlogin.users";
|
||||
public static final String LINE_TWO_FROM_MISSING_DB = "nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:0:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999:";
|
||||
private static File tempDir;
|
||||
private final static @NotNull Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
|
||||
private final long PURGE_TIME = 2630000000L;
|
||||
private static @Nullable FlatFileDatabaseManager db;
|
||||
|
||||
//Making them all unique makes it easier on us to edit this stuff later
|
||||
int expectedLvlMining = 1, expectedLvlWoodcutting = 2, expectedLvlRepair = 3,
|
||||
expectedLvlUnarmed = 4, expectedLvlHerbalism = 5, expectedLvlExcavation = 6,
|
||||
expectedLvlArchery = 7, expectedLvlSwords = 8, expectedLvlAxes = 9, expectedLvlAcrobatics = 10,
|
||||
expectedLvlTaming = 11, expectedLvlFishing = 12, expectedLvlAlchemy = 13;
|
||||
|
||||
float expectedExpMining = 10, expectedExpWoodcutting = 20, expectedExpRepair = 30,
|
||||
expectedExpUnarmed = 40, expectedExpHerbalism = 50, expectedExpExcavation = 60,
|
||||
expectedExpArchery = 70, expectedExpSwords = 80, expectedExpAxes = 90, expectedExpAcrobatics = 100,
|
||||
expectedExpTaming = 110, expectedExpFishing = 120, expectedExpAlchemy = 130;
|
||||
|
||||
long expectedBerserkCd = 111, expectedGigaDrillBreakerCd = 222, expectedTreeFellerCd = 333,
|
||||
expectedGreenTerraCd = 444, expectedSerratedStrikesCd = 555, expectedSkullSplitterCd = 666,
|
||||
expectedSuperBreakerCd = 777, expectedBlastMiningCd = 888, expectedChimaeraWingCd = 999;
|
||||
|
||||
int expectedScoreboardTips = 1111;
|
||||
Long expectedLastLogin = 2020L;
|
||||
|
||||
@BeforeAll
|
||||
static void initBeforeAll() {
|
||||
logger.setFilter(new DebugFilter());
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void init() {
|
||||
assertNull(db);
|
||||
//noinspection UnstableApiUsage
|
||||
tempDir = Files.createTempDir();
|
||||
db = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
|
||||
}
|
||||
|
||||
private @NotNull String getTemporaryUserFilePath() {
|
||||
return tempDir.getPath() + File.separator + TEST_FILE_NAME;
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
recursiveDelete(tempDir);
|
||||
db = null;
|
||||
}
|
||||
|
||||
//Nothing wrong with this database
|
||||
private static final String[] normalDatabaseData = {
|
||||
"nossr50:1000:::0:1000:640:1000:1000:1000:1000:1000:1000:1000:1000:16:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
|
||||
"mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:",
|
||||
"powerless:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:0:HEARTS:0:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:5:1600906906:"
|
||||
};
|
||||
|
||||
private static final String[] badUUIDDatabaseData = {
|
||||
"nossr50:1000:::0:1000:640:1000:1000:1000:1000:1000:1000:1000:1000:16:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
|
||||
"z750:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:3:5:1600906906:", //This one has an incorrect UUID representation
|
||||
"powerless:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:0:HEARTS:0:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:5:1600906906:"
|
||||
};
|
||||
|
||||
private static final String[] outdatedDatabaseData = {
|
||||
"nossr50:1000:::0:1000:640:1000:1000:1000:1000:1000:1000:1000:1000:16:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
|
||||
"mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:",
|
||||
"electronicboy:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:0:HEARTS:0:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:" //This user is missing data added after UUID index
|
||||
};
|
||||
|
||||
private static final String[] emptyLineDatabaseData = {
|
||||
"nossr50:1000:::0:1000:640:1000:1000:1000:1000:1000:1000:1000:1000:16:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
|
||||
"mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:",
|
||||
"kashike:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:0:HEARTS:0:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:5:1600906906:",
|
||||
"" //EMPTY LINE
|
||||
};
|
||||
|
||||
private static final String[] emptyNameDatabaseData = {
|
||||
":1000:::0:1000:640:1000:1000:1000:1000:1000:1000:1000:1000:16:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
|
||||
"mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:",
|
||||
"aikar:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:0:HEARTS:0:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:5:1600906906:"
|
||||
};
|
||||
|
||||
private static final String[] duplicateNameDatabaseData = {
|
||||
"mochi:1000:::0:1000:640:1000:1000:1000:1000:1000:1000:1000:1000:16:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
|
||||
"mochi:1000:::0:1000:640:1000:1000:1000:1000:1000:1000:1000:1000:16:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:631e3896-da2a-4077-974b-d047859d76bc:0:0:",
|
||||
};
|
||||
|
||||
private static final String[] duplicateUUIDDatabaseData = {
|
||||
"nossr50:1000:::0:1000:640:1000:1000:1000:1000:1000:1000:1000:1000:16:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
|
||||
"mrfloris:1000:::0:1000:640:1000:1000:1000:1000:1000:1000:1000:1000:16:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
|
||||
};
|
||||
|
||||
private static final String[] corruptDatabaseData = {
|
||||
"nossr50:1000:::0:100:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
|
||||
"mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:",
|
||||
"corruptdataboy:の:::ののの0:2452:0:1983:1937:1790:3042ののののの:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617のののののの583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:d20c6e8d-5615-4284-b8d1-e20b92011530:5:1600906906:",
|
||||
"のjapaneseuserの:333:::0:2452:0:444:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:25870f0e-7558-4659-9f60-417e24cb3332:5:1600906906:",
|
||||
"sameUUIDasjapaneseuser:333:::0:442:0:544:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:25870f0e-7558-4659-9f60-417e24cb3332:5:1600906906:",
|
||||
};
|
||||
|
||||
private static final String[] badDatabaseData = {
|
||||
//First entry here is missing some values
|
||||
"nossr50:1000:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
|
||||
//Second entry here has an integer value replaced by a string
|
||||
"mrfloris:2420:::0:2452:0:1983:1937:1790:3042:badvalue:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:"
|
||||
};
|
||||
|
||||
@Test
|
||||
void testDefaultInit() {
|
||||
db = new FlatFileDatabaseManager(getTemporaryUserFilePath(), logger, PURGE_TIME, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateLeaderboards() {
|
||||
assertNotNull(db);
|
||||
assertEquals(LeaderboardStatus.UPDATED, db.updateLeaderboards());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSaveUser() {
|
||||
//Make a Profile to save and check to see if it worked
|
||||
UUID uuid = UUID.fromString("588fe472-1c82-4c4e-9aa1-7eefccb277e3");
|
||||
String playerName = "nossr50";
|
||||
PlayerProfile testProfile = new PlayerProfile(playerName, uuid, 0);
|
||||
//The above profile should be "zero" initialized
|
||||
|
||||
//Save the zero version and see if it looks correct
|
||||
assertNotNull(db);
|
||||
assertTrue(db.getUsersFile().exists()); //Users file should have been created from the above com.gmail.nossr50.database.FlatFileDatabaseManager.checkFileHealthAndStructure
|
||||
assertNotNull(db.getUsersFile());
|
||||
|
||||
//The DB is empty at this point, add our user
|
||||
assertTrue(db.saveUser(testProfile)); //True means we saved the user
|
||||
|
||||
//Check for the empty profile
|
||||
PlayerProfile retrievedFromData = db.loadPlayerProfile(uuid);
|
||||
assertTrue(retrievedFromData.isLoaded()); //PlayerProfile::isLoaded returns true if the data was created from the file, false if it wasn't found and a dummy profile was returned
|
||||
assertEquals(uuid, retrievedFromData.getUniqueId());
|
||||
assertEquals(playerName, retrievedFromData.getPlayerName());
|
||||
|
||||
/*
|
||||
* Test overwriting names with new names
|
||||
*/
|
||||
|
||||
String alteredName = "changedmyname";
|
||||
PlayerProfile changedNameProfile = new PlayerProfile(alteredName, uuid, 0);
|
||||
assertTrue(db.saveUser(changedNameProfile)); //True means we saved the user
|
||||
|
||||
retrievedFromData = db.loadPlayerProfile(uuid);
|
||||
assertTrue(retrievedFromData.isLoaded()); //PlayerProfile::isLoaded returns true if the data was created from the file, false if it wasn't found and a dummy profile was returned
|
||||
assertEquals(uuid, retrievedFromData.getUniqueId());
|
||||
assertEquals(alteredName, retrievedFromData.getPlayerName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddedMissingLastLoginValues() {
|
||||
File dbFile = prepareDatabaseTestResource(DB_MISSING_LAST_LOGIN);
|
||||
|
||||
//This makes sure our private method is working before the tests run afterwards
|
||||
ArrayList<String[]> dataFromFile = getSplitDataFromFile(dbFile);
|
||||
logger.info("File Path: "+ dbFile.getAbsolutePath());
|
||||
assertArrayEquals(LINE_TWO_FROM_MISSING_DB.split(":"), dataFromFile.get(1));
|
||||
assertEquals(dataFromFile.get(1)[FlatFileDatabaseManager.UUID_INDEX], HEALTHY_DB_LINE_ONE_UUID_STR);
|
||||
|
||||
db = new FlatFileDatabaseManager(dbFile, logger, PURGE_TIME, 0, true);
|
||||
List<FlatFileDataFlag> flagsFound = db.checkFileHealthAndStructure();
|
||||
assertNotNull(flagsFound);
|
||||
assertTrue(flagsFound.contains(FlatFileDataFlag.LAST_LOGIN_SCHEMA_UPGRADE));
|
||||
|
||||
//Check for the fixed value
|
||||
PlayerProfile profile = db.loadPlayerProfile("nossr50");
|
||||
assertEquals(-1, (long) profile.getLastLogin());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoadByName() {
|
||||
File healthyDB = prepareDatabaseTestResource(DB_HEALTHY);
|
||||
|
||||
/*
|
||||
* We have established the files are in good order, so now for the actual testing
|
||||
*/
|
||||
|
||||
//This makes sure our private method is working before the tests run afterwards
|
||||
ArrayList<String[]> dataFromFile = getSplitDataFromFile(healthyDB);
|
||||
logger.info("File Path: "+healthyDB.getAbsolutePath());
|
||||
assertArrayEquals(HEALTHY_DB_LINE_1.split(":"), dataFromFile.get(0));
|
||||
assertEquals(dataFromFile.get(0)[FlatFileDatabaseManager.UUID_INDEX], HEALTHY_DB_LINE_ONE_UUID_STR);
|
||||
UUID healthDBEntryOneUUID = UUID.fromString(HEALTHY_DB_LINE_ONE_UUID_STR);
|
||||
|
||||
db = new FlatFileDatabaseManager(healthyDB, logger, PURGE_TIME, 0, true);
|
||||
List<FlatFileDataFlag> flagsFound = db.checkFileHealthAndStructure();
|
||||
assertNull(flagsFound); //No flags should be found
|
||||
|
||||
/*
|
||||
* Once the DB looks fine load the profile
|
||||
*/
|
||||
|
||||
String playerName = "nossr50";
|
||||
UUID uuid = UUID.fromString("588fe472-1c82-4c4e-9aa1-7eefccb277e3");
|
||||
|
||||
PlayerProfile profile = db.loadPlayerProfile(playerName);
|
||||
testHealthyDataProfileValues(playerName, uuid, profile);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNewUser() {
|
||||
//We will test that new user values line up with our expectations
|
||||
UUID uuid = new UUID(0, 1);
|
||||
String playerName = "nossr50";
|
||||
|
||||
int newUserTestStartingLvl = 1337;
|
||||
db = new FlatFileDatabaseManager(new File(tempDir.getPath() + File.separator + TEST_FILE_NAME), logger, PURGE_TIME, newUserTestStartingLvl, true);
|
||||
db.checkFileHealthAndStructure();
|
||||
|
||||
PlayerProfile playerProfile = db.newUser(playerName, uuid);
|
||||
|
||||
assertTrue(playerProfile.isLoaded());
|
||||
assertEquals(playerName, playerProfile.getPlayerName());
|
||||
assertEquals(uuid, playerProfile.getUniqueId());
|
||||
|
||||
PlayerProfile retrievedFromDisk = db.loadPlayerProfile(uuid);
|
||||
assertTrue(retrievedFromDisk.isLoaded());
|
||||
assertEquals(playerName, retrievedFromDisk.getPlayerName());
|
||||
assertEquals(uuid, retrievedFromDisk.getUniqueId());
|
||||
|
||||
//Checking a new user for being "zero" initialized
|
||||
checkNewUserValues(playerProfile, newUserTestStartingLvl);
|
||||
checkNewUserValues(retrievedFromDisk, newUserTestStartingLvl);
|
||||
|
||||
//TODO: Should we do any dupe checking? Probably not needed as it would be caught on the next load
|
||||
db.newUser("disco", new UUID(3, 3));
|
||||
db.newUser("dingus", new UUID(3, 4));
|
||||
db.newUser("duped_dingus", new UUID(3, 4));
|
||||
|
||||
assertEquals(5, getSplitDataFromFile(db.getUsersFile()).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddingUsersToEndOfExistingDB() {
|
||||
//We will test that new user values line up with our expectations
|
||||
UUID uuid = new UUID(0, 80);
|
||||
String playerName = "the_kitty_man";
|
||||
|
||||
File file = prepareDatabaseTestResource(DB_HEALTHY); //Existing DB
|
||||
|
||||
int newUserTestStartingLvl = 1337;
|
||||
db = new FlatFileDatabaseManager(file, logger, PURGE_TIME, newUserTestStartingLvl, true);
|
||||
db.checkFileHealthAndStructure();
|
||||
|
||||
PlayerProfile playerProfile = db.newUser(playerName, uuid);
|
||||
|
||||
assertTrue(playerProfile.isLoaded());
|
||||
assertEquals(playerName, playerProfile.getPlayerName());
|
||||
assertEquals(uuid, playerProfile.getUniqueId());
|
||||
|
||||
PlayerProfile retrievedFromDisk = db.loadPlayerProfile(uuid);
|
||||
assertTrue(retrievedFromDisk.isLoaded());
|
||||
assertEquals(playerName, retrievedFromDisk.getPlayerName());
|
||||
assertEquals(uuid, retrievedFromDisk.getUniqueId());
|
||||
|
||||
//Checking a new user for being "zero" initialized
|
||||
checkNewUserValues(playerProfile, newUserTestStartingLvl);
|
||||
checkNewUserValues(retrievedFromDisk, newUserTestStartingLvl);
|
||||
|
||||
//TODO: Should we do any dupe checking? Probably not needed as it would be caught on the next load
|
||||
db.newUser("bidoof", new UUID(3, 3));
|
||||
db.newUser("derp", new UUID(3, 4));
|
||||
db.newUser("pizza", new UUID(3, 4));
|
||||
|
||||
assertEquals(7, getSplitDataFromFile(db.getUsersFile()).size());
|
||||
|
||||
//Now we *fix* the DB and there should be one less
|
||||
db.checkFileHealthAndStructure();
|
||||
assertEquals(6, getSplitDataFromFile(db.getUsersFile()).size());
|
||||
}
|
||||
|
||||
private void checkNewUserValues(@NotNull PlayerProfile playerProfile, int startingLevel) {
|
||||
//Checking a new user for being zero initialized
|
||||
for(PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
||||
if(SkillTools.isChildSkill(primarySkillType))
|
||||
continue;
|
||||
|
||||
assertEquals(startingLevel, playerProfile.getSkillLevel(primarySkillType));
|
||||
assertEquals(0, playerProfile.getSkillXpLevelRaw(primarySkillType), 0);
|
||||
}
|
||||
|
||||
for(SuperAbilityType superAbilityType : SuperAbilityType.values()) {
|
||||
assertEquals(0, playerProfile.getAbilityDATS(superAbilityType));
|
||||
}
|
||||
|
||||
assertTrue(playerProfile.getLastLogin() > 0);
|
||||
assertEquals(playerProfile.getChimaerWingDATS(), 0);
|
||||
assertEquals(playerProfile.getScoreboardTipsShown(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoadByUUID() {
|
||||
File dbFile = prepareDatabaseTestResource(DB_HEALTHY);
|
||||
|
||||
/*
|
||||
* We have established the files are in good order, so now for the actual testing
|
||||
*/
|
||||
|
||||
//This makes sure our private method is working before the tests run afterwards
|
||||
ArrayList<String[]> dataFromFile = getSplitDataFromFile(dbFile);
|
||||
logger.info("File Path: " + dbFile.getAbsolutePath());
|
||||
assertArrayEquals(HEALTHY_DB_LINE_1.split(":"), dataFromFile.get(0));
|
||||
assertEquals(dataFromFile.get(0)[FlatFileDatabaseManager.UUID_INDEX], HEALTHY_DB_LINE_ONE_UUID_STR);
|
||||
|
||||
db = new FlatFileDatabaseManager(dbFile, logger, PURGE_TIME, 0, true);
|
||||
List<FlatFileDataFlag> flagsFound = db.checkFileHealthAndStructure();
|
||||
assertNull(flagsFound); //No flags should be found
|
||||
|
||||
/*
|
||||
* Once the DB looks fine load the profile
|
||||
*/
|
||||
|
||||
String playerName = "nossr50";
|
||||
UUID uuid = UUID.fromString("588fe472-1c82-4c4e-9aa1-7eefccb277e3");
|
||||
|
||||
PlayerProfile profile1 = db.loadPlayerProfile(uuid);
|
||||
testHealthyDataProfileValues(playerName, uuid, profile1);
|
||||
|
||||
|
||||
assertFalse(db.loadPlayerProfile(new UUID(0, 1)).isLoaded()); //This profile should not exist and therefor will return unloaded
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoadByUUIDAndName() {
|
||||
File dbFile = prepareDatabaseTestResource(DB_HEALTHY);
|
||||
|
||||
/*
|
||||
* We have established the files are in good order, so now for the actual testing
|
||||
*/
|
||||
|
||||
//This makes sure our private method is working before the tests run afterwards
|
||||
ArrayList<String[]> dataFromFile = getSplitDataFromFile(dbFile);
|
||||
logger.info("File Path: " + dbFile.getAbsolutePath());
|
||||
assertArrayEquals(HEALTHY_DB_LINE_1.split(":"), dataFromFile.get(0));
|
||||
assertEquals(dataFromFile.get(0)[FlatFileDatabaseManager.UUID_INDEX], HEALTHY_DB_LINE_ONE_UUID_STR);
|
||||
|
||||
db = new FlatFileDatabaseManager(dbFile, logger, PURGE_TIME, 0, true);
|
||||
List<FlatFileDataFlag> flagsFound = db.checkFileHealthAndStructure();
|
||||
assertNull(flagsFound); //No flags should be found
|
||||
|
||||
/*
|
||||
* Once the DB looks fine load the profile
|
||||
*/
|
||||
|
||||
String playerName = "nossr50";
|
||||
UUID uuid = UUID.fromString("588fe472-1c82-4c4e-9aa1-7eefccb277e3");
|
||||
|
||||
Player player = initMockPlayer(playerName, uuid);
|
||||
PlayerProfile profile1 = db.loadPlayerProfile(player);
|
||||
testHealthyDataProfileValues(playerName, uuid, profile1);
|
||||
|
||||
String updatedName = "updatedName";
|
||||
Player updatedNamePlayer = initMockPlayer(updatedName, uuid);
|
||||
PlayerProfile updatedNameProfile = db.loadPlayerProfile(updatedNamePlayer);
|
||||
testHealthyDataProfileValues(updatedName, uuid, updatedNameProfile);
|
||||
|
||||
Player shouldNotExist = initMockPlayer("doesntexist", new UUID(0, 1));
|
||||
PlayerProfile profile3 = db.loadPlayerProfile(shouldNotExist);
|
||||
assertFalse(profile3.isLoaded());
|
||||
}
|
||||
|
||||
private File prepareDatabaseTestResource(@NotNull String dbFileName) {
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
URI resourceFileURI = null;
|
||||
|
||||
try {
|
||||
resourceFileURI = classLoader.getResource(dbFileName).toURI();
|
||||
} catch (URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
assertNotNull(resourceFileURI);
|
||||
File fromResourcesFile = new File(resourceFileURI);
|
||||
assertNotNull(resourceFileURI);
|
||||
File copyOfFile = new File(tempDir.getPath() + File.separator + dbFileName);
|
||||
|
||||
if(copyOfFile.exists()) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
copyOfFile.delete();
|
||||
}
|
||||
|
||||
assertTrue(fromResourcesFile.exists());
|
||||
|
||||
try {
|
||||
//noinspection UnstableApiUsage
|
||||
Files.copy(fromResourcesFile, copyOfFile);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
assertNotNull(copyOfFile);
|
||||
return copyOfFile;
|
||||
}
|
||||
|
||||
private void testHealthyDataProfileValues(@NotNull String playerName, @NotNull UUID uuid, @NotNull PlayerProfile profile) {
|
||||
assertTrue(profile.isLoaded()); //PlayerProfile::isLoaded returns true if the data was created from the file, false if it wasn't found and a dummy profile was returned
|
||||
assertEquals(uuid, profile.getUniqueId());
|
||||
assertEquals(playerName, profile.getPlayerName());
|
||||
|
||||
/*
|
||||
* Player is a match and data is loaded, check values
|
||||
*/
|
||||
|
||||
for(PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
||||
if(SkillTools.isChildSkill(primarySkillType))
|
||||
continue;
|
||||
|
||||
// logger.info("Checking expected values for: "+primarySkillType);
|
||||
// logger.info("Profile Level Value: "+profile.getSkillLevel(primarySkillType));
|
||||
// logger.info("Expected Lvl Value: "+getExpectedLevelHealthyDBEntryOne(primarySkillType));
|
||||
// logger.info("Profile Exp Value: "+profile.getSkillXpLevelRaw(primarySkillType));
|
||||
// logger.info("Expected Exp Value: "+getExpectedExperienceHealthyDBEntryOne(primarySkillType));
|
||||
|
||||
assertEquals(getExpectedLevelHealthyDBEntryOne(primarySkillType), profile.getSkillLevel(primarySkillType));
|
||||
assertEquals(getExpectedExperienceHealthyDBEntryOne(primarySkillType), profile.getSkillXpLevelRaw(primarySkillType), 0);
|
||||
}
|
||||
|
||||
//Check the other things
|
||||
for(SuperAbilityType superAbilityType : SuperAbilityType.values()) {
|
||||
assertEquals(getExpectedSuperAbilityDATS(superAbilityType), profile.getAbilityDATS(superAbilityType));
|
||||
}
|
||||
|
||||
assertEquals(expectedChimaeraWingCd, profile.getUniqueData(UniqueDataType.CHIMAERA_WING_DATS));
|
||||
assertEquals(expectedScoreboardTips, profile.getScoreboardTipsShown());
|
||||
assertEquals(expectedLastLogin, profile.getLastLogin());
|
||||
}
|
||||
|
||||
private long getExpectedSuperAbilityDATS(@NotNull SuperAbilityType superAbilityType) {
|
||||
switch(superAbilityType) {
|
||||
case BERSERK:
|
||||
return expectedBerserkCd;
|
||||
case SUPER_BREAKER:
|
||||
return expectedSuperBreakerCd;
|
||||
case GIGA_DRILL_BREAKER:
|
||||
return expectedGigaDrillBreakerCd;
|
||||
case GREEN_TERRA:
|
||||
return expectedGreenTerraCd;
|
||||
case SKULL_SPLITTER:
|
||||
return expectedSkullSplitterCd;
|
||||
case TREE_FELLER:
|
||||
return expectedTreeFellerCd;
|
||||
case SERRATED_STRIKES:
|
||||
return expectedSerratedStrikesCd;
|
||||
case BLAST_MINING:
|
||||
return expectedBlastMiningCd;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//TODO: Why is this stuff a float?
|
||||
private float getExpectedExperienceHealthyDBEntryOne(@NotNull PrimarySkillType primarySkillType) {
|
||||
switch(primarySkillType) {
|
||||
case ACROBATICS:
|
||||
return expectedExpAcrobatics;
|
||||
case ALCHEMY:
|
||||
return expectedExpAlchemy;
|
||||
case ARCHERY:
|
||||
return expectedExpArchery;
|
||||
case AXES:
|
||||
return expectedExpAxes;
|
||||
case EXCAVATION:
|
||||
return expectedExpExcavation;
|
||||
case FISHING:
|
||||
return expectedExpFishing;
|
||||
case HERBALISM:
|
||||
return expectedExpHerbalism;
|
||||
case MINING:
|
||||
return expectedExpMining;
|
||||
case REPAIR:
|
||||
return expectedExpRepair;
|
||||
case SALVAGE:
|
||||
case SMELTING:
|
||||
return 0;
|
||||
case SWORDS:
|
||||
return expectedExpSwords;
|
||||
case TAMING:
|
||||
return expectedExpTaming;
|
||||
case UNARMED:
|
||||
return expectedExpUnarmed;
|
||||
case WOODCUTTING:
|
||||
return expectedExpWoodcutting;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private int getExpectedLevelHealthyDBEntryOne(@NotNull PrimarySkillType primarySkillType) {
|
||||
switch(primarySkillType) {
|
||||
case ACROBATICS:
|
||||
return expectedLvlAcrobatics;
|
||||
case ALCHEMY:
|
||||
return expectedLvlAlchemy;
|
||||
case ARCHERY:
|
||||
return expectedLvlArchery;
|
||||
case AXES:
|
||||
return expectedLvlAxes;
|
||||
case EXCAVATION:
|
||||
return expectedLvlExcavation;
|
||||
case FISHING:
|
||||
return expectedLvlFishing;
|
||||
case HERBALISM:
|
||||
return expectedLvlHerbalism;
|
||||
case MINING:
|
||||
return expectedLvlMining;
|
||||
case REPAIR:
|
||||
return expectedLvlRepair;
|
||||
case SALVAGE:
|
||||
case SMELTING:
|
||||
return 0;
|
||||
case SWORDS:
|
||||
return expectedLvlSwords;
|
||||
case TAMING:
|
||||
return expectedLvlTaming;
|
||||
case UNARMED:
|
||||
return expectedLvlUnarmed;
|
||||
case WOODCUTTING:
|
||||
return expectedLvlWoodcutting;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOverwriteName() {
|
||||
overwriteDataAndCheckForFlag(db, duplicateNameDatabaseData, FlatFileDataFlag.DUPLICATE_NAME);
|
||||
ArrayList<String[]> splitDataLines = getSplitDataFromFile(db.getUsersFile());
|
||||
assertNotEquals(splitDataLines.get(1)[0], splitDataLines.get(0)[0]); //Name comparison
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDataNotFound() {
|
||||
//Save the zero version and see if it looks correct
|
||||
assertNotNull(db);
|
||||
assertTrue(db.getUsersFile().exists());
|
||||
assertNotNull(db.getUsersFile());
|
||||
|
||||
//Check for the "unloaded" profile
|
||||
PlayerProfile retrievedFromData = db.loadPlayerProfile("nossr50");
|
||||
assertFalse(retrievedFromData.isLoaded()); //PlayerProfile::isLoaded returns false if data doesn't exist for the user
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPurgePowerlessUsers() {
|
||||
replaceDataInFile(db, normalDatabaseData);
|
||||
int purgeCount = db.purgePowerlessUsers();
|
||||
assertEquals(purgeCount, 1); //1 User should have been purged
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckFileHealthAndStructure() {
|
||||
replaceDataInFile(db, badDatabaseData);
|
||||
|
||||
List<FlatFileDataFlag> dataFlags = db.checkFileHealthAndStructure();
|
||||
assertNotNull(dataFlags);
|
||||
assertNotEquals(dataFlags.size(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindFixableDuplicateNames() {
|
||||
overwriteDataAndCheckForFlag(db, duplicateNameDatabaseData, FlatFileDataFlag.DUPLICATE_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindDuplicateUUIDs() {
|
||||
overwriteDataAndCheckForFlag(db, duplicateUUIDDatabaseData, FlatFileDataFlag.DUPLICATE_UUID);
|
||||
}
|
||||
|
||||
@Test()
|
||||
void findBadUUIDData() {
|
||||
overwriteDataAndCheckForFlag(db, badUUIDDatabaseData, FlatFileDataFlag.BAD_UUID_DATA);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindCorruptData() {
|
||||
overwriteDataAndCheckForFlag(db, corruptDatabaseData, FlatFileDataFlag.CORRUPTED_OR_UNRECOGNIZABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindEmptyNames() {
|
||||
overwriteDataAndCheckForFlag(db, emptyNameDatabaseData, FlatFileDataFlag.MISSING_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindBadValues() {
|
||||
overwriteDataAndCheckForFlag(db, badDatabaseData, FlatFileDataFlag.BAD_VALUES);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindOutdatedData() {
|
||||
overwriteDataAndCheckForFlag(db, outdatedDatabaseData, FlatFileDataFlag.INCOMPLETE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetDatabaseType() {
|
||||
assertNotNull(db);
|
||||
assertEquals(db.getDatabaseType(), DatabaseType.FLATFILE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReadRank() {
|
||||
//This is an empty DB
|
||||
assertNotNull(db);
|
||||
String rankBoyName = "rankBoy";
|
||||
UUID rankBoyUUID = new UUID(1337, 1337);
|
||||
String rankGirlName = "rankGirl";
|
||||
UUID rankGirlUUID = new UUID(7331, 7331);
|
||||
|
||||
PlayerProfile rankGirlProfile = addPlayerProfileWithLevelsAndSave(rankGirlName, rankGirlUUID, 100); //Rank 1
|
||||
PlayerProfile rankBoyProfile = addPlayerProfileWithLevelsAndSave(rankBoyName, rankBoyUUID, 10); //Rank 2
|
||||
|
||||
assertEquals(LeaderboardStatus.UPDATED, db.updateLeaderboards());
|
||||
Map<PrimarySkillType, Integer> rankGirlPositions = db.readRank(rankGirlName);
|
||||
Map<PrimarySkillType, Integer> rankBoyPositions = db.readRank(rankBoyName);
|
||||
|
||||
for(PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
||||
if(primarySkillType.isChildSkill()) {
|
||||
assertNull(rankBoyPositions.get(primarySkillType));
|
||||
assertNull(rankGirlPositions.get(primarySkillType));
|
||||
} else {
|
||||
assertEquals(1, rankGirlPositions.get(primarySkillType));
|
||||
assertEquals(2, rankBoyPositions.get(primarySkillType));
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(1, db.readRank(rankGirlName).get(null)); //Girl should be position 1
|
||||
assertEquals(2, db.readRank(rankBoyName).get(null)); //Boy should be position 2
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoadFromFile() {
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
URI resourceFileURI = null;
|
||||
|
||||
try {
|
||||
resourceFileURI = classLoader.getResource(DB_BADDATA).toURI();
|
||||
} catch (URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
assertNotNull(resourceFileURI);
|
||||
File fromResourcesFile = new File(resourceFileURI);
|
||||
assertNotNull(resourceFileURI);
|
||||
File copyOfFile = new File(tempDir.getPath() + File.separator + DB_BADDATA);
|
||||
|
||||
if(copyOfFile.exists()) {
|
||||
copyOfFile.delete();
|
||||
}
|
||||
|
||||
assertTrue(fromResourcesFile.exists());
|
||||
|
||||
try {
|
||||
Files.copy(fromResourcesFile, copyOfFile);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
assertNotNull(copyOfFile);
|
||||
|
||||
//This makes sure our private method is working before the tests run afterwards
|
||||
ArrayList<String[]> dataFromFile = getSplitDataFromFile(copyOfFile);
|
||||
logger.info("File Path: "+copyOfFile.getAbsolutePath());
|
||||
assertArrayEquals(BAD_FILE_LINE_ONE.split(":"), dataFromFile.get(0));
|
||||
assertEquals(dataFromFile.get(22)[0], "nossr51");
|
||||
assertArrayEquals(BAD_DATA_FILE_LINE_TWENTY_THREE.split(":"), dataFromFile.get(22));
|
||||
|
||||
FlatFileDatabaseManager db_a = new FlatFileDatabaseManager(copyOfFile, logger, PURGE_TIME, 0, true);
|
||||
List<FlatFileDataFlag> flagsFound = db_a.checkFileHealthAndStructure();
|
||||
assertNotNull(flagsFound);
|
||||
assertTrue(flagsFound.contains(FlatFileDataFlag.BAD_VALUES));
|
||||
}
|
||||
|
||||
private @NotNull ArrayList<String[]> getSplitDataFromFile(@NotNull File file) {
|
||||
ArrayList<String[]> splitDataList = new ArrayList<>();
|
||||
|
||||
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {
|
||||
String line;
|
||||
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
if (line.isEmpty())
|
||||
continue;
|
||||
|
||||
String[] splitData = line.split(":");
|
||||
splitDataList.add(splitData);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return splitDataList;
|
||||
}
|
||||
|
||||
private @NotNull PlayerProfile addPlayerProfileWithLevelsAndSave(String playerName, UUID uuid, int levels) {
|
||||
assertNotNull(db);
|
||||
assertFalse(db.loadPlayerProfile(uuid).isLoaded());
|
||||
|
||||
db.newUser(playerName, uuid);
|
||||
PlayerProfile leveledProfile = db.loadPlayerProfile(uuid);
|
||||
|
||||
assertTrue(leveledProfile.isLoaded());
|
||||
assertEquals(playerName, leveledProfile.getPlayerName());
|
||||
assertEquals(uuid, leveledProfile.getUniqueId());
|
||||
|
||||
for(PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
||||
if(SkillTools.isChildSkill(primarySkillType))
|
||||
continue;
|
||||
|
||||
leveledProfile.modifySkill(primarySkillType, levels); //TODO: This method also resets XP, not cool
|
||||
}
|
||||
|
||||
db.saveUser(leveledProfile);
|
||||
leveledProfile = db.loadPlayerProfile(uuid);
|
||||
|
||||
for(PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
||||
if(SkillTools.isChildSkill(primarySkillType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
assertEquals(levels, leveledProfile.getSkillLevel(primarySkillType));
|
||||
}
|
||||
|
||||
return leveledProfile;
|
||||
}
|
||||
|
||||
private void replaceDataInFile(@NotNull FlatFileDatabaseManager flatFileDatabaseManager, @NotNull String[] dataEntries) {
|
||||
String filePath = flatFileDatabaseManager.getUsersFile().getAbsolutePath();
|
||||
BufferedReader in = null;
|
||||
FileWriter out = null;
|
||||
|
||||
try {
|
||||
StringBuilder writer = new StringBuilder();
|
||||
|
||||
for(String data : dataEntries) {
|
||||
writer.append(data).append("\r\n");
|
||||
}
|
||||
|
||||
out = new FileWriter(filePath);
|
||||
out.write(writer.toString());
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
logger.info("File not found");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
logger.info("Added the following lines to the FlatFileDatabase for the purposes of the test...");
|
||||
// Open the file
|
||||
in = new BufferedReader(new FileReader(filePath));
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
logger.info(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void overwriteDataAndCheckForFlag(@NotNull FlatFileDatabaseManager targetDatabase, @NotNull String[] data, @NotNull FlatFileDataFlag flag) {
|
||||
replaceDataInFile(targetDatabase, data);
|
||||
|
||||
List<FlatFileDataFlag> dataFlags = targetDatabase.checkFileHealthAndStructure();
|
||||
assertNotNull(dataFlags);
|
||||
assertTrue(dataFlags.contains(flag));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Player initMockPlayer(@NotNull String name, @NotNull UUID uuid) {
|
||||
Player mockPlayer = mock(Player.class);
|
||||
Mockito.when(mockPlayer.getName()).thenReturn(name);
|
||||
Mockito.when(mockPlayer.getUniqueId()).thenReturn(uuid);
|
||||
return mockPlayer;
|
||||
}
|
||||
|
||||
private static class DebugFilter implements Filter {
|
||||
@Override
|
||||
public boolean isLoggable(LogRecord record) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void recursiveDelete(@NotNull File directoryToBeDeleted) {
|
||||
if (directoryToBeDeleted.isDirectory()) {
|
||||
for (File file : directoryToBeDeleted.listFiles()) {
|
||||
recursiveDelete(file);
|
||||
}
|
||||
}
|
||||
directoryToBeDeleted.delete();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
package com.gmail.nossr50.database.flatfile;
|
||||
|
||||
import com.gmail.nossr50.database.FlatFileDatabaseManager;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
class FlatFileDataUtilTest {
|
||||
|
||||
@Test
|
||||
void getPreparedSaveDataLine() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void repairBadData() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void getZeroInitialisedData() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTooManyDataEntriesSplitString() {
|
||||
Assertions.assertThrows(AssertionError.class, () -> {
|
||||
FlatFileDataContainer dataContainer = new CategorizedFlatFileData(0, new HashSet<>(), new String[FlatFileDatabaseManager.DATA_ENTRY_COUNT + 1]);
|
||||
FlatFileDataUtil.getPreparedSaveDataLine(dataContainer);
|
||||
});
|
||||
}
|
||||
}
|
@@ -1,12 +1,12 @@
|
||||
package com.gmail.nossr50.datatypes;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class BlockLocationHistoryTest {
|
||||
class BlockLocationHistoryTest {
|
||||
@Test
|
||||
public void testRemovesOldestElement() {
|
||||
void testRemovesOldestElement() {
|
||||
BlockLocationHistory history = new BlockLocationHistory(2);
|
||||
Location locationA = new Location(null, 0, 1, 2);
|
||||
Location locationB = new Location(null, 1, 2, 3);
|
||||
@@ -15,13 +15,13 @@ public class BlockLocationHistoryTest {
|
||||
history.add(locationA);
|
||||
history.add(locationB);
|
||||
history.add(locationC);
|
||||
Assert.assertFalse(history.contains(locationA));
|
||||
Assert.assertTrue(history.contains(locationB));
|
||||
Assert.assertTrue(history.contains(locationC));
|
||||
Assertions.assertFalse(history.contains(locationA));
|
||||
Assertions.assertTrue(history.contains(locationB));
|
||||
Assertions.assertTrue(history.contains(locationC));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupportsDuplicateElement() {
|
||||
void testSupportsDuplicateElement() {
|
||||
BlockLocationHistory history = new BlockLocationHistory(2);
|
||||
Location locationA = new Location(null, 0, 1, 2);
|
||||
Location locationB = new Location(null, 1, 2, 3);
|
||||
@@ -29,9 +29,9 @@ public class BlockLocationHistoryTest {
|
||||
history.add(locationA);
|
||||
history.add(locationA);
|
||||
history.add(locationB);
|
||||
Assert.assertTrue(history.contains(locationA));
|
||||
Assert.assertTrue(history.contains(locationB));
|
||||
Assertions.assertTrue(history.contains(locationA));
|
||||
Assertions.assertTrue(history.contains(locationB));
|
||||
history.add(locationB);
|
||||
Assert.assertFalse(history.contains(locationA));
|
||||
Assertions.assertFalse(history.contains(locationA));
|
||||
}
|
||||
}
|
||||
|
@@ -1,73 +1,135 @@
|
||||
package com.gmail.nossr50.util.blockmeta;
|
||||
|
||||
import com.gmail.nossr50.TestUtil;
|
||||
import com.gmail.nossr50.util.Misc;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.util.BlockUtils;
|
||||
import com.google.common.io.Files;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.*;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Could be a lot better. But some tests are better than none! Tests the major things, still kinda unit-testy. Verifies that the serialization isn't completely broken.
|
||||
* Could be a lot better. But some tests are better than none! Tests the major things, still kinda unit-testy. Verifies
|
||||
* that the serialization isn't completely broken.
|
||||
*/
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({ Bukkit.class, Misc.class })
|
||||
public class ChunkStoreTest {
|
||||
class ChunkStoreTest {
|
||||
|
||||
public static final int LEGACY_WORLD_HEIGHT_MAX = 256;
|
||||
public static final int LEGACY_WORLD_HEIGHT_MIN = 0;
|
||||
private static File tempDir;
|
||||
@BeforeClass
|
||||
|
||||
@BeforeAll
|
||||
public static void setUpClass() {
|
||||
tempDir = Files.createTempDir();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
@AfterAll
|
||||
public static void tearDownClass() {
|
||||
TestUtil.recursiveDelete(tempDir);
|
||||
recursiveDelete(tempDir);
|
||||
}
|
||||
|
||||
private World mockWorld;
|
||||
@Before
|
||||
public void setUpMock(){
|
||||
|
||||
private MockedStatic<Bukkit> bukkitMock;
|
||||
private MockedStatic<mcMMO> mcMMOMock;
|
||||
|
||||
@BeforeEach
|
||||
void setUpMock() {
|
||||
UUID worldUUID = UUID.randomUUID();
|
||||
mockWorld = mock(World.class);
|
||||
mockWorld = Mockito.mock(World.class);
|
||||
Mockito.when(mockWorld.getUID()).thenReturn(worldUUID);
|
||||
Mockito.when(mockWorld.getMaxHeight()).thenReturn(256);
|
||||
Mockito.when(mockWorld.getWorldFolder()).thenReturn(tempDir);
|
||||
PowerMockito.mockStatic(Bukkit.class);
|
||||
Mockito.when(Bukkit.getWorld(worldUUID)).thenReturn(mockWorld);
|
||||
|
||||
bukkitMock = Mockito.mockStatic(Bukkit.class);
|
||||
bukkitMock.when(() -> Bukkit.getWorld(worldUUID)).thenReturn(mockWorld);
|
||||
|
||||
mcMMOMock = Mockito.mockStatic(mcMMO.class);
|
||||
|
||||
Mockito.when(mockWorld.getMinHeight()).thenReturn(LEGACY_WORLD_HEIGHT_MIN);
|
||||
Mockito.when(mockWorld.getMaxHeight()).thenReturn(LEGACY_WORLD_HEIGHT_MAX);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void teardownMock() {
|
||||
bukkitMock.close();
|
||||
mcMMOMock.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetValue() {
|
||||
void testIndexOutOfBounds() {
|
||||
Mockito.when(mockWorld.getMinHeight()).thenReturn(-64);
|
||||
HashChunkManager hashChunkManager = new HashChunkManager();
|
||||
|
||||
// Top Block
|
||||
Block illegalHeightBlock = initMockBlock(1337, 256, -1337);
|
||||
Assertions.assertFalse(hashChunkManager.isTrue(illegalHeightBlock));
|
||||
Assertions.assertThrows(IndexOutOfBoundsException.class, () -> hashChunkManager.setTrue(illegalHeightBlock));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetTrue() {
|
||||
Mockito.when(mockWorld.getMinHeight()).thenReturn(-64);
|
||||
HashChunkManager hashChunkManager = new HashChunkManager();
|
||||
int radius = 2; // Could be anything but drastically changes test time
|
||||
|
||||
for (int x = -radius; x <= radius; x++) {
|
||||
for (int y = mockWorld.getMinHeight(); y < mockWorld.getMaxHeight(); y++) {
|
||||
for (int z = -radius; z <= radius; z++) {
|
||||
Block testBlock = initMockBlock(x, y, z);
|
||||
|
||||
hashChunkManager.setTrue(testBlock);
|
||||
Assertions.assertTrue(hashChunkManager.isTrue(testBlock));
|
||||
hashChunkManager.setFalse(testBlock);
|
||||
Assertions.assertFalse(hashChunkManager.isTrue(testBlock));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bot Block
|
||||
Block bottomBlock = initMockBlock(1337, 0, -1337);
|
||||
Assertions.assertFalse(hashChunkManager.isTrue(bottomBlock));
|
||||
|
||||
Assertions.assertTrue(BlockUtils.isWithinWorldBounds(bottomBlock));
|
||||
hashChunkManager.setTrue(bottomBlock);
|
||||
Assertions.assertTrue(hashChunkManager.isTrue(bottomBlock));
|
||||
|
||||
// Top Block
|
||||
Block topBlock = initMockBlock(1337, 255, -1337);
|
||||
Assertions.assertFalse(hashChunkManager.isTrue(topBlock));
|
||||
|
||||
Assertions.assertTrue(BlockUtils.isWithinWorldBounds(topBlock));
|
||||
hashChunkManager.setTrue(topBlock);
|
||||
Assertions.assertTrue(hashChunkManager.isTrue(topBlock));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetValue() {
|
||||
BitSetChunkStore original = new BitSetChunkStore(mockWorld, 0, 0);
|
||||
original.setTrue(0, 0, 0);
|
||||
Assert.assertTrue(original.isTrue(0, 0, 0));
|
||||
Assertions.assertTrue(original.isTrue(0, 0, 0));
|
||||
original.setFalse(0, 0, 0);
|
||||
Assert.assertFalse(original.isTrue(0, 0, 0));
|
||||
Assertions.assertFalse(original.isTrue(0, 0, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsEmpty() {
|
||||
void testIsEmpty() {
|
||||
BitSetChunkStore original = new BitSetChunkStore(mockWorld, 0, 0);
|
||||
Assert.assertTrue(original.isEmpty());
|
||||
Assertions.assertTrue(original.isEmpty());
|
||||
original.setTrue(0, 0, 0);
|
||||
original.setFalse(0, 0, 0);
|
||||
Assert.assertTrue(original.isEmpty());
|
||||
Assertions.assertTrue(original.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRoundTrip() throws IOException {
|
||||
void testRoundTrip() throws IOException {
|
||||
BitSetChunkStore original = new BitSetChunkStore(mockWorld, 1, 2);
|
||||
original.setTrue(14, 89, 12);
|
||||
original.setTrue(14, 90, 12);
|
||||
@@ -78,9 +140,8 @@ public class ChunkStoreTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNegativeWorldMin() throws IOException {
|
||||
PowerMockito.mockStatic(Misc.class);
|
||||
Mockito.when(Misc.getWorldMinCompat(mockWorld)).thenReturn(-64);
|
||||
void testNegativeWorldMin() throws IOException {
|
||||
Mockito.when(mockWorld.getMinHeight()).thenReturn(-64);
|
||||
|
||||
BitSetChunkStore original = new BitSetChunkStore(mockWorld, 1, 2);
|
||||
original.setTrue(14, -32, 12);
|
||||
@@ -92,56 +153,57 @@ public class ChunkStoreTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNegativeWorldMinUpgrade() throws IOException {
|
||||
void testNegativeWorldMinUpgrade() throws IOException {
|
||||
BitSetChunkStore original = new BitSetChunkStore(mockWorld, 1, 2);
|
||||
original.setTrue(14, 1, 12);
|
||||
original.setTrue(14, 2, 12);
|
||||
original.setTrue(13, 3, 12);
|
||||
byte[] serializedBytes = serializeChunkstore(original);
|
||||
|
||||
PowerMockito.mockStatic(Misc.class);
|
||||
Mockito.when(Misc.getWorldMinCompat(mockWorld)).thenReturn(-64);
|
||||
Mockito.when(mockWorld.getMinHeight()).thenReturn(-64);
|
||||
ChunkStore deserialized = BitSetChunkStore.Serialization.readChunkStore(new DataInputStream(new ByteArrayInputStream(serializedBytes)));
|
||||
assert deserialized != null;
|
||||
assertEqualIgnoreMinMax(original, deserialized);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChunkCoords() throws IOException {
|
||||
void testChunkCoords() throws IOException {
|
||||
for (int x = -96; x < 0; x++) {
|
||||
int cx = x >> 4;
|
||||
int ix = Math.abs(x) % 16;
|
||||
System.out.print(cx + ":" + ix + " ");
|
||||
int cx = x >> 4;
|
||||
int ix = Math.abs(x) % 16;
|
||||
//System.out.print(cx + ":" + ix + " ");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpgrade() throws IOException {
|
||||
void testUpgrade() throws IOException {
|
||||
LegacyChunkStore original = new LegacyChunkStore(mockWorld, 12, 32);
|
||||
original.setTrue(14, 89, 12);
|
||||
original.setTrue(14, 90, 12);
|
||||
original.setTrue(13, 89, 12);
|
||||
byte[] serializedBytes = serializeChunkstore(original);
|
||||
ChunkStore deserialized = BitSetChunkStore.Serialization.readChunkStore(new DataInputStream(new ByteArrayInputStream(serializedBytes)));
|
||||
assert deserialized != null;
|
||||
assertEqual(original, deserialized);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleRegionRoundtrip() throws IOException {
|
||||
void testSimpleRegionRoundtrip() throws IOException {
|
||||
LegacyChunkStore original = new LegacyChunkStore(mockWorld, 12, 12);
|
||||
original.setTrue(14, 89, 12);
|
||||
original.setTrue(14, 90, 12);
|
||||
original.setTrue(13, 89, 12);
|
||||
File file = new File(tempDir, "SimpleRegionRoundTrip.region");
|
||||
McMMOSimpleRegionFile region = new McMMOSimpleRegionFile(file, 0, 0);
|
||||
try (DataOutputStream outputStream = region.getOutputStream(12, 12)){
|
||||
try (DataOutputStream outputStream = region.getOutputStream(12, 12)) {
|
||||
outputStream.write(serializeChunkstore(original));
|
||||
}
|
||||
region.close();
|
||||
region = new McMMOSimpleRegionFile(file, 0, 0);
|
||||
try (DataInputStream is = region.getInputStream(original.getChunkX(), original.getChunkZ()))
|
||||
{
|
||||
Assert.assertNotNull(is);
|
||||
try (DataInputStream is = region.getInputStream(original.getChunkX(), original.getChunkZ())) {
|
||||
Assertions.assertNotNull(is);
|
||||
ChunkStore deserialized = BitSetChunkStore.Serialization.readChunkStore(is);
|
||||
assert deserialized != null;
|
||||
assertEqual(original, deserialized);
|
||||
}
|
||||
region.close();
|
||||
@@ -149,36 +211,36 @@ public class ChunkStoreTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleRegionRejectsOutOfBounds() {
|
||||
void testSimpleRegionRejectsOutOfBounds() {
|
||||
File file = new File(tempDir, "SimpleRegionRoundTrip.region");
|
||||
McMMOSimpleRegionFile region = new McMMOSimpleRegionFile(file, 0, 0);
|
||||
assertThrows(() -> region.getOutputStream(-1, 0), IndexOutOfBoundsException.class);
|
||||
assertThrows(() -> region.getOutputStream(0, -1), IndexOutOfBoundsException.class);
|
||||
assertThrows(() -> region.getOutputStream(32, 0), IndexOutOfBoundsException.class);
|
||||
assertThrows(() -> region.getOutputStream(0, 32), IndexOutOfBoundsException.class);
|
||||
Assertions.assertThrows(IndexOutOfBoundsException.class, () -> region.getOutputStream(-1, 0));
|
||||
Assertions.assertThrows(IndexOutOfBoundsException.class, () -> region.getOutputStream(0, -1));
|
||||
Assertions.assertThrows(IndexOutOfBoundsException.class, () -> region.getOutputStream(32, 0));
|
||||
Assertions.assertThrows(IndexOutOfBoundsException.class, () -> region.getOutputStream(0, 32));
|
||||
region.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChunkStoreRejectsOutOfBounds() {
|
||||
void testChunkStoreRejectsOutOfBounds() {
|
||||
ChunkStore chunkStore = new BitSetChunkStore(mockWorld, 0, 0);
|
||||
assertThrows(() -> chunkStore.setTrue(-1, 0, 0), IndexOutOfBoundsException.class);
|
||||
assertThrows(() -> chunkStore.setTrue(0, -1, 0), IndexOutOfBoundsException.class);
|
||||
assertThrows(() -> chunkStore.setTrue(0, 0, -1), IndexOutOfBoundsException.class);
|
||||
assertThrows(() -> chunkStore.setTrue(16, 0, 0), IndexOutOfBoundsException.class);
|
||||
assertThrows(() -> chunkStore.setTrue(0, mockWorld.getMaxHeight(), 0), IndexOutOfBoundsException.class);
|
||||
assertThrows(() -> chunkStore.setTrue(0, 0, 16), IndexOutOfBoundsException.class);
|
||||
Assertions.assertThrows(IndexOutOfBoundsException.class, () -> chunkStore.setTrue(-1, 0, 0));
|
||||
Assertions.assertThrows(IndexOutOfBoundsException.class, () -> chunkStore.setTrue(0, -1, 0));
|
||||
Assertions.assertThrows(IndexOutOfBoundsException.class, () -> chunkStore.setTrue(0, 0, -1));
|
||||
Assertions.assertThrows(IndexOutOfBoundsException.class, () -> chunkStore.setTrue(16, 0, 0));
|
||||
Assertions.assertThrows(IndexOutOfBoundsException.class, () -> chunkStore.setTrue(0, mockWorld.getMaxHeight(), 0));
|
||||
Assertions.assertThrows(IndexOutOfBoundsException.class, () -> chunkStore.setTrue(0, 0, 16));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegressionChunkMirrorBug() {
|
||||
void testRegressionChunkMirrorBug() {
|
||||
ChunkManager chunkManager = new HashChunkManager();
|
||||
Block mockBlockA = mock(Block.class);
|
||||
Block mockBlockA = Mockito.mock(Block.class);
|
||||
Mockito.when(mockBlockA.getX()).thenReturn(15);
|
||||
Mockito.when(mockBlockA.getZ()).thenReturn(15);
|
||||
Mockito.when(mockBlockA.getY()).thenReturn(0);
|
||||
Mockito.when(mockBlockA.getWorld()).thenReturn(mockWorld);
|
||||
Block mockBlockB = mock(Block.class);
|
||||
Block mockBlockB = Mockito.mock(Block.class);
|
||||
Mockito.when(mockBlockB.getX()).thenReturn(-15);
|
||||
Mockito.when(mockBlockB.getZ()).thenReturn(-15);
|
||||
Mockito.when(mockBlockB.getY()).thenReturn(0);
|
||||
@@ -186,42 +248,25 @@ public class ChunkStoreTest {
|
||||
|
||||
chunkManager.setTrue(mockBlockA);
|
||||
chunkManager.setFalse(mockBlockB);
|
||||
Assert.assertTrue(chunkManager.isTrue(mockBlockA));
|
||||
Assertions.assertTrue(chunkManager.isTrue(mockBlockA));
|
||||
}
|
||||
|
||||
private interface Delegate {
|
||||
void run();
|
||||
}
|
||||
|
||||
private void assertThrows(@NotNull Delegate delegate, @NotNull Class<?> clazz) {
|
||||
try {
|
||||
delegate.run();
|
||||
Assert.fail(); // We didn't throw
|
||||
}
|
||||
catch (Throwable t) {
|
||||
Assert.assertTrue(t.getClass().equals(clazz));
|
||||
}
|
||||
}
|
||||
|
||||
private void assertEqual(ChunkStore expected, ChunkStore actual)
|
||||
{
|
||||
Assert.assertEquals(expected.getChunkMin(), actual.getChunkMin());
|
||||
Assert.assertEquals(expected.getChunkMax(), actual.getChunkMax());
|
||||
private void assertEqual(ChunkStore expected, ChunkStore actual) {
|
||||
Assertions.assertEquals(expected.getChunkMin(), actual.getChunkMin());
|
||||
Assertions.assertEquals(expected.getChunkMax(), actual.getChunkMax());
|
||||
assertEqualIgnoreMinMax(expected, actual);
|
||||
}
|
||||
|
||||
private void assertEqualIgnoreMinMax(ChunkStore expected, ChunkStore actual)
|
||||
{
|
||||
Assert.assertEquals(expected.getChunkX(), actual.getChunkX());
|
||||
Assert.assertEquals(expected.getChunkZ(), actual.getChunkZ());
|
||||
Assert.assertEquals(expected.getWorldId(), actual.getWorldId());
|
||||
for (int y = Math.min(actual.getChunkMin(), expected.getChunkMin()); y < Math.max(actual.getChunkMax(), expected.getChunkMax()); y++)
|
||||
{
|
||||
private void assertEqualIgnoreMinMax(ChunkStore expected, ChunkStore actual) {
|
||||
Assertions.assertEquals(expected.getChunkX(), actual.getChunkX());
|
||||
Assertions.assertEquals(expected.getChunkZ(), actual.getChunkZ());
|
||||
Assertions.assertEquals(expected.getWorldId(), actual.getWorldId());
|
||||
for (int y = Math.min(actual.getChunkMin(), expected.getChunkMin()); y < Math.max(actual.getChunkMax(), expected.getChunkMax()); y++) {
|
||||
if (expected.getChunkMin() > y || actual.getChunkMin() > y || expected.getChunkMax() <= y || actual.getChunkMax() <= y)
|
||||
continue; // Ignore
|
||||
for (int x = 0; x < 16; x++)
|
||||
for (int z = 0; z < 16; z++)
|
||||
Assert.assertTrue(expected.isTrue(x, y, z) == actual.isTrue(x, y, z));
|
||||
Assertions.assertEquals(expected.isTrue(x, y, z), actual.isTrue(x, y, z));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,7 +275,9 @@ public class ChunkStoreTest {
|
||||
if (chunkStore instanceof BitSetChunkStore)
|
||||
BitSetChunkStore.Serialization.writeChunkStore(new DataOutputStream(byteArrayOutputStream), chunkStore);
|
||||
else
|
||||
new UnitTestObjectOutputStream(byteArrayOutputStream).writeObject(chunkStore); // Serializes the class as if it were the old PrimitiveChunkStore
|
||||
new UnitTestObjectOutputStream(byteArrayOutputStream).writeObject(chunkStore); // Serializes the class as if
|
||||
// it were the old
|
||||
// PrimitiveChunkStore
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
}
|
||||
|
||||
@@ -345,9 +392,11 @@ public class ChunkStoreTest {
|
||||
private void readObject(@NotNull ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class UnitTestObjectOutputStream extends ObjectOutputStream {
|
||||
|
||||
public UnitTestObjectOutputStream(@NotNull OutputStream outputStream) throws IOException {
|
||||
super(outputStream);
|
||||
}
|
||||
@@ -359,5 +408,25 @@ public class ChunkStoreTest {
|
||||
str = "com.gmail.nossr50.util.blockmeta.chunkmeta.PrimitiveChunkStore";
|
||||
super.writeUTF(str);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Block initMockBlock(int x, int y, int z) {
|
||||
Block mockBlock = Mockito.mock(Block.class);
|
||||
Mockito.when(mockBlock.getX()).thenReturn(x);
|
||||
Mockito.when(mockBlock.getY()).thenReturn(y);
|
||||
Mockito.when(mockBlock.getZ()).thenReturn(z);
|
||||
Mockito.when(mockBlock.getWorld()).thenReturn(mockWorld);
|
||||
return mockBlock;
|
||||
}
|
||||
|
||||
public static void recursiveDelete(@NotNull File directoryToBeDeleted) {
|
||||
if (directoryToBeDeleted.isDirectory()) {
|
||||
for (File file : directoryToBeDeleted.listFiles()) {
|
||||
recursiveDelete(file);
|
||||
}
|
||||
}
|
||||
directoryToBeDeleted.delete();
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,130 @@
|
||||
package com.gmail.nossr50.util.platform;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class MinecraftGameVersionTest {
|
||||
|
||||
@Test
|
||||
void testAtLeast() {
|
||||
// TODO: Remove redundant tests
|
||||
MinecraftGameVersion oneEightEight = new MinecraftGameVersion(1, 8, 8);
|
||||
MinecraftGameVersion oneSixteenFive = new MinecraftGameVersion(1, 16, 5);
|
||||
MinecraftGameVersion oneTwo = new MinecraftGameVersion(1, 2);
|
||||
|
||||
// 1.8.8
|
||||
assertTrue(oneEightEight.isAtLeast(1, 8, 7));
|
||||
assertFalse(oneEightEight.isAtLeast(1, 9, 0));
|
||||
|
||||
// 1.16.5
|
||||
assertTrue(oneSixteenFive.isAtLeast(1, 15, 2));
|
||||
assertFalse(oneSixteenFive.isAtLeast(1, 17, 0));
|
||||
|
||||
// 1.2
|
||||
assertTrue(oneTwo.isAtLeast(1, 2, 0));
|
||||
|
||||
// Test major version number
|
||||
MinecraftGameVersion majorVersionTest = new MinecraftGameVersion(2, 0, 0);
|
||||
|
||||
assertFalse(majorVersionTest.isAtLeast(3, 0, 0));
|
||||
assertFalse(majorVersionTest.isAtLeast(3, 1, 0));
|
||||
assertFalse(majorVersionTest.isAtLeast(3, 0, 2));
|
||||
|
||||
assertTrue(majorVersionTest.isAtLeast(2, 0, 0));
|
||||
assertTrue(majorVersionTest.isAtLeast(1, 0, 0));
|
||||
|
||||
// Test minor version number
|
||||
MinecraftGameVersion minorVersionTest = new MinecraftGameVersion(0, 3, 0);
|
||||
|
||||
assertFalse(minorVersionTest.isAtLeast(0, 4, 0));
|
||||
assertFalse(minorVersionTest.isAtLeast(1, 4, 0));
|
||||
assertFalse(minorVersionTest.isAtLeast(0, 4, 1));
|
||||
|
||||
assertTrue(minorVersionTest.isAtLeast(0, 1, 0));
|
||||
assertTrue(minorVersionTest.isAtLeast(0, 2, 0));
|
||||
assertTrue(minorVersionTest.isAtLeast(0, 2, 1));
|
||||
assertTrue(minorVersionTest.isAtLeast(0, 3, 0));
|
||||
|
||||
// Test patch version number
|
||||
|
||||
MinecraftGameVersion patchVersionTest = new MinecraftGameVersion(0, 0, 5);
|
||||
|
||||
assertFalse(patchVersionTest.isAtLeast(1, 0, 0));
|
||||
assertFalse(patchVersionTest.isAtLeast(0, 0, 6));
|
||||
assertFalse(patchVersionTest.isAtLeast(0, 1, 4));
|
||||
assertFalse(patchVersionTest.isAtLeast(1, 1, 4));
|
||||
|
||||
assertTrue(patchVersionTest.isAtLeast(0, 0, 1));
|
||||
assertTrue(patchVersionTest.isAtLeast(0, 0, 2));
|
||||
assertTrue(patchVersionTest.isAtLeast(0, 0, 3));
|
||||
assertTrue(patchVersionTest.isAtLeast(0, 0, 4));
|
||||
assertTrue(patchVersionTest.isAtLeast(0, 0, 5));
|
||||
}
|
||||
|
||||
@MethodSource("getGameVersions")
|
||||
@ParameterizedTest(name = "Verify that \"{0}\" is recognized as {1}.{2}.{3}")
|
||||
void testVersionDetection(String gameVersion, int major, int minor, int patch) {
|
||||
/*
|
||||
* The platform manager checks for the type of server software,
|
||||
* we will just simulate some "Spigot" version here, so that the test can
|
||||
* continue successfully.
|
||||
*/
|
||||
String serverSoftwareVersion = "git-Spigot-12345-abcdef (MC: " + major + '.' + minor + '.' + patch + ')';
|
||||
|
||||
// Set up a mock plugin for logging.
|
||||
mcMMO plugin = Mockito.mock(mcMMO.class);
|
||||
Mockito.when(plugin.getName()).thenReturn("mcMMO");
|
||||
Mockito.when(plugin.getLogger()).thenReturn(Logger.getLogger("mcMMO"));
|
||||
mcMMO.p = plugin;
|
||||
|
||||
try (MockedStatic<Bukkit> bukkit = Mockito.mockStatic(Bukkit.class)) {
|
||||
// Inject our own Bukkit versions
|
||||
bukkit.when(Bukkit::getVersion).thenReturn(serverSoftwareVersion);
|
||||
bukkit.when(Bukkit::getBukkitVersion).thenReturn(gameVersion);
|
||||
|
||||
PlatformManager manager = new PlatformManager();
|
||||
Platform platform = manager.getPlatform();
|
||||
MinecraftGameVersion minecraftVersion = platform.getGameVersion();
|
||||
|
||||
assertEquals(major, minecraftVersion.getMajorVersion().asInt());
|
||||
assertEquals(minor, minecraftVersion.getMinorVersion().asInt());
|
||||
assertEquals(patch, minecraftVersion.getPatchVersion().asInt());
|
||||
} finally {
|
||||
mcMMO.p = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static @NotNull Stream<Arguments> getGameVersions() {
|
||||
/*
|
||||
* These samples were taken directly from the historical
|
||||
* data of CraftBukkit's pom.xml file:
|
||||
* https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse/pom.xml
|
||||
*
|
||||
* We should be safe to assume that forks follow these conventions and do not mess
|
||||
* with this version number (Spigot, Paper and Tuinity do at least).
|
||||
*/
|
||||
return Stream.of(
|
||||
Arguments.of("1.13.2-R0.1-SNAPSHOT", 1, 13, 2),
|
||||
Arguments.of("1.13-R0.2-SNAPSHOT", 1, 13, 0),
|
||||
Arguments.of("1.13.2-R0.1-SNAPSHOT", 1, 13, 2),
|
||||
Arguments.of("1.13-pre7-R0.1-SNAPSHOT", 1, 13, 0),
|
||||
Arguments.of("1.14-pre5-SNAPSHOT", 1, 14, 0),
|
||||
Arguments.of("1.15-R0.1-SNAPSHOT", 1, 15, 0),
|
||||
Arguments.of("1.16.5-R0.1-SNAPSHOT", 1, 16, 5),
|
||||
Arguments.of("1.17-R0.1-SNAPSHOT", 1, 17, 0)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
//package com.gmail.nossr50.util.skills;
|
||||
//
|
||||
//import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
//import com.google.common.collect.ImmutableList;
|
||||
//import org.junit.Before;
|
||||
//import org.junit.Test;
|
||||
//import org.junit.runner.RunWith;
|
||||
//import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
//import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
|
||||
//import org.powermock.modules.junit4.PowerMockRunner;
|
||||
//
|
||||
//@RunWith(PowerMockRunner.class)
|
||||
//@PrepareForTest(SkillTools.class)
|
||||
//public class SkillToolsTest {
|
||||
//
|
||||
//}
|
32
src/test/java/com/gmail/nossr50/util/text/TextUtilsTest.java
Normal file
32
src/test/java/com/gmail/nossr50/util/text/TextUtilsTest.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package com.gmail.nossr50.util.text;
|
||||
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* This Unit Test checks if Adventure was set up correctly and works as expected.
|
||||
* Normally we can rely on this to be the case. However sometimes our dependencies
|
||||
* lack so far behind that things stop working correctly.
|
||||
* This test ensures that basic functionality is guaranteed to work as we would expect.
|
||||
*
|
||||
* See https://github.com/mcMMO-Dev/mcMMO/pull/4446
|
||||
*
|
||||
*/
|
||||
class TextUtilsTest {
|
||||
|
||||
@Test
|
||||
void testColorizeText() {
|
||||
String inputText = "&4This text should be red.";
|
||||
|
||||
/*
|
||||
* If this method raises an exception, we know Adventure is not set up correctly.
|
||||
* This will also make the test fail and warn us about it.
|
||||
*/
|
||||
TextComponent component = TextUtils.colorizeText(inputText);
|
||||
|
||||
String message = "Looks like Adventure is not working correctly. We likely need to update our dependency!";
|
||||
Assertions.assertEquals(NamedTextColor.DARK_RED, component.color(), message);
|
||||
}
|
||||
}
|
23
src/test/resources/baddatadb.users
Normal file
23
src/test/resources/baddatadb.users
Normal file
@@ -0,0 +1,23 @@
|
||||
mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:
|
||||
ender_vine:434:::33:93:0:115:115:389:216:88:287:130:468:380:944:150:90:0:0:1948:584::2:0:1584896276:1586477151:1585264062:0:1576456374:1534725135:1577535765::404:4207:0:1616024209:HEARTS:3:0:812c10b0-7bbf-49e5-ac53-3f0521eb504b:5:0:
|
||||
electronicboy:225:::1876:16:0:99:137:148:308:109:418:193:430:0:854:0:0:0:0:260:2816::19:0:1604048398:1601216462:1563297488:1533836917:1571449594:1601219209:1601215461::406:4207:0:1617465739:HEARTS:7:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:5:0:
|
||||
z750:1074:::21081:231:0:280:65:156:463:612:742:550:1060:1000:1751:3666:5834:4871:11278:1943:13642::25:460:1613103021:1610212680:1609278207:0:1610076033:1586744907:1610150046::399:7050:0:1613611193:HEARTS:11:0:1594aa76-6ce0-46f6-90b2-83896a829db8:5:0:
|
||||
Aikar:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:1617623810:HEARTS:0:0:6c4ed41d-9936-45da-9f57-b0f4cfa451b4:0:
|
||||
wizjany:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:1617624693:HEARTS:0:0:0609efd6-e9ae-4f6a-bcff-69a6c890192f:0:
|
||||
SpottedLeaf:0:::0:0:0:0:0:0:0:0:0:0:21:0:0:0:0:0:0:0:231::0:0:0:0:0:0:0:0:0::0:0:0:1617628585:HEARTS:0:0:6c002484-c964-4627-8026-9955d0d30aaf:0:0:
|
||||
Cheesy:0:::0:0:0:0:0:0:0:0:0:0:6:0:0:0:0:0:0:0:882::0:0:0:0:0:0:0:0:0::0:0:0:1617636874:HEARTS:0:0:0a5804b3-f127-4962-8b83-f5f3dfe6d8e3:0:0:
|
||||
Mochi:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:1617642310:HEARTS:0:0:468fb276-444f-4c79-bb07-8a7a30f95606:0:
|
||||
Futan:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:1617644058:HEARTS:0:0:98f9e3c2-75ce-448c-b30b-01f93b69f0ca:0:
|
||||
Dave:0:::0:0:0:0:0:0:0:0:0:0:0:0:61:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:1617653877:HEARTS:0:0:23926471-655b-4117-8ee6-7c718677f2e1:0:0:
|
||||
MomShroom:0:::0:0:0:0:0:0:0:0:0:0:1:0:0:0:0:0:0:0:231::0:0:0:0:0:0:0:0:0::0:0:0:1617700103:HEARTS:0:0:eda1c2d5-7cf6-461c-aced-86954675b905:0:0:
|
||||
broccolai:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:1617736110:HEARTS:0:0:8a4f8f1c-8242-4c52-bd63-3a4f6fe85771:0:
|
||||
gabizou:0:::0:0:0:0:0:0:0:0:0:0:6:0:0:0:0:0:692:897:231::0:0:0:0:0:0:0:0:0::0:302:0:1617744451:HEARTS:0:0:fd1ad842-8959-4433-9f09-406da1567f98:0:0:
|
||||
Vera:18:::150:1:769:0:0:0:0:0:0:0:0:0:0:183:0:0:0:540:0::0:0:0:0:0:0:0:0:0::0:0:0:1617744730:HEARTS:0:0:0a95d72c-4316-4b25-a4ad-b0719843d723:0:0:
|
||||
proxy:0:::189:1:0:1:1:0:0:0:0:1:0:36:96:0:0:0:0:181:0::1:0:0:0:0:0:0:0:0::0:0:0:1617792154:HEARTS:1:0:d8531191-e49b-4132-8223-e3b46f8450d2:0:0:
|
||||
chew:4:::1011:0:0:0:0:0:2:0:0:0:0:0:61:0:432:0:0:0:651::0:0:0:0:0:0:0:0:0::0:0:0:1617794539:HEARTS:0:0:58cea4a2-1979-48e4-a171-eaa631376835:0:0:
|
||||
t00thpick1:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:1617798657:HEARTS:0:0:1300f1de-0108-43c3-839f-d40d7e0c7027:0:
|
||||
kashike:1:::756:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:1617826439:HEARTS:0:0:891825c2-2ceb-4b69-82c3-f2dfb47f9a6d:0:0:
|
||||
camm:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:1617830574:HEARTS:0:0:5c34f924-f7f6-4547-9e36-4234133e2162:0:
|
||||
brandonxp4000:0:::0:0:0:0:0:0:0:0:2:0:1:0:181:0:0:0:54:0:231::0:0:0:0:0:0:0:0:0::0:0:0:1617887039:HEARTS:0:0:cbf7122b-0271-4daa-aeaa-3bc44e6dae88:0:0:
|
||||
Tapola:1:::111:0:0:1:0:0:0:0:3:2:0:111:193:0:0:0:1010:92:0::0:0:0:0:0:0:0:0:0::0:0:0:1617886681:HEARTS:0:0:4a21353a-8ca1-436f-9b5f-d2e522dcf79e:0:0:
|
||||
nossr51:baddata:::baddata:baddata:640:baddata:1000:1000:1000:baddata:baddata:baddata:baddata:16:0:500:20273:0:0:0:0::1000:0:0:baddata:1593543012:0:0:0:0::1000:0:0:baddata:IGNORED:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1:0:
|
3
src/test/resources/healthydb.users
Normal file
3
src/test/resources/healthydb.users
Normal file
@@ -0,0 +1,3 @@
|
||||
nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:IGNORED:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999:2020:
|
||||
mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:3030:
|
||||
powerless:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:1337:HEARTS:0:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:5:1600906906:4040:
|
4
src/test/resources/missinglastlogin.users
Normal file
4
src/test/resources/missinglastlogin.users
Normal file
@@ -0,0 +1,4 @@
|
||||
# A single comment line is sometimes at the top of the DB
|
||||
nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:0:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999:
|
||||
mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:
|
||||
powerless:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:1337:HEARTS:0:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:5:1600906906:
|
Reference in New Issue
Block a user