Skip to content

Commit

Permalink
Add game tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rubensworks committed Dec 18, 2024
1 parent fce7e84 commit c5f0b72
Show file tree
Hide file tree
Showing 12 changed files with 1,366 additions and 8 deletions.
9 changes: 3 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,9 @@ jobs:
GITHUB_USER: ${{ github.actor }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: 'Test'
env:
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
if: ${{ env.COVERALLS_REPO_TOKEN }}
run: ./gradlew test jacocoTestReport coveralls
- name: 'Game Test'
run: ./gradlew runGameTestServer
run: ./gradlew test runGameTestServer jacocoTestReport
- name: 'Submit coverage results'
uses: coverallsapp/github-action@v2
- name: 'Deploy as GitHub CI artifacts'
uses: actions/upload-artifact@v4
with:
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## Integrated Tunnels

[![Build Status](https://github.com/CyclopsMC/IntegratedTunnels/workflows/CI/badge.svg)](https://github.com/CyclopsMC/IntegratedTunnels/actions?query=workflow%3ACI)
[![Coverage Status](https://coveralls.io/repos/github/CyclopsMC/IntegratedTunnels/badge.svg)](https://coveralls.io/github/CyclopsMC/IntegratedTunnels)
[![Download](https://img.shields.io/static/v1?label=Maven&message=GitHub%20Packages&color=blue)](https://github.com/CyclopsMC/packages/packages/770038)
[![Crowdin](https://badges.crowdin.net/cyclopsmc-integratedtunnels/localized.svg)](https://crowdin.com/project/cyclopsmc-integratedtunnels)
[![CurseForge](http://cf.way2muchnoise.eu/full_251389_downloads.svg)](http://minecraft.curseforge.com/projects/251389)
Expand Down
13 changes: 13 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -401,12 +401,25 @@ idea {
}

jacocoTestReport {
// Include unit and game test coverage
executionData fileTree(project.buildDir).include("jacoco/*.exec")
reports {
xml.required = true
html.required = true
}
}

// Also measure coverage for game tests
tasks.whenTaskAdded { task ->
if (task.name.equals('runGameTestServer')) {
jacocoTestReport.dependsOn test, task
jacoco {
toolVersion = "0.8.12"
applyTo task
}
}
}

spotless {
java {
target 'src/*/java/org/cyclops/**/*.java'
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ neoforge_loader_version_range=[4,)
neoforge_update_json_url=https://raw.githubusercontent.com/CyclopsMC/Versions/master/neoforge_update/integrated-tunnels.json

# Dependencies
cyclopscore_version=1.25.1-627
integrateddynamics_version=1.23.2-832
cyclopscore_version=1.25.5-643
integrateddynamics_version=1.24.1-993
integratedtunnelscompat_version=1.0.0-45
commoncapabilities_version=2.9.3-147
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
package org.cyclops.integratedtunnels.gametest;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.gametest.framework.GameTest;
import net.minecraft.gametest.framework.GameTestHelper;
import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.gametest.GameTestHolder;
import net.neoforged.neoforge.gametest.PrefixGameTestTemplate;
import org.cyclops.integrateddynamics.RegistryEntries;
import org.cyclops.integrateddynamics.api.part.PartPos;
import org.cyclops.integrateddynamics.api.part.write.IPartStateWriter;
import org.cyclops.integrateddynamics.blockentity.BlockEntityEnergyBattery;
import org.cyclops.integrateddynamics.core.block.IgnoredBlockStatus;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeLong;
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypes;
import org.cyclops.integrateddynamics.core.helper.PartHelpers;
import org.cyclops.integratedtunnels.Reference;
import org.cyclops.integratedtunnels.part.PartTypes;
import org.cyclops.integratedtunnels.part.aspect.TunnelAspects;

import static org.cyclops.integrateddynamics.gametest.GameTestHelpersIntegratedDynamics.createVariableForValue;
import static org.cyclops.integrateddynamics.gametest.GameTestHelpersIntegratedDynamics.placeVariableInWriter;

@GameTestHolder(Reference.MOD_ID)
@PrefixGameTestTemplate(false)
public class GameTestsEnergy {

public static final String TEMPLATE_EMPTY = "empty10";
public static final int TIMEOUT = 2000;
public static final BlockPos POS = BlockPos.ZERO.offset(2, 0, 2);

@GameTest(template = TEMPLATE_EMPTY, timeoutTicks = TIMEOUT)
public void testEnergyImporterToInterfaceBoolean(GameTestHelper helper) {
// Place cable
helper.setBlock(POS, RegistryEntries.BLOCK_CABLE.value());
helper.setBlock(POS.east(), RegistryEntries.BLOCK_CABLE.value());

// Place energy importer
PartHelpers.addPart(helper.getLevel(), helper.absolutePos(POS), Direction.WEST, PartTypes.IMPORTER_ENERGY, new ItemStack(PartTypes.IMPORTER_ENERGY.getItem()));

// Place energy interface
PartHelpers.addPart(helper.getLevel(), helper.absolutePos(POS.east()), Direction.EAST, PartTypes.INTERFACE_ENERGY, new ItemStack(PartTypes.INTERFACE_ENERGY.getItem()));

// Place batteries
helper.setBlock(POS.west(), RegistryEntries.BLOCK_ENERGY_BATTERY.get());
helper.setBlock(POS.east().east(), RegistryEntries.BLOCK_ENERGY_BATTERY.get());

// Insert energy in interface battery
BlockEntityEnergyBattery batteryIn = helper.getBlockEntity(POS.west());
batteryIn.setEnergyStored(10_000);

// Place empty variable in importer
ItemStack variableAspect = new ItemStack(RegistryEntries.ITEM_VARIABLE);
placeVariableInWriter(helper.getLevel(), PartPos.of(helper.getLevel(), helper.absolutePos(POS), Direction.WEST), TunnelAspects.Write.Energy.BOOLEAN_IMPORT, variableAspect);

helper.succeedWhen(() -> {
// Check if energy is moved
BlockEntityEnergyBattery batteryOut = helper.getBlockEntity(POS.east().east());
helper.assertValueEqual(batteryOut.getEnergyStored(), 10_000, "Battery out does not contain energy");
helper.assertValueEqual(batteryIn.getEnergyStored(), 0, "Battery in was not drained");

// Check importer state
IPartStateWriter partStateWriter = (IPartStateWriter) PartHelpers.getPart(PartPos.of(helper.getLevel(), helper.absolutePos(POS), Direction.WEST)).getState();
helper.assertFalse(partStateWriter.isDeactivated(), "Importer is deactivated");
helper.assertValueEqual(
PartTypes.IMPORTER_ENERGY.getBlockState(PartHelpers.getPartContainerChecked(PartPos.of(helper.getLevel(), helper.absolutePos(POS), Direction.WEST)), Direction.WEST).getValue(IgnoredBlockStatus.STATUS),
IgnoredBlockStatus.Status.ACTIVE,
"Block status is incorrect"
);
helper.assertValueEqual(partStateWriter.getActiveAspect(), TunnelAspects.Write.Energy.BOOLEAN_IMPORT, "Active aspect is incorrect");
helper.assertTrue(partStateWriter.getErrors(TunnelAspects.Write.Energy.BOOLEAN_IMPORT).isEmpty(), "Active aspect has errors");
});
}

@GameTest(template = TEMPLATE_EMPTY, timeoutTicks = TIMEOUT)
public void testEnergyInterfaceToExporterBoolean(GameTestHelper helper) {
// Place cable
helper.setBlock(POS, RegistryEntries.BLOCK_CABLE.value());
helper.setBlock(POS.east(), RegistryEntries.BLOCK_CABLE.value());

// Place energy interface
PartHelpers.addPart(helper.getLevel(), helper.absolutePos(POS), Direction.WEST, PartTypes.INTERFACE_ENERGY, new ItemStack(PartTypes.INTERFACE_ENERGY.getItem()));

// Place energy exporter
PartHelpers.addPart(helper.getLevel(), helper.absolutePos(POS.east()), Direction.EAST, PartTypes.EXPORTER_ENERGY, new ItemStack(PartTypes.EXPORTER_ENERGY.getItem()));

// Place batteries
helper.setBlock(POS.west(), RegistryEntries.BLOCK_ENERGY_BATTERY.get());
helper.setBlock(POS.east().east(), RegistryEntries.BLOCK_ENERGY_BATTERY.get());

// Insert energy in interface battery
BlockEntityEnergyBattery batteryIn = helper.getBlockEntity(POS.west());
batteryIn.setEnergyStored(10_000);

// Place empty variable in exporter
ItemStack variableAspect = new ItemStack(RegistryEntries.ITEM_VARIABLE);
placeVariableInWriter(helper.getLevel(), PartPos.of(helper.getLevel(), helper.absolutePos(POS.east()), Direction.EAST), TunnelAspects.Write.Energy.BOOLEAN_EXPORT, variableAspect);

helper.succeedWhen(() -> {
// Check if energy is moved
BlockEntityEnergyBattery batteryOut = helper.getBlockEntity(POS.east().east());
helper.assertValueEqual(batteryOut.getEnergyStored(), 10_000, "Battery out does not contain energy");
helper.assertValueEqual(batteryIn.getEnergyStored(), 0, "Battery in was not drained");

// Check importer state
IPartStateWriter partStateWriter = (IPartStateWriter) PartHelpers.getPart(PartPos.of(helper.getLevel(), helper.absolutePos(POS.east()), Direction.EAST)).getState();
helper.assertFalse(partStateWriter.isDeactivated(), "Exporter is deactivated");
helper.assertValueEqual(
PartTypes.EXPORTER_ENERGY.getBlockState(PartHelpers.getPartContainerChecked(PartPos.of(helper.getLevel(), helper.absolutePos(POS.east()), Direction.EAST)), Direction.EAST).getValue(IgnoredBlockStatus.STATUS),
IgnoredBlockStatus.Status.ACTIVE,
"Block status is incorrect"
);
helper.assertValueEqual(partStateWriter.getActiveAspect(), TunnelAspects.Write.Energy.BOOLEAN_EXPORT, "Active aspect is incorrect");
helper.assertTrue(partStateWriter.getErrors(TunnelAspects.Write.Energy.BOOLEAN_EXPORT).isEmpty(), "Active aspect has errors");
});
}

@GameTest(template = TEMPLATE_EMPTY, timeoutTicks = TIMEOUT)
public void testEnergyImporterToInterfaceToExporterBoolean(GameTestHelper helper) {
// Place cable
helper.setBlock(POS, RegistryEntries.BLOCK_CABLE.value());
helper.setBlock(POS.east(), RegistryEntries.BLOCK_CABLE.value());

// Place item importer
PartHelpers.addPart(helper.getLevel(), helper.absolutePos(POS), Direction.WEST, PartTypes.IMPORTER_ENERGY, new ItemStack(PartTypes.IMPORTER_ENERGY.getItem()));

// Place item interface
PartHelpers.addPart(helper.getLevel(), helper.absolutePos(POS.east()), Direction.EAST, PartTypes.INTERFACE_ENERGY, new ItemStack(PartTypes.INTERFACE_ENERGY.getItem()));

// Place item exporter
PartHelpers.addPart(helper.getLevel(), helper.absolutePos(POS.east()), Direction.NORTH, PartTypes.EXPORTER_ENERGY, new ItemStack(PartTypes.EXPORTER_ENERGY.getItem()));

// Place batteries
helper.setBlock(POS.west(), RegistryEntries.BLOCK_ENERGY_BATTERY.get());
helper.setBlock(POS.east().east(), RegistryEntries.BLOCK_ENERGY_BATTERY.get());
helper.setBlock(POS.east().north(), RegistryEntries.BLOCK_ENERGY_BATTERY.get());

// Insert energy in interface battery
BlockEntityEnergyBattery batteryIn = helper.getBlockEntity(POS.west());
batteryIn.setEnergyStored(10_000);

// Place empty variable in importer
ItemStack variableAspectImporter = new ItemStack(RegistryEntries.ITEM_VARIABLE);
placeVariableInWriter(helper.getLevel(), PartPos.of(helper.getLevel(), helper.absolutePos(POS), Direction.WEST), TunnelAspects.Write.Energy.BOOLEAN_IMPORT, variableAspectImporter);

// Place empty variable in exporter
ItemStack variableAspectExporter = new ItemStack(RegistryEntries.ITEM_VARIABLE);
placeVariableInWriter(helper.getLevel(), PartPos.of(helper.getLevel(), helper.absolutePos(POS.east()), Direction.NORTH), TunnelAspects.Write.Energy.BOOLEAN_EXPORT, variableAspectExporter);

helper.succeedWhen(() -> {
// Check if energy is moved
BlockEntityEnergyBattery batteryInterface = helper.getBlockEntity(POS.east().east());
BlockEntityEnergyBattery batteryOut = helper.getBlockEntity(POS.east().north());
helper.assertValueEqual(batteryInterface.getEnergyStored(), 0, "Battery interface was not drained");
helper.assertValueEqual(batteryOut.getEnergyStored(), 10_000, "Battery out does not contain energy");
helper.assertValueEqual(batteryIn.getEnergyStored(), 0, "Battery in was not drained");
});
}

@GameTest(template = TEMPLATE_EMPTY, timeoutTicks = TIMEOUT)
public void testEnergyImporterToInterfaceLong(GameTestHelper helper) {
// Place cable
helper.setBlock(POS, RegistryEntries.BLOCK_CABLE.value());
helper.setBlock(POS.east(), RegistryEntries.BLOCK_CABLE.value());

// Place item importer
PartHelpers.addPart(helper.getLevel(), helper.absolutePos(POS), Direction.WEST, PartTypes.IMPORTER_ENERGY, new ItemStack(PartTypes.IMPORTER_ENERGY.getItem()));

// Place item interface
PartHelpers.addPart(helper.getLevel(), helper.absolutePos(POS.east()), Direction.EAST, PartTypes.INTERFACE_ENERGY, new ItemStack(PartTypes.INTERFACE_ENERGY.getItem()));

// Place batteries
helper.setBlock(POS.west(), RegistryEntries.BLOCK_ENERGY_BATTERY.get());
helper.setBlock(POS.east().east(), RegistryEntries.BLOCK_ENERGY_BATTERY.get());

// Insert energy in importer battery
BlockEntityEnergyBattery batteryIn = helper.getBlockEntity(POS.west());
batteryIn.setEnergyStored(10_000);

// Place empty variable in importer
ItemStack variableAspect = createVariableForValue(helper.getLevel(), ValueTypes.LONG, ValueTypeLong.ValueLong.of(10));
placeVariableInWriter(helper.getLevel(), PartPos.of(helper.getLevel(), helper.absolutePos(POS), Direction.WEST), TunnelAspects.Write.Energy.LONG_IMPORT, variableAspect);

helper.succeedWhen(() -> {
// Check if energy is moved
BlockEntityEnergyBattery batteryOut = helper.getBlockEntity(POS.east().east());
helper.assertValueEqual(batteryOut.getEnergyStored(), 10_000, "Battery out does not contain energy");
helper.assertValueEqual(batteryIn.getEnergyStored(), 0, "Battery in was not drained");
});
}

}
Loading

0 comments on commit c5f0b72

Please sign in to comment.