Files
Mindustry/tests/src/test/java/ApplicationTests.java

397 lines
12 KiB
Java
Raw Normal View History

2018-12-27 15:47:17 -05:00
import io.anuke.arc.ApplicationCore;
import io.anuke.arc.backends.headless.HeadlessApplication;
import io.anuke.arc.backends.headless.HeadlessApplicationConfiguration;
2019-02-20 17:54:23 -05:00
import io.anuke.arc.collection.Array;
2018-12-27 15:47:17 -05:00
import io.anuke.arc.math.geom.Point2;
import io.anuke.arc.util.Log;
import io.anuke.arc.util.Time;
2018-10-03 20:58:35 -04:00
import io.anuke.mindustry.Vars;
2019-04-07 14:09:34 -04:00
import io.anuke.mindustry.content.*;
2018-10-03 20:58:35 -04:00
import io.anuke.mindustry.core.GameState.State;
2019-04-07 14:09:34 -04:00
import io.anuke.mindustry.core.*;
import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest;
import io.anuke.mindustry.entities.type.BaseUnit;
2019-02-02 15:59:07 -05:00
import io.anuke.mindustry.entities.type.base.Spirit;
2019-04-07 14:09:34 -04:00
import io.anuke.mindustry.game.*;
2018-10-03 20:58:35 -04:00
import io.anuke.mindustry.io.BundleLoader;
import io.anuke.mindustry.io.SaveIO;
import io.anuke.mindustry.maps.Map;
2019-04-07 14:09:34 -04:00
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.world.*;
import org.junit.jupiter.api.*;
2018-10-03 20:58:35 -04:00
import static io.anuke.mindustry.Vars.*;
import static org.junit.jupiter.api.Assertions.*;
public class ApplicationTests{
static Map testMap;
2019-04-07 14:53:53 -04:00
static boolean initialized;
2018-10-03 20:58:35 -04:00
@BeforeAll
static void launchApplication(){
2019-04-07 14:53:53 -04:00
//only gets called once
if(initialized) return;
initialized = true;
2018-10-03 20:58:35 -04:00
try{
boolean[] begins = {false};
Throwable[] exceptionThrown = {null};
Log.setUseColors(false);
2018-12-27 15:47:17 -05:00
ApplicationCore core = new ApplicationCore(){
2018-10-03 20:58:35 -04:00
@Override
2018-12-27 15:47:17 -05:00
public void setup(){
2018-10-03 20:58:35 -04:00
Vars.init();
headless = true;
BundleLoader.load();
content.load();
2018-12-27 15:47:17 -05:00
add(logic = new Logic());
add(world = new World());
add(netServer = new NetServer());
2019-01-17 19:28:25 -05:00
content.initialize(Content::init);
2018-10-03 20:58:35 -04:00
}
@Override
2018-12-27 15:47:17 -05:00
public void init(){
super.init();
2018-10-03 20:58:35 -04:00
begins[0] = true;
testMap = world.maps.loadInternalMap("groundZero");
2018-10-03 20:58:35 -04:00
}
};
HeadlessApplicationConfiguration config = new HeadlessApplicationConfiguration();
2018-12-27 15:47:17 -05:00
new HeadlessApplication(core, config);
2018-10-03 20:58:35 -04:00
for(Thread thread : Thread.getAllStackTraces().keySet()){
if(thread.getName().equals("HeadlessApplication")){
thread.setUncaughtExceptionHandler((t, throwable) -> exceptionThrown[0] = throwable);
break;
}
}
while(!begins[0]){
if(exceptionThrown[0] != null){
fail(exceptionThrown[0]);
}
Thread.sleep(10);
}
}catch(Throwable r){
fail(r);
}
}
@BeforeEach
void resetWorld(){
2019-04-08 09:03:18 -04:00
Time.setDeltaProvider(() -> 1f);
2018-10-03 20:58:35 -04:00
logic.reset();
state.set(State.menu);
}
@Test
void initialization(){
2018-10-07 23:22:54 -04:00
assertNotNull(logic);
assertNotNull(world);
2018-10-03 20:58:35 -04:00
assertTrue(content.getContentMap().length > 0);
}
@Test
void playMap(){
world.loadMap(testMap);
2018-10-03 20:58:35 -04:00
}
@Test
void spawnWaves(){
world.loadMap(testMap);
2019-04-07 14:53:53 -04:00
assertTrue(world.spawner.countSpawns() > 0, "No spawns present.");
2018-10-03 20:58:35 -04:00
logic.runWave();
//force trigger delayed spawns
Time.setDeltaProvider(() -> 1000f);
Time.update();
Time.update();
Time.setDeltaProvider(() -> 1f);
2018-10-03 20:58:35 -04:00
unitGroups[waveTeam.ordinal()].updateEvents();
2019-04-07 14:53:53 -04:00
assertFalse(unitGroups[waveTeam.ordinal()].isEmpty(), "No enemies spawned.");
2018-10-03 20:58:35 -04:00
}
@Test
void createMap(){
Tile[][] tiles = world.createTiles(8, 8);
world.beginMapLoad();
for(int x = 0; x < tiles.length; x++){
for(int y = 0; y < tiles[0].length; y++){
tiles[x][y] = new Tile(x, y, (byte)0, (byte)0);
}
}
world.endMapLoad();
}
@Test
void multiblock(){
createMap();
int bx = 4;
int by = 4;
2019-01-31 15:33:07 -05:00
world.setBlock(world.tile(bx, by), Blocks.coreShard, Team.blue);
2018-10-07 23:22:54 -04:00
assertEquals(world.tile(bx, by).getTeam(), Team.blue);
2019-04-08 09:03:18 -04:00
for(int x = bx - 1; x <= bx + 1; x++){
for(int y = by - 1; y <= by + 1; y++){
2018-10-03 20:58:35 -04:00
if(x == bx && by == y){
2019-01-31 15:33:07 -05:00
assertEquals(world.tile(x, y).block(), Blocks.coreShard);
2018-10-03 20:58:35 -04:00
}else{
assertTrue(world.tile(x, y).block() == Blocks.part && world.tile(x, y).getLinked() == world.tile(bx, by));
2018-10-03 20:58:35 -04:00
}
}
}
}
@Test
void blockInventories(){
multiblock();
Tile tile = world.tile(4, 4);
tile.entity.items.add(Items.coal, 5);
tile.entity.items.add(Items.titanium, 50);
2018-10-07 23:22:54 -04:00
assertEquals(tile.entity.items.total(), 55);
tile.entity.items.remove(Items.phasefabric, 10);
2018-10-03 20:58:35 -04:00
tile.entity.items.remove(Items.titanium, 10);
2018-10-07 23:22:54 -04:00
assertEquals(tile.entity.items.total(), 45);
2018-10-03 20:58:35 -04:00
}
@Test
void timers(){
boolean[] ran = {false};
Time.run(1.9999f, () -> ran[0] = true);
2018-10-03 20:58:35 -04:00
Time.update();
2018-10-03 20:58:35 -04:00
assertFalse(ran[0]);
Time.update();
2018-10-03 20:58:35 -04:00
assertTrue(ran[0]);
}
@Test
void manyTimers(){
int runs = 100000;
int[] total = {0};
for(int i = 0; i < runs; i++){
Time.run(0.999f, () -> total[0]++);
}
assertEquals(0, total[0]);
Time.update();
assertEquals(runs, total[0]);
}
@Test
void longTimers(){
Time.setDeltaProvider(() -> Float.MAX_VALUE);
Time.update();
int steps = 100;
float delay = 100000f;
Time.setDeltaProvider(() -> delay / steps + 0.01f);
int runs = 100000;
int[] total = {0};
for(int i = 0; i < runs; i++){
Time.run(delay, () -> total[0]++);
}
assertEquals(0, total[0]);
for(int i = 0; i < steps; i++){
Time.update();
}
assertEquals(runs, total[0]);
}
2018-10-03 20:58:35 -04:00
@Test
void save(){
world.loadMap(testMap);
assertTrue(state.teams.get(defaultTeam).cores.size > 0);
2018-10-03 20:58:35 -04:00
SaveIO.saveToSlot(0);
}
@Test
void load(){
world.loadMap(testMap);
2018-10-03 20:58:35 -04:00
Map map = world.getMap();
SaveIO.saveToSlot(0);
resetWorld();
SaveIO.loadFromSlot(0);
2019-03-11 11:43:23 -04:00
assertEquals(world.width(), map.width);
assertEquals(world.height(), map.height);
assertTrue(state.teams.get(defaultTeam).cores.size > 0);
2018-10-03 20:58:35 -04:00
}
2018-10-04 17:59:16 -04:00
@Test
2018-11-23 12:40:36 -05:00
void inventoryDeposit(){
2019-01-12 16:55:24 -05:00
depositTest(Blocks.surgeSmelter, Items.copper);
2019-01-07 18:39:06 -05:00
depositTest(Blocks.vault, Items.copper);
depositTest(Blocks.thoriumReactor, Items.thorium);
2018-11-23 12:40:36 -05:00
}
@Test
void edges(){
2018-12-26 13:22:31 -05:00
Point2[] edges = Edges.getEdges(1);
assertEquals(edges[0], new Point2(1, 0));
assertEquals(edges[1], new Point2(0, 1));
assertEquals(edges[2], new Point2(-1, 0));
assertEquals(edges[3], new Point2(0, -1));
2018-10-04 17:59:16 -04:00
2018-12-26 13:22:31 -05:00
Point2[] edges2 = Edges.getEdges(2);
2018-10-07 23:22:54 -04:00
assertEquals(8, edges2.length);
2018-10-04 17:59:16 -04:00
}
2018-11-23 12:40:36 -05:00
@Test
void buildingOverlap(){
initBuilding();
2019-04-08 09:03:18 -04:00
Spirit d1 = (Spirit)UnitTypes.spirit.create(Team.blue);
Spirit d2 = (Spirit)UnitTypes.spirit.create(Team.blue);
d1.set(10f, 20f);
d2.set(10f, 20f);
d1.addBuildRequest(new BuildRequest(0, 0, 0, Blocks.copperWallLarge));
d2.addBuildRequest(new BuildRequest(1, 1, 0, Blocks.copperWallLarge));
Time.setDeltaProvider(() -> 9999999f);
2019-02-02 15:59:07 -05:00
d1.updateBuilding();
d2.updateBuilding();
2019-01-07 18:39:06 -05:00
assertEquals(Blocks.copperWallLarge, world.tile(0, 0).block());
assertEquals(Blocks.air, world.tile(2, 2).block());
assertEquals(Blocks.part, world.tile(1, 1).block());
}
2019-02-20 17:54:23 -05:00
@Test
void zoneEmptyWaves(){
for(Zone zone : content.zones()){
2019-02-22 23:16:50 -05:00
Array<SpawnGroup> spawns = zone.rules.get().spawns;
for(int i = 1; i <= 100; i++){
int total = 0;
for(SpawnGroup spawn : spawns){
total += spawn.getUnitsSpawned(i);
}
assertNotEquals(0, total, "Zone " + zone + " has no spawned enemies at wave " + i);
}
2019-02-20 17:54:23 -05:00
}
}
@Test
void zoneOverflowWaves(){
for(Zone zone : content.zones()){
2019-02-22 23:16:50 -05:00
Array<SpawnGroup> spawns = zone.rules.get().spawns;
2019-02-20 17:54:23 -05:00
2019-02-22 23:16:50 -05:00
for(int i = 1; i <= 40; i++){
int total = 0;
for(SpawnGroup spawn : spawns){
total += spawn.getUnitsSpawned(i);
}
2019-02-20 17:54:23 -05:00
2019-02-22 23:16:50 -05:00
if(total >= 140){
fail("Zone '" + zone + "' has too many spawned enemies at wave " + i + " : " + total);
}
2019-02-20 17:54:23 -05:00
}
}
}
@Test
void buildingDestruction(){
initBuilding();
2019-04-08 09:03:18 -04:00
Spirit d1 = (Spirit)UnitTypes.spirit.create(Team.blue);
Spirit d2 = (Spirit)UnitTypes.spirit.create(Team.blue);
d1.set(10f, 20f);
d2.set(10f, 20f);
d1.addBuildRequest(new BuildRequest(0, 0, 0, Blocks.copperWallLarge));
d2.addBuildRequest(new BuildRequest(1, 1));
Time.setDeltaProvider(() -> 3f);
2019-02-02 15:59:07 -05:00
d1.updateBuilding();
Time.setDeltaProvider(() -> 1f);
2019-02-02 15:59:07 -05:00
d2.updateBuilding();
assertEquals(content.getByName(ContentType.block, "build2"), world.tile(0, 0).block());
Time.setDeltaProvider(() -> 9999f);
2019-02-02 15:59:07 -05:00
d1.updateBuilding();
d2.updateBuilding();
assertEquals(Blocks.air, world.tile(0, 0).block());
assertEquals(Blocks.air, world.tile(2, 2).block());
assertEquals(Blocks.air, world.tile(1, 1).block());
}
2019-04-01 11:57:43 -04:00
@Test
void allBlockTest(){
Tile[][] tiles = world.createTiles(256 + 20, 10);
world.beginMapLoad();
for(int x = 0; x < tiles.length; x++){
for(int y = 0; y < tiles[0].length; y++){
tiles[x][y] = new Tile(x, y, Blocks.stone.id, (byte)0);
}
}
int i = 0;
2019-04-08 09:03:18 -04:00
for(int x = 5; x < tiles.length && i < content.blocks().size; ){
2019-04-01 11:57:43 -04:00
Block block = content.block(i++);
if(block.buildVisibility.get()){
tiles[x][5].setBlock(block);
x += block.size;
}
}
world.endMapLoad();
for(int x = 0; x < tiles.length; x++){
for(int y = 0; y < tiles[0].length; y++){
Tile tile = world.tile(x, y);
if(tile.entity != null){
try{
tile.entity.update();
}catch(Throwable t){
fail("Failed to update block '" + tile.block() + "'.", t);
}
assertEquals(tile.block(), tile.entity.block);
assertEquals(tile.block().health, tile.entity.health);
}
}
}
}
void initBuilding(){
createMap();
Tile core = world.tile(5, 5);
2019-01-31 15:33:07 -05:00
world.setBlock(core, Blocks.coreShard, Team.blue);
for(Item item : content.items()){
core.entity.items.set(item, 3000);
}
assertEquals(core, state.teams.get(Team.blue).cores.first());
}
2018-11-23 12:40:36 -05:00
void depositTest(Block block, Item item){
2018-12-29 12:05:29 -05:00
BaseUnit unit = UnitTypes.spirit.create(Team.none);
2018-11-23 12:40:36 -05:00
Tile tile = new Tile(0, 0, Blocks.air.id, block.id);
int capacity = tile.block().itemCapacity;
int deposited = tile.block().acceptStack(item, capacity - 1, tile, unit);
assertEquals(capacity - 1, deposited);
tile.block().handleStack(item, capacity - 1, tile, unit);
assertEquals(tile.entity.items.get(item), capacity - 1);
int overflow = tile.block().acceptStack(item, 10, tile, unit);
assertEquals(1, overflow);
tile.block().handleStack(item, 1, tile, unit);
assertEquals(capacity, tile.entity.items.get(item));
}
2018-10-03 20:58:35 -04:00
}