Skip to content

Commit 4149afd

Browse files
committed
Add game tests
1 parent d9c195e commit 4149afd

File tree

8 files changed

+188
-9
lines changed

8 files changed

+188
-9
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,9 @@ jobs:
5555
GITHUB_USER: ${{ github.actor }}
5656
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
5757
- name: 'Test'
58-
env:
59-
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
60-
if: ${{ env.COVERALLS_REPO_TOKEN }}
61-
run: ./gradlew test jacocoTestReport coveralls
62-
- name: 'Game Test'
63-
run: ./gradlew runGameTestServer
58+
run: ./gradlew test runGameTestServer jacocoTestReport
59+
- name: 'Submit coverage results'
60+
uses: coverallsapp/github-action@v2
6461
- name: 'Deploy as GitHub CI artifacts'
6562
uses: actions/upload-artifact@v4
6663
with:

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
## Integrated Scripting
22

33
[![Build Status](https://github.com/CyclopsMC/IntegratedScripting/workflows/CI/badge.svg)](https://github.com/CyclopsMC/IntegratedScripting/actions?query=workflow%3ACI)
4+
[![Coverage Status](https://coveralls.io/repos/github/CyclopsMC/IntegratedScripting/badge.svg)](https://coveralls.io/github/CyclopsMC/IntegratedScripting)
45
[![Download](https://img.shields.io/static/v1?label=Maven&message=GitHub%20Packages&color=blue)](https://github.com/CyclopsMC/packages/packages/1901862)
56
[![Crowdin](https://badges.crowdin.net/integratedscripting/localized.svg)](https://crowdin.com/project/integratedscripting)
67
[![CurseForge](http://cf.way2muchnoise.eu/full_889785_downloads.svg)](https://minecraft.curseforge.com/projects/integrated-scripting)

build.gradle

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,12 +383,25 @@ idea {
383383
}
384384

385385
jacocoTestReport {
386+
// Include unit and game test coverage
387+
executionData fileTree(project.buildDir).include("jacoco/*.exec")
386388
reports {
387389
xml.required = true
388390
html.required = true
389391
}
390392
}
391393

394+
// Also measure coverage for game tests
395+
tasks.whenTaskAdded { task ->
396+
if (task.name.equals('runGameTestServer')) {
397+
jacocoTestReport.dependsOn test, task
398+
jacoco {
399+
toolVersion = "0.8.12"
400+
applyTo task
401+
}
402+
}
403+
}
404+
392405
spotless {
393406
java {
394407
target 'src/*/java/org/cyclops/**/*.java'

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@ neoforge_loader_version_range=[4,)
2626
neoforge_update_json_url=https://raw.githubusercontent.com/CyclopsMC/Versions/master/neoforge_update/integrated-scripting.json
2727

2828
# Dependencies
29-
cyclopscore_version=1.25.1-627
30-
integrateddynamics_version=1.23.2-832
29+
cyclopscore_version=1.25.5-643
30+
integrateddynamics_version=1.24.1-993
3131
commoncapabilities_version=2.9.3-147

src/main/java/org/cyclops/integratedscripting/RegistryEntries.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@
1111
import org.cyclops.integrateddynamics.blockentity.BlockEntityVariablestore;
1212
import org.cyclops.integratedscripting.inventory.container.ContainerScriptingDrive;
1313
import org.cyclops.integratedscripting.inventory.container.ContainerTerminalScripting;
14+
import org.cyclops.integratedscripting.item.ItemScriptingDisk;
1415

1516
/**
1617
* Referenced registry entries.
1718
* @author rubensworks
1819
*/
1920
public class RegistryEntries {
20-
public static final DeferredHolder<Item, Item> ITEM_SCRIPTING_DISK = DeferredHolder.create(Registries.ITEM, ResourceLocation.parse("integratedscripting:scripting_disk"));
21+
public static final DeferredHolder<Item, ItemScriptingDisk> ITEM_SCRIPTING_DISK = DeferredHolder.create(Registries.ITEM, ResourceLocation.parse("integratedscripting:scripting_disk"));
2122

2223
public static final DeferredHolder<Block, Block> BLOCK_SCRIPTING_DRIVE = DeferredHolder.create(Registries.BLOCK, ResourceLocation.parse("integratedscripting:scripting_drive"));
2324
public static final DeferredHolder<Block, Block> BLOCK_PART_TERMINAL_SCRIPTING = DeferredHolder.create(Registries.BLOCK, ResourceLocation.parse("integratedscripting:part_terminal_scripting"));
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package org.cyclops.integratedscripting.gametest;
2+
3+
import net.minecraft.core.BlockPos;
4+
import net.minecraft.core.Direction;
5+
import net.minecraft.gametest.framework.GameTestHelper;
6+
import net.minecraft.world.item.ItemStack;
7+
import net.minecraft.world.level.Level;
8+
import org.cyclops.integrateddynamics.IntegratedDynamics;
9+
import org.cyclops.integrateddynamics.RegistryEntries;
10+
import org.cyclops.integrateddynamics.api.item.IVariableFacadeHandlerRegistry;
11+
import org.cyclops.integrateddynamics.api.part.PartPos;
12+
import org.cyclops.integrateddynamics.blockentity.BlockEntityVariablestore;
13+
import org.cyclops.integrateddynamics.core.helper.PartHelpers;
14+
import org.cyclops.integratedscripting.api.item.IScriptVariableFacade;
15+
import org.cyclops.integratedscripting.blockentity.BlockEntityScriptingDrive;
16+
import org.cyclops.integratedscripting.core.evaluate.ScriptVariableFacadeHandler;
17+
import org.cyclops.integratedscripting.core.item.ScriptVariableFacade;
18+
import org.cyclops.integratedscripting.part.PartTypes;
19+
20+
import java.nio.file.Path;
21+
22+
/**
23+
* @author rubensworks
24+
*/
25+
public class GameTestHelpersIntegratedScripting {
26+
27+
public static NetworkPositions createBasicNetwork(GameTestHelper helper, BlockPos pos) {
28+
// Place cable
29+
helper.setBlock(pos, RegistryEntries.BLOCK_CABLE.value());
30+
helper.setBlock(pos.above(), RegistryEntries.BLOCK_CABLE.value());
31+
helper.setBlock(pos.above().east(), RegistryEntries.BLOCK_CABLE.value());
32+
33+
// Place scripting drive
34+
helper.setBlock(pos.south(), org.cyclops.integratedscripting.RegistryEntries.BLOCK_SCRIPTING_DRIVE.value());
35+
36+
// Insert scripting disk into scripting drive
37+
BlockEntityScriptingDrive scriptingDrive = helper.getBlockEntity(pos.south());
38+
scriptingDrive.getInventory().setItem(0, new ItemStack(org.cyclops.integratedscripting.RegistryEntries.ITEM_SCRIPTING_DISK));
39+
40+
// Place variable store
41+
helper.setBlock(pos.south().south(), RegistryEntries.BLOCK_VARIABLE_STORE.value());
42+
43+
// Place scripting terminal
44+
PartHelpers.addPart(helper.getLevel(), helper.absolutePos(pos.above()), Direction.NORTH, PartTypes.TERMINAL_SCRIPTING, new ItemStack(PartTypes.TERMINAL_SCRIPTING.getItem()));
45+
46+
// Place display panel
47+
PartHelpers.addPart(helper.getLevel(), helper.absolutePos(pos.above().east()), Direction.NORTH, org.cyclops.integrateddynamics.core.part.PartTypes.DISPLAY_PANEL, new ItemStack(org.cyclops.integrateddynamics.core.part.PartTypes.DISPLAY_PANEL.getItem()));
48+
49+
BlockEntityVariablestore variableStore = helper.getBlockEntity(pos.south().south());
50+
51+
return new NetworkPositions(
52+
PartPos.of(helper.getLevel(), helper.absolutePos(pos.above()), Direction.NORTH),
53+
PartPos.of(helper.getLevel(), helper.absolutePos(pos.above().east()), Direction.NORTH),
54+
variableStore,
55+
org.cyclops.integratedscripting.RegistryEntries.ITEM_SCRIPTING_DISK.get().getOrCreateDiskId(scriptingDrive.getInventory().getItem(0))
56+
);
57+
}
58+
59+
public static ItemStack createVariableForScript(Level level, int disk, Path path, String member) {
60+
IVariableFacadeHandlerRegistry registry = IntegratedDynamics._instance.getRegistryManager().getRegistry(IVariableFacadeHandlerRegistry.class);
61+
ItemStack itemStack = new ItemStack(RegistryEntries.ITEM_VARIABLE);
62+
return registry.writeVariableFacadeItem(true, itemStack, ScriptVariableFacadeHandler.getInstance(),
63+
new IVariableFacadeHandlerRegistry.IVariableFacadeFactory<IScriptVariableFacade>() {
64+
@Override
65+
public IScriptVariableFacade create(boolean generateId) {
66+
return new ScriptVariableFacade(generateId, disk, path, member);
67+
}
68+
69+
@Override
70+
public IScriptVariableFacade create(int id) {
71+
return new ScriptVariableFacade(id, disk, path, member);
72+
}
73+
}, level, null, org.cyclops.integratedscripting.RegistryEntries.BLOCK_PART_TERMINAL_SCRIPTING.get().defaultBlockState());
74+
}
75+
76+
public static record NetworkPositions(
77+
PartPos terminal,
78+
PartPos displayPanel,
79+
BlockEntityVariablestore variableStore,
80+
int diskId
81+
){}
82+
83+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package org.cyclops.integratedscripting.gametest;
2+
3+
import net.minecraft.core.BlockPos;
4+
import net.minecraft.gametest.framework.GameTest;
5+
import net.minecraft.gametest.framework.GameTestHelper;
6+
import net.minecraft.world.item.ItemStack;
7+
import net.neoforged.neoforge.gametest.GameTestHolder;
8+
import net.neoforged.neoforge.gametest.PrefixGameTestTemplate;
9+
import org.apache.commons.lang3.tuple.Pair;
10+
import org.cyclops.integrateddynamics.core.evaluate.operator.Operators;
11+
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeInteger;
12+
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypes;
13+
import org.cyclops.integrateddynamics.part.PartTypePanelDisplay;
14+
import org.cyclops.integratedscripting.Reference;
15+
import org.cyclops.integratedscripting.api.network.IScriptingData;
16+
import org.cyclops.integratedscripting.core.network.ScriptingNetworkHelpers;
17+
18+
import java.nio.file.Path;
19+
20+
import static org.cyclops.integrateddynamics.gametest.GameTestHelpersIntegratedDynamics.*;
21+
import static org.cyclops.integratedscripting.gametest.GameTestHelpersIntegratedScripting.createBasicNetwork;
22+
import static org.cyclops.integratedscripting.gametest.GameTestHelpersIntegratedScripting.createVariableForScript;
23+
24+
@GameTestHolder(Reference.MOD_ID)
25+
@PrefixGameTestTemplate(false)
26+
public class GameTestsScripts {
27+
28+
public static final String TEMPLATE_EMPTY = "empty10";
29+
public static final int TIMEOUT = 2000;
30+
public static final BlockPos POS = BlockPos.ZERO.offset(2, 0, 2);
31+
32+
@GameTest(template = TEMPLATE_EMPTY, timeoutTicks = TIMEOUT)
33+
public void testScriptsDisplayScriptConst(GameTestHelper helper) {
34+
GameTestHelpersIntegratedScripting.NetworkPositions positions = createBasicNetwork(helper, POS);
35+
36+
// Write script
37+
ScriptingNetworkHelpers.getScriptingData().setScript(positions.diskId(), Path.of("script0.js"), "const abc = 3", IScriptingData.ChangeLocation.MEMORY);
38+
39+
// Create variable from script
40+
ItemStack variableScript = createVariableForScript(helper.getLevel(), positions.diskId(), Path.of("script0.js"), "abc");
41+
42+
// Place variable in display
43+
Pair<PartTypePanelDisplay, PartTypePanelDisplay.State> partAndState = placeVariableInDisplayPanel(helper.getLevel(), positions.displayPanel(), variableScript);
44+
45+
helper.succeedWhen(() -> {
46+
assertValueEqual(partAndState.getRight().getDisplayValue(), ValueTypeInteger.ValueInteger.of(3));
47+
});
48+
}
49+
50+
@GameTest(template = TEMPLATE_EMPTY, timeoutTicks = TIMEOUT)
51+
public void testScriptsDisplayScriptApplied(GameTestHelper helper) {
52+
GameTestHelpersIntegratedScripting.NetworkPositions positions = createBasicNetwork(helper, POS);
53+
54+
// Write script
55+
ScriptingNetworkHelpers.getScriptingData().setScript(positions.diskId(), Path.of("script0.js"), "function abc(a, b) { return a + b; }", IScriptingData.ChangeLocation.MEMORY);
56+
57+
// Create variable from script
58+
ItemStack variableScript = createVariableForScript(helper.getLevel(), positions.diskId(), Path.of("script0.js"), "abc");
59+
60+
// Create constants as input to the script's function
61+
ItemStack variableConst1 = createVariableForValue(helper.getLevel(), ValueTypes.INTEGER, ValueTypeInteger.ValueInteger.of(3));
62+
ItemStack variableConst2 = createVariableForValue(helper.getLevel(), ValueTypes.INTEGER, ValueTypeInteger.ValueInteger.of(8));
63+
64+
// Insert all variables into the variable store
65+
positions.variableStore().getInventory().setItem(0, variableScript);
66+
positions.variableStore().getInventory().setItem(1, variableConst1);
67+
positions.variableStore().getInventory().setItem(2, variableConst2);
68+
69+
// Create variable card for applying the function
70+
ItemStack variableAdded = createVariableForOperator(helper.getLevel(), Operators.OPERATOR_APPLY_2, new int[]{
71+
getVariableFacade(helper.getLevel(), variableScript).getId(),
72+
getVariableFacade(helper.getLevel(), variableConst1).getId(),
73+
getVariableFacade(helper.getLevel(), variableConst2).getId()
74+
});
75+
76+
// Place variable in display
77+
Pair<PartTypePanelDisplay, PartTypePanelDisplay.State> partAndState = placeVariableInDisplayPanel(helper.getLevel(), positions.displayPanel(), variableAdded);
78+
79+
helper.succeedWhen(() -> {
80+
assertValueEqual(partAndState.getRight().getDisplayValue(), ValueTypeInteger.ValueInteger.of(11));
81+
});
82+
}
83+
84+
}
Binary file not shown.

0 commit comments

Comments
 (0)