Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add game and junit tests to AP #562

Draft
wants to merge 72 commits into
base: dev/1.19.2
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
ab2dd39
Start writing some new tests, this not even near finished. The plan i…
SirEndii Jul 19, 2023
23631d0
Merge branch '1.19.2' into dev/tests
SirEndii Jul 20, 2023
62b9169
Merge branch '1.19.2' into dev/tests
SirEndii Jul 27, 2023
2cdb99a
Merge branch '1.19.2' into dev/tests
SirEndii Jul 30, 2023
0cbde8a
Merge branch '1.19.2' into dev/tests
SirEndii Aug 11, 2023
09748a3
Merge branch '1.19.2' into dev/tests
SirEndii Aug 28, 2023
426f8f9
Merge branch 'refs/heads/dev/1.19.2' into feat/tests
SirEndii Feb 23, 2024
866474f
Add some testing game tests, next step is trying to run tests on comp…
SirEndii Feb 23, 2024
cfc667e
Remove unused imports
SirEndii Feb 23, 2024
1e3ef5a
Add the CC testing framework utilities
SirEndii Feb 24, 2024
e96743d
Merge branch 'refs/heads/dev/1.19.2' into feat/tests
SirEndii Apr 26, 2024
0807a8a
Merge branch 'refs/heads/dev/1.19.2' into feat/tests
SirEndii Apr 30, 2024
d0fc2ac
Merge branch 'refs/heads/dev/1.19.2' into feat/tests
SirEndii May 2, 2024
8f63805
Implemented(Copied) the needed classes for the computer game tests fr…
SirEndii May 2, 2024
8fb24a8
Added needed junit and hamcrest libraries to the minecraft classpath …
SirEndii May 2, 2024
09e4e81
Added jqwik database to gitignore
SirEndii May 2, 2024
097a824
Fixed game tests for `runGameTestClient`
SirEndii May 3, 2024
c258ba4
Rename var old -> oldClasspath, oldVal -> minecraftClasspath
SirEndii May 3, 2024
231b175
Remove some not needed stuff in the build.gradle
SirEndii May 3, 2024
d4c127d
Created a test using kotlin for the environmental detector. This was …
SirEndii May 3, 2024
cd16a2d
Remove CC tests and complete the environment detector test
SirEndii May 5, 2024
f57b317
Add game test action
SirEndii May 5, 2024
3c6c9f1
Satisfy checkstyle
SirEndii May 5, 2024
53bf4b2
Fixed if statement
SirEndii May 5, 2024
8324d84
Added a prototype test for the ME Bridge. Used to know how the ME Sys…
SirEndii May 6, 2024
4da1afd
Added documentation on how to create tests.
SirEndii May 7, 2024
8099d49
Some styling changes to the lua scripts
SirEndii May 8, 2024
30c10ac
Polished andesite
SirEndii May 8, 2024
05d7ee5
eq -> assert and space fixing in the docs
SirEndii May 8, 2024
afcecd5
Finished the me crafting test and started implementing a test for me …
SirEndii May 8, 2024
fcfd9ce
Merge branch 'refs/heads/dev/1.19.2' into feat/tests
SirEndii May 8, 2024
578ccd8
Finished the me storage test
SirEndii May 8, 2024
233a194
Added me transfer tests to test the integrity of our item export and …
SirEndii May 10, 2024
feb2c9a
Add game tests for Block Reader peripheral
dogboy21 May 11, 2024
0e42330
Fix inconsistency in the code style for assert/eq on isTileEntity
dogboy21 May 11, 2024
7f9af5c
tablelength -> tableLength
dogboy21 May 11, 2024
2c4c172
Merge pull request #610 from dogboy21/blockreader-tests
SirEndii May 11, 2024
5263ede
Merge branch 'refs/heads/dev/1.19.2' into feat/tests
SirEndii May 21, 2024
1a692db
Merge remote-tracking branch 'refs/remotes/origin/dev/1.19.2' into fe…
SirEndii May 21, 2024
e1a84cd
increase sleep for the `isItemCrafting` function in the mecrafting pe…
SirEndii May 21, 2024
2aedb2a
Implement tests for NBT Storage peripheral
dogboy21 May 11, 2024
2f09327
Implement tests for Redstone Integrator peripheral
dogboy21 May 11, 2024
3f28371
Implement tests for Geo Scanner peripheral
dogboy21 May 11, 2024
967fbe2
Add missing comment in Geo Scanner test
dogboy21 May 11, 2024
a3a834d
Add test for Mana Flowers in the Botania Mod Integration
dogboy21 May 12, 2024
f8d7c75
Add todo comment for missing getScanCooldown function on Geo Scanner
dogboy21 May 12, 2024
0b31b09
Uncomment tests for currently unavailable Botania methods
dogboy21 May 12, 2024
77df4d0
Add test for Mana Pools in the Botania Mod Integration
dogboy21 May 12, 2024
970fc5f
Add test for Mana Spreaders in the Botania Mod Integration
dogboy21 May 13, 2024
1e96a64
Add test for Beacons in the Minecraft Mod (lol) Integration
dogboy21 May 13, 2024
043daa7
Add test for Note Blocks in the Minecraft Mod Integration
dogboy21 May 18, 2024
f8e6df9
Fix style for object key accessors
dogboy21 May 18, 2024
1954f8e
Fix RS Integrator test flakiness
dogboy21 May 18, 2024
62ee0aa
Readd test for isOnEnchantedSoil on Botania Flowers now that the meth…
dogboy21 May 21, 2024
7421144
Merge pull request #612 from dogboy21/peripheral-tests
SirEndii May 21, 2024
0a0e10d
Revert "Implement game tests for more peripherals"
SirEndii May 21, 2024
cda5a84
Merge pull request #615 from IntelligenceModding/revert-612-periphera…
SirEndii May 21, 2024
dca02be
Revert "Revert "Implement game tests for more peripherals""
SirEndii May 21, 2024
7a0dd63
Merge pull request #616 from IntelligenceModding/revert-615-revert-61…
SirEndii May 21, 2024
9cf6e2a
Some documentation additions
SirEndii May 21, 2024
20bc455
Fixed the orientation of RS Blocks when they are loaded from a struct…
SirEndii Jun 1, 2024
4b49523
Begone
SirEndii Jun 1, 2024
8272ba2
Backported changes from the CC: Tweaked Gametest framework present in…
dogboy21 Jun 1, 2024
bc4d3e4
Add gradle task to start automated client tests
dogboy21 Jun 1, 2024
6227fd6
Add docs on client tests
dogboy21 Jun 1, 2024
321ab7e
Merge pull request #622 from dogboy21/cctest-backport
SirEndii Jun 2, 2024
2a805bd
Added client test for the Chat Box peripheral
dogboy21 Jun 3, 2024
fe24952
Fix NPE on client test start with existing world
dogboy21 Jun 29, 2024
e5b46ad
Add Chat Box event test
dogboy21 Jun 29, 2024
4904f85
Fix runGameTestClient task also running common tests
dogboy21 Jun 29, 2024
83c7977
Clean and fix runGameTestClient task
dogboy21 Jul 4, 2024
1acbce7
Merge pull request #628 from dogboy21/clienttests
SirEndii Jul 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/build-and-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ on:

jobs:
build-and-test:
uses: IntelligenceModding/actions/.github/workflows/build-and-test.yaml@master
uses: IntelligenceModding/actions/.github/workflows/build-and-test.yaml@master
run-gametests:
uses: IntelligenceModding/actions/.github/workflows/run-gametests.yaml@master
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ build
eclipse
run
server
/.jqwik-database

# Files from Forge MDK
forge*changelog.txt

#github

1.17
.env

Expand Down
145 changes: 104 additions & 41 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ plugins {
id 'net.darkhax.curseforgegradle' version '1.1.16'
id 'org.jetbrains.changelog' version '1.2.1'
id "com.modrinth.minotaur" version "2.+"
id "org.jetbrains.kotlin.jvm" version "1.6.10"
id "org.jetbrains.kotlin.jvm" version "${kotlin_version}"
id 'net.minecraftforge.gradle' version '[6.0.18,6.2)'
id 'org.parchmentmc.librarian.forgegradle' version '1.+'
id 'org.spongepowered.mixin' version '0.7.+'
Expand Down Expand Up @@ -56,7 +56,23 @@ sourceSets {
main.resources {
srcDir 'src/generated/resources'
}
testMod {}
testMod {
java.srcDir 'src/testMod/java'
kotlin.srcDir 'src/testMod/kotlin'
resources.srcDir 'src/testMod/resources'
compileClasspath += main.compileClasspath + test.compileClasspath
runtimeClasspath += main.runtimeClasspath + test.runtimeClasspath
}
testFixtures {
java.srcDir 'src/testFixtures/java'
kotlin.srcDir 'src/testFixtures/kotlin'
resources.srcDir 'src/testFixtures/resources'
}
}

java.registerFeature("testFixtures") {
usingSourceSet(sourceSets.testFixtures)
disablePublication()
}

minecraft {
Expand All @@ -66,7 +82,13 @@ minecraft {
accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
accessTransformer file('src/testMod/resources/META-INF/accesstransformer.cfg')


runs {
all {
lazyToken('minecraft_classpath') {
configurations.library.copyRecursive().resolve().collect { it.absolutePath }.join(File.pathSeparator)
}
}
client {
workingDirectory project.file('run')

Expand Down Expand Up @@ -126,38 +148,69 @@ minecraft {
}
}

testClient {
gameTestClient {
workingDirectory project.file('test-files/client')
parent runs.client

def oldClasspath = lazyTokens["minecraft_classpath"]
lazyToken("minecraft_classpath") {
// Add all files in testMinecraftLibrary to the classpath.
def allFiles = new HashSet<String>();

def minecraftClasspath = oldClasspath?.get()
if (minecraftClasspath != null && !minecraftClasspath.isEmpty()) allFiles.addAll(minecraftClasspath.split(File.pathSeparatorChar))

for (file in configurations["testMinecraftLibrary"]) allFiles.add(file.absolutePath)

println("New classpath $allFiles")
allFiles.join(File.pathSeparator)
}

property 'forge.logging.markers', 'REGISTRIES'
property 'forge.logging.console.level', 'debug'
property 'forge.enabledGameTestNamespaces', 'advancedperipherals,advancedperipheralstest'
property 'advancedperipheralstest.sources', file("src/testMod/resources/data/advancedperipheralstest").absolutePath

args "--mixin.config=advancedperipheralstest.mixins.json"

mods {
aptest {
advancedperipheralstest {
source sourceSets.testMod
source sourceSets.testFixtures
}
}
}

lazyToken('minecraft_classpath') {
(configurations.implementationExtra.copyRecursive().resolve())
.collect { it.absolutePath }
.join(File.pathSeparator)
gameTestServer {
def oldClasspath = lazyTokens["minecraft_classpath"]
lazyToken("minecraft_classpath") {
// Add all files in testMinecraftLibrary to the classpath.
def allFiles = new HashSet<String>();

def minecraftClasspath = oldClasspath?.get()
if (minecraftClasspath != null && !minecraftClasspath.isEmpty()) allFiles.addAll(minecraftClasspath.split(File.pathSeparatorChar))

for (file in configurations["testMinecraftLibrary"]) allFiles.add(file.absolutePath)

println("New classpath $allFiles")
allFiles.join(File.pathSeparator)
}
}

testServer {
workingDirectory project.file('test-files/server')
property 'forge.logging.markers', 'REGISTRIES'
property 'forge.logging.console.level', 'debug'
property 'forge.enabledGameTestNamespaces', 'advancedperipherals,advancedperipheralstest'
property 'advancedperipheralstest.sources', file("src/testMod/resources/data/advancedperipheralstest").absolutePath

args "--mixin.config=advancedperipheralstest.mixins.json"
parent runs.server

mods {
aptest {
advancedperipheralstest {
source sourceSets.testMod
source sourceSets.testFixtures
}
}

lazyToken('minecraft_classpath') {
(configurations.implementationExtra.copyRecursive().resolve())
.collect { it.absolutePath }
.join(File.pathSeparator)
}
}
}
}
Expand Down Expand Up @@ -247,9 +300,27 @@ repositories {
}

configurations {
minecraftLibrary { extendsFrom(minecraftEmbed) }

testMinecraftLibrary {
canBeResolved = true
canBeConsumed = false
// Prevent ending up with multiple versions of libraries on the classpath.
shouldResolveConsistentlyWith(minecraftLibrary)
}

library
implementation.extendsFrom library
implementationExtra
testImplementation.extendsFrom(implementation)
testModImplementation.extendsFrom(implementation)
testModImplementation.extendsFrom(testImplementation)
testFixturesImplementation.extendsFrom(implementation)
testFixturesImplementation.extendsFrom(testImplementation)
}

processTestModResources {
duplicatesStrategy = 'exclude'
}

dependencies {
Expand All @@ -260,6 +331,7 @@ dependencies {
compileOnly "org.jetbrains:annotations:${jb_annotations}"
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
implementation fg.deobf("org.squiddev:cc-tweaked-${minecraft_version}:${cc_version}")
implementation fg.deobf("org.squiddev:cc-tweaked-${minecraft_version}:${cc_version}:api")
// Minimal requirements end

// Extended requirements
Expand Down Expand Up @@ -295,7 +367,7 @@ dependencies {
compileOnly fg.deobf("curse.maven:ae-additions-493962:${ae2additions_version}")
//runtimeOnly fg.deobf("curse.maven:ae-additions-493962:${ae2additions_version}")

implementation fg.deobf("thedarkcolour:kotlinforforge:${kotlinforforge_version}")
runtimeOnly fg.deobf("thedarkcolour:kotlinforforge:${kotlinforforge_version}")

// Botania
compileOnly fg.deobf("vazkii.botania:Botania:${botania_version}")
Expand Down Expand Up @@ -323,9 +395,6 @@ dependencies {
compileOnly fg.deobf("com.simibubi.create:create-${minecraft_version}:${create_version}:all")
runtimeOnly fg.deobf("com.simibubi.create:create-${minecraft_version}:${create_version}:all")

//Removed until fully ported
//testImplementation fg.deobf("site.siredvin.ttoolkit:ttoolkit-${minecraft_version}:${ttoolkit_version}")

//Powah
compileOnly fg.deobf("curse.maven:powah-633483:${powah_version}")
runtimeOnly fg.deobf("curse.maven:powah-633483:${powah_version}")
Expand All @@ -337,12 +406,17 @@ dependencies {

testImplementation "org.junit.jupiter:junit-jupiter-api:${junit_version}"
testImplementation "org.junit.jupiter:junit-jupiter-params:${junit_version}"
testImplementation "org.junit.jupiter:junit-jupiter-engine:${junit_version}"
testImplementation "net.jqwik:jqwik:${jqwikVersion}"
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${kotlin_coroutines_version}"
testImplementation "org.hamcrest:hamcrest:${hamcrest_version}"
testImplementation "org.jetbrains.kotlin:kotlin-reflect:${kotlin_version}"
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${kotlinx_coroutines_version}"
testModImplementation sourceSets.main.output
testModImplementation sourceSets.testFixtures.output

testMinecraftLibrary("org.junit.jupiter:junit-jupiter-api:${junit_version}")
testMinecraftLibrary("org.junit.jupiter:junit-jupiter-params:${junit_version}")
testMinecraftLibrary("org.hamcrest:hamcrest:${hamcrest_version}")

testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junit_version}"
// Testing stuff
// JEI
implementation fg.deobf("mezz.jei:jei-${jei_version}")
Expand Down Expand Up @@ -370,6 +444,11 @@ changelog {

compileTestModJava {
dependsOn(compileJava)
dependsOn(compileKotlin)
dependsOn(compileTestJava)
dependsOn(compileTestKotlin)
dependsOn(compileTestFixturesJava)
dependsOn(compileTestFixturesKotlin)
}

task setupServer(type: Copy) {
Expand All @@ -383,28 +462,12 @@ task setupServer(type: Copy) {
into "test-files/server"
}

["Client", "Server"].forEach { name ->
tasks.register("test$name", JavaExec.class).configure {
it.group('In-game tests')
it.description("Runs tests on a temporary Minecraft instance.")
it.dependsOn(setupServer, "prepareRunTest$name", "cleanTest$name", 'compileTestModJava')

JavaExec exec = tasks.getByName("runTest$name")
exec.copyTo(it)
it.setClasspath(exec.getClasspath())
it.mainClass = exec.mainClass
it.setArgs(exec.getArgs())

it.systemProperty('forge.logging.console.level', 'debug')
it.systemProperty('ttoolkit.run', 'true')
}
}

test {
useJUnitPlatform()
testLogging {
events "skipped", "failed"
}
finalizedBy('runGameTestServer')
}

afterEvaluate {
Expand Down
6 changes: 3 additions & 3 deletions config/checkstyle/checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

<!-- Blocks -->
<module name="EmptyBlock">
<property name="tokens" value="LITERAL_WHILE,LITERAL_TRY,LITERAL_CATCH,LITERAL_FINALLY,LITERAL_DO,LITERAL_IF,LITERAL_ELSE,INSTANCE_INIT,STATIC_INIT,LITERAL_SWITCH,LITERAL_SYNCHRONIZED,LITERAL_CASE,LITERAL_DEFAULT,ARRAY_INIT"/>
<property name="tokens" value="LITERAL_WHILE,LITERAL_TRY,LITERAL_FINALLY,LITERAL_DO,LITERAL_IF,LITERAL_ELSE,INSTANCE_INIT,STATIC_INIT,LITERAL_SWITCH,LITERAL_SYNCHRONIZED,LITERAL_CASE,LITERAL_DEFAULT,ARRAY_INIT"/>
</module>
<module name="EmptyCatchBlock">
<property name="exceptionVariableName" value="ignored" />
Expand Down Expand Up @@ -93,12 +93,12 @@
<module name="LocalFinalVariableName" />
<module name="LocalVariableName" />
<module name="MemberName" />
<module name="MethodName" />
<module name="MethodTypeParameterName">
<property name="format" value="[A-Z ]+"/>
</module>
<module name="PackageName">
<property name="format" value="^de\.srendi\.advancedperipherals(\.[a-z][a-z0-9]*)*" />
<property name="format" value="(?:(dan200\.computercraft)|(de\.srendi\.advancedperipherals))(\.[a-z][a-z0-9]*)*" />
<!-- For the game tests -->
</module>
<module name="ParameterName" />
<module name="StaticVariableName">
Expand Down
72 changes: 72 additions & 0 deletions docs/CREATING_TESTS.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
## Creating Game Tests

Since [#562](https://github.com/IntelligenceModding/AdvancedPeripherals/pull/562), Advanced Peripherals has a testing framework that allows us to write tests for our peripherals.
The testing framework is copied from [ComputerCraft](https://github.com/cc-tweaked/CC-Tweaked) and adapted to Advanced Peripherals.

### First things first.

To write a test, you need to have a test world. But this needs to be done in the testing environment.
To run the testing environment, run the gradle task `runTestClient`. This will start a new instance of Minecraft with the testing environment.
That includes the ability to run tests, import and export tests using the `/cctest` and the `/test` command.

After the tests are created, you can use the gradle task `runTestServer` to start the game test server which then runs all the test.
To test a single test, you can also use `/test run <test_name>` in the testing environment.

### Building your test structure

Tests should have a base plate made out of andesite.
Every test needs one computer and the peripheral you want to test. For example the environment detector.

![assets/img.png](assets/img.png)

Now you need to set a label to the computer, so it can run the lua test script.
`label set <test_type>.<test_name>`
For example, peripheraltest as the test type. The test type is the name of the `@GameTestHolder` class. PeripheralTest.kt for this type.
`environment` would be our test name. So the label would be `peripheraltest.environment`.

The computer needs the id 0 so it can load the default startup.lua and the tests scripts from the resources folder.

Now to save your test, get a structure block, place it in the lower right corner of the test structure and set the mode to save.
Use the command `/give @p minecraft:structure_block` to get a structure block.

Set the size for your test and the structure name. The structure name is your test name with the minecraft namespace. `minecraft:peripheraltest.environment` in our case.

![assets/img_1.png](assets/img_1.png)

Click on done to save the content of the structure block and then on SAVE to save the structure.
We now have our test structure saved as a .nbt file in the world folder. To export it as a snbt file, use the command `/cctest export`
to export the file to the `src/testMod/resources/data/advancedperipherals/structures` folder, so it can be used by the game test server later.

### Writing the test

To write a test, you need to create a new class in the `src/testMod/kotlin/advancedperipherals/test` package or use one of the existing classes.
The class should be annotated with `@GameTestHolder`.
The class should have a function annotated with `@GameTest` that will be executed by the game test server later.
The function needs to have the parameter `GameTestContext` that will be used to interact with the game world.

A simple game test would look like this. You can see that the context can be used to interact with the world.
You can then use one of the helper functions to interact with the computer. For example, `thenComputerOk()` to check if the script on the computer was executed without any fails.
```kt
@GameTest
fun environment(context: GameTestHelper) = context.sequence {
context.level.setWeatherParameters(6000, 0, false, false);
thenComputerOk();
}
```

Of course, you need a lua script to interact with the peripheral.
The script should be placed in the `src/testMod/resources/data/advancedperipheralstest/computer/tests` folder and should be named after the test name.
`peripheraltest.environment.lua` in our case.

```lua
detector = peripheral.find("environmentDetector")
test.eq(detector ~= nil, true, "Peripheral not found")

isRaining = detector.isRaining()
test.eq(false,isRaining, "It should not rain")
```

Last but not least, import the script to the computer. You need to do that when you're currently in the test world, and you want to write the script in your IDE.
Luckily, the test framework provides a command for that.
`/cctest import` imports the scripts from the resources folder to the world folder.
You can then find the script in the computer's folder using `ls tests/`.
Binary file added docs/assets/img.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 5 additions & 4 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ org.gradle.logging.level=info
# Minecraft related
mod_id=advancedperipherals
minecraft_version=1.19.2
forge_version=43.3.8
forge_version=43.3.13
loader_version=43
mod_version=0.7.36r
release_type=release
Expand All @@ -14,11 +14,12 @@ mappings_version=2022.11.27-1.19.2
jb_annotations=21.0.1

# Test dependencies
junit_version=5.7.2
junit_version=5.10.2
hamcrest_version=2.2
kotlin_version=1.8.0
kotlinx_coroutines_version=1.6.0-RC3
ttoolkit_version=0.1.3
jqwikVersion=1.8.4
kotlin_version=1.9.23
kotlin_coroutines_version=1.8.0

# Mod dependencies
cc_version=1.101.3
Expand Down
Loading
Loading