Mindustry/tests/src/test/java/power/ItemLiquidGeneratorTests.java
Timmeey86 1f8751054c Tested/fixed delta calculations
Tests now use a fixed delta of 0.5 to make sure calculations work with deltas different from 1.0
2018-11-28 11:04:08 +01:00

119 lines
6.5 KiB
Java

package power;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.content.Liquids;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.power.BurnerGenerator;
import io.anuke.mindustry.world.blocks.power.ItemGenerator;
import io.anuke.mindustry.world.blocks.power.ItemLiquidGenerator;
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.DynamicTest.dynamicTest;
/**
* This class tests ItemLiquidGenerators. Currently, testing is only performed on the BurnerGenerator subclass,
* which means only power calculations based on flammability are tested.
* All tests are run with a fixed delta of 0.5 so delta considerations can be tested as well.
* Additionally, each PowerGraph::update() call will have its own thread frame, i.e. the method will never be called twice within the same frame.
* Both of these constraints are handled by FakeThreadHandler within PowerTestFixture.
* Any power amount (produced, consumed, buffered) should be affected by FakeThreadHandler.fakeDelta but satisfaction should not!
*/
public class ItemLiquidGeneratorTests extends PowerTestFixture{
private ItemLiquidGenerator generator;
private Tile tile;
private ItemGenerator.ItemGeneratorEntity entity;
private final float fakeLiquidPowerMultiplier = 2.0f;
private final float fakeItemDuration = 0.5f;
private final float maximumLiquidUsage = 0.5f;
@BeforeEach
public void createBurnerGenerator(){
// Use a burner generator instead of a custom ItemLiquidGenerator subclass since we would implement abstract methods the same way.
generator = new BurnerGenerator("fakegen"){{
powerProduction = 0.1f;
itemDuration = 60f;
liquidPowerMultiplier = fakeLiquidPowerMultiplier;
itemDuration = fakeItemDuration;
maxLiquidGenerate = maximumLiquidUsage;
}};
tile = createFakeTile(0, 0, generator);
entity = tile.entity();
}
/** Tests the consumption and efficiency when being supplied with liquids. */
@TestFactory
DynamicTest[] testLiquidConsumption(){
return new DynamicTest[]{
dynamicTest("01", () -> test_liquidConsumption(Liquids.oil, 0.0f, "No liquids provided")),
dynamicTest("02", () -> test_liquidConsumption(Liquids.oil, maximumLiquidUsage / 4.0f, "Low oil provided")),
dynamicTest("03", () -> test_liquidConsumption(Liquids.oil, maximumLiquidUsage * 1.0f, "Sufficient oil provided")),
dynamicTest("04", () -> test_liquidConsumption(Liquids.oil, maximumLiquidUsage * 2.0f, "Excess oil provided"))
// Note: The generator will decline any other liquid since it's not flammable
};
}
void test_liquidConsumption(Liquid liquid, float availableLiquidAmount, String parameterDescription){
final float baseEfficiency = fakeLiquidPowerMultiplier * liquid.flammability;
final float expectedEfficiency = Math.min(1.0f, availableLiquidAmount / maximumLiquidUsage) * baseEfficiency;
final float expectedConsumptionPerTick = Math.min(maximumLiquidUsage, availableLiquidAmount);
final float expectedRemainingLiquidAmount = Math.max(0.0f, availableLiquidAmount - expectedConsumptionPerTick * FakeThreadHandler.fakeDelta);
assertTrue(generator.acceptLiquid(tile, null, liquid, availableLiquidAmount), parameterDescription + ": Liquids which will be declined by the generator don't need to be tested - The code won't be called for those cases.");
// Reset liquids since BeforeEach will not be called between dynamic tests
for(Liquid tmpLiquid : Vars.content.liquids()){
entity.liquids.reset(tmpLiquid, 0.0f);
}
entity.liquids.add(liquid, availableLiquidAmount);
entity.cons.update(tile.entity);
assertTrue(entity.cons.valid());
// Perform an update on the generator once - This should use up any resource up to the maximum liquid usage
generator.update(tile);
assertEquals(expectedRemainingLiquidAmount, entity.liquids.get(liquid), parameterDescription + ": Remaining liquid amount mismatch.");
assertEquals(expectedEfficiency, entity.productionEfficiency, parameterDescription + ": Efficiency mismatch.");
}
/** Tests the consumption and efficiency when being supplied with items. */
@TestFactory
DynamicTest[] testItemConsumption(){
return new DynamicTest[]{
dynamicTest("01", () -> test_itemConsumption(Items.coal, 0, "No items provided")),
dynamicTest("02", () -> test_itemConsumption(Items.coal, 1, "Sufficient coal provided")),
dynamicTest("03", () -> test_itemConsumption(Items.coal, 10, "Excess coal provided")),
dynamicTest("04", () -> test_itemConsumption(Items.blastCompound, 1, "Blast compound provided")),
//dynamicTest("03", () -> test_itemConsumption(Items.plastanium, 1, "Plastanium provided")), // Not accepted by generator due to low flammability
dynamicTest("05", () -> test_itemConsumption(Items.biomatter, 1, "Biomatter provided")),
dynamicTest("06", () -> test_itemConsumption(Items.pyratite, 1, "Pyratite provided"))
};
}
void test_itemConsumption(Item item, int amount, String parameterDescription){
final float expectedEfficiency = Math.min(1.0f, amount > 0 ? item.flammability : 0f);
final float expectedRemainingItemAmount = Math.max(0, amount - 1);
assertTrue(generator.acceptItem(item, tile, null), parameterDescription + ": Items which will be declined by the generator don't need to be tested - The code won't be called for those cases.");
// Reset items since BeforeEach will not be called between dynamic tests
entity.items.clear();
if(amount > 0){
entity.items.add(item, amount);
}
entity.cons.update(tile.entity);
assertTrue(entity.cons.valid());
// Perform an update on the generator once - This should use up one or zero items - dependent on if the item is accepted and available or not.
generator.update(tile);
assertEquals(expectedRemainingItemAmount, entity.items.get(item), parameterDescription + ": Remaining item amount mismatch.");
assertEquals(expectedEfficiency, entity.productionEfficiency, parameterDescription + ": Efficiency mismatch.");
}
}