Skip to content

Commit 2b25d43

Browse files
committed
Update to 1.21.5-rc1
1 parent 7ee6af1 commit 2b25d43

36 files changed

+229
-477
lines changed

README.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ data merge entity @e[type=item,distance=..2,limit=1] {Motion: [0.0, 0.01, 0.0]}
3535
```
3636

3737
## Running tests
38-
Tests can be run in-game using the `test` command.
39-
* `test runall`: runs all the tests
40-
* `test runall <namespace>`: runs all tests from a specified namespace
38+
Tests can be run in-game using the `test` command. Some example commands:
39+
* `test run *:*`: runs all the tests
40+
* `test run <namespace>:*`: runs all tests from a specified namespace
4141
* `test run <test>`: runs the test with a specified name
4242
* `test runfailed`: runs all the previously failed tests
4343
* `test runthis`: runs the closes test
@@ -126,10 +126,9 @@ Fake players can be spawned using the `/dummy` command. Dummies won't save or lo
126126
## Directives
127127
Tests can be customized by placing certain directives as special comments at the start of the test function.
128128

129-
* `@template`: the resource location of a structure template to use for the test, defaults to an empty 1x1x1 structure
129+
* `@environment`: the test environment for this test, defaults to `minecraft:default`
130+
* `@template`: the resource location of a structure template to use for the test, defaults to `minecraft:empty`, which is an empty 1x1x1 structure
130131
* `@timeout`: an integer specifying the timeout, defaults to `100`
131132
* `@optional`: whether this test is allowed to fail, defaults to `false`, if there is no value after the directive it is considered as `true`
133+
* `@skyaccess`: whether this test needs sky access, defaults to `false`, which will place barrier blocks above the test
132134
* `@dummy`: whether to spawn a dummy at the start of the test and set `@s` to this dummy, taking a position which defaults to `~0.5 ~ ~0.5`
133-
* `@batch`: the batch name for this test, defaults to `packtestBatch`
134-
* `@beforebatch`: a command to run before this batch, there can only be one per batch
135-
* `@afterbatch`: a command to run after this batch, there can only be one per batch

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
plugins {
2-
id 'fabric-loom' version '1.8-SNAPSHOT'
2+
id 'fabric-loom' version '1.10-SNAPSHOT'
33
id 'maven-publish'
44
}
55

gradle.properties

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ org.gradle.parallel=true
44

55
# Fabric Properties
66
# check these on https://fabricmc.net/develop
7-
minecraft_version=1.21.4
7+
minecraft_version=1.21.5-rc1
88
loader_version=0.16.10
99

1010
# Mod Properties
11-
mod_version=1.10.0
11+
mod_version=1.11.0-beta1
1212
maven_group=io.github.misode
1313
archives_base_name=packtest
1414

1515
# Dependencies
16-
fabric_version=0.119.2+1.21.4
16+
fabric_version=0.119.3+1.21.5

gradle/wrapper/gradle-wrapper.jar

130 Bytes
Binary file not shown.

gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip
44
networkTimeout=10000
55
validateDistributionUrl=true
66
zipStoreBase=GRADLE_USER_HOME

gradlew

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,7 @@ done
8686
# shellcheck disable=SC2034
8787
APP_BASE_NAME=${0##*/}
8888
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
89-
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
90-
' "$PWD" ) || exit
89+
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
9190

9291
# Use the maximum available, or set MAX_FD != -1 to use that value.
9392
MAX_FD=maximum

src/main/java/io/github/misode/packtest/LineNumberException.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package io.github.misode.packtest;
22

33
import net.minecraft.gametest.framework.GameTestAssertException;
4+
import net.minecraft.network.chat.Component;
45

56
public class LineNumberException extends GameTestAssertException {
67

78
final int lineNumber;
89

9-
public LineNumberException(String string, int lineNumber) {
10-
super(string);
10+
public LineNumberException(Component message, int tick, int lineNumber) {
11+
super(message, tick);
1112
this.lineNumber = lineNumber;
1213
}
1314

src/main/java/io/github/misode/packtest/PackTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import net.minecraft.commands.CommandSourceStack;
1414
import net.minecraft.commands.Commands;
1515
import net.minecraft.commands.synchronization.ArgumentUtils;
16-
import net.minecraft.core.BlockPos;
1716
import net.minecraft.data.registries.VanillaRegistries;
1817
import net.minecraft.gametest.framework.GameTestServer;
1918
import net.minecraft.server.packs.repository.PackRepository;
@@ -30,7 +29,7 @@
3029
import java.nio.file.Path;
3130
import java.nio.file.Paths;
3231
import java.util.Comparator;
33-
import java.util.List;
32+
import java.util.Optional;
3433
import java.util.function.ToIntFunction;
3534

3635
public class PackTest implements ModInitializer {
@@ -98,7 +97,7 @@ private static void registerCommands(CommandDispatcher<CommandSourceStack> dispa
9897
}
9998

10099
public static void runHeadlessServer(LevelStorageSource.LevelStorageAccess storage, PackRepository packRepository) {
101-
GameTestServer.spin(thread -> GameTestServer.create(thread, storage, packRepository, List.of(), BlockPos.ZERO));
100+
GameTestServer.spin(thread -> GameTestServer.create(thread, storage, packRepository, Optional.empty(), false));
102101
}
103102

104103
public static String wrapError(String message) {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package io.github.misode.packtest;
2+
3+
import net.minecraft.network.chat.Component;
4+
5+
public interface PackTestAssertException {
6+
Component packtest$getMessage();
7+
int packtest$getTick();
8+
}

src/main/java/io/github/misode/packtest/PackTestFunction.java

Lines changed: 63 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,55 @@
1313
import net.minecraft.commands.execution.ExecutionContext;
1414
import net.minecraft.commands.functions.CommandFunction;
1515
import net.minecraft.commands.functions.InstantiatedFunction;
16+
import net.minecraft.core.Holder;
17+
import net.minecraft.core.HolderGetter;
18+
import net.minecraft.core.registries.Registries;
1619
import net.minecraft.gametest.framework.*;
20+
import net.minecraft.network.chat.Component;
21+
import net.minecraft.resources.ResourceKey;
1722
import net.minecraft.resources.ResourceLocation;
18-
import net.minecraft.server.level.ServerLevel;
23+
import net.minecraft.world.level.block.Rotation;
1924
import net.minecraft.world.phys.Vec3;
2025

2126
import java.util.*;
22-
import java.util.function.Consumer;
2327
import java.util.regex.Matcher;
2428
import java.util.regex.Pattern;
2529

26-
public class PackTestFunction {
30+
public record PackTestFunction(Map<String, String> directives, List<Step> steps, int permissionLevel) {
2731
private static final Pattern DIRECTIVE_PATTERN = Pattern.compile("^#\\s*@(\\w+)(?:\\s+(.+))?$");
28-
private static final String DEFAULT_BATCH = "packtestBatch";
29-
private static final String DEFAULT_TEMPLATE = "packtest:empty";
30-
private final ResourceLocation id;
31-
private final Map<String, String> directives;
32-
private final List<Step> steps;
3332

34-
public PackTestFunction(ResourceLocation id, Map<String, String> directives, List<Step> steps) {
35-
this.id = id;
36-
this.directives = directives;
37-
this.steps = steps;
33+
public void run(GameTestHelper helper) {
34+
CommandSourceStack source = helper.getLevel().getServer().createCommandSourceStack()
35+
.withPosition(helper.absoluteVec(Vec3.ZERO))
36+
.withPermission(this.permissionLevel)
37+
.withSuppressedOutput();
38+
((PackTestSourceStack) source).packtest$setHelper(helper);
39+
40+
Vec3 dummyPos = this.getDummyPos(source).orElse(null);
41+
Dummy dummy;
42+
if (dummyPos != null) {
43+
try {
44+
dummy = Dummy.createRandom(helper.getLevel().getServer(), helper.getLevel().dimension(), dummyPos);
45+
dummy.setOnGround(true); // little hack because we know the dummy will be on the ground
46+
source = source.withEntity(dummy);
47+
} catch (IllegalArgumentException e) {
48+
throw new GameTestAssertException(Component.literal("Failed to initialize test with dummy"), 0);
49+
}
50+
}
51+
52+
ChatListener chatListener = new ChatListener();
53+
((PackTestInfo)((PackTestHelper)helper).packtest$getInfo()).packtest$setChatListener(chatListener);
54+
helper.onEachTick(chatListener::reset);
55+
56+
CommandDispatcher<CommandSourceStack> dispatcher = helper.getLevel().getServer().getCommands().getDispatcher();
57+
GameTestSequence sequence = helper.startSequence();
58+
for (Step step : this.steps) {
59+
step.register(sequence, dispatcher, source);
60+
}
61+
sequence.thenSucceed();
3862
}
3963

40-
public static PackTestFunction fromLines(ResourceLocation id, CommandDispatcher<CommandSourceStack> dispatcher, List<String> lines) {
64+
public static PackTestFunction fromLines(List<String> lines, int permissionLevel) {
4165
HashMap<String, String> directives = new HashMap<>();
4266
for (String line : lines) {
4367
if (!line.startsWith("#")) {
@@ -54,30 +78,12 @@ public static PackTestFunction fromLines(ResourceLocation id, CommandDispatcher<
5478
List<Step> steps = new ArrayList<>();
5579
for (int i = 0; i < lines.size(); i += 1) {
5680
String line = lines.get(i).stripLeading();
57-
if (line.startsWith("await delay ")) {
58-
steps.add(new IdleStep(line.substring("await delay ".length()), i + 1));
59-
} else if (!line.startsWith("#") && !line.isEmpty()) {
60-
steps.add(new CommandStep(lines.get(i), i + 1, dispatcher));
81+
if (!line.startsWith("#") && !line.isEmpty()) {
82+
steps.add(new Step(lines.get(i), i + 1));
6183
}
6284
}
6385

64-
return new PackTestFunction(id, directives, steps);
65-
}
66-
67-
private String getTestName() {
68-
return this.id.toLanguageKey();
69-
}
70-
71-
private String getTemplateName() {
72-
return this.directives.getOrDefault("template", DEFAULT_TEMPLATE);
73-
}
74-
75-
private String getBatchName() {
76-
return this.directives.getOrDefault("batch", DEFAULT_BATCH);
77-
}
78-
79-
private int getTimeout() {
80-
return Optional.ofNullable(this.directives.get("timeout")).map(Integer::parseInt).orElse(100);
86+
return new PackTestFunction(directives, steps, permissionLevel);
8187
}
8288

8389
private Optional<Vec3> getDummyPos(CommandSourceStack source) {
@@ -95,97 +101,41 @@ private Optional<Vec3> getDummyPos(CommandSourceStack source) {
95101
}
96102
}
97103

98-
private boolean isRequired() {
99-
return Optional.ofNullable(this.directives.get("optional")).map(s -> !Boolean.parseBoolean(s)).orElse(true);
100-
}
101-
102-
private boolean needsSkyAccess() {
103-
return Optional.ofNullable(this.directives.get("skyaccess")).map(Boolean::parseBoolean).orElse(false);
104+
public TestData<Holder<TestEnvironmentDefinition>> getTestData(HolderGetter.Provider registries) {
105+
var environments = registries.lookup(Registries.TEST_ENVIRONMENT).orElseThrow();
106+
ResourceLocation environmentId = Optional.ofNullable(this.directives.get("environment")).map(ResourceLocation::parse).orElse(GameTestEnvironments.DEFAULT_KEY.location());
107+
Holder<TestEnvironmentDefinition> environment = environments.getOrThrow(ResourceKey.create(Registries.TEST_ENVIRONMENT, environmentId));
108+
ResourceLocation structure = Optional.ofNullable(this.directives.get("template")).map(ResourceLocation::parse).orElse(ResourceLocation.withDefaultNamespace("empty"));
109+
int maxTicks = Optional.ofNullable(this.directives.get("timeout")).map(Integer::parseInt).orElse(100);
110+
boolean required = Optional.ofNullable(this.directives.get("optional")).map(s -> !Boolean.parseBoolean(s)).orElse(true);
111+
boolean skyAccess = Optional.ofNullable(this.directives.get("skyaccess")).map(Boolean::parseBoolean).orElse(false);
112+
return new TestData<>(environment, structure, maxTicks, 0, required, Rotation.NONE, false, 1, 1, skyAccess);
104113
}
105114

106-
public void registerBatchHook(int permissionLevel, Map<String, Consumer<ServerLevel>> map, String type) {
107-
String command = this.directives.get(type + "batch");
108-
if (command == null) {
109-
return;
110-
}
111-
String batchName = this.getBatchName();
112-
Consumer<ServerLevel> oldBefore = map.putIfAbsent(batchName, (level) -> {
113-
CommandSourceStack source = level.getServer().createCommandSourceStack()
114-
.withPermission(permissionLevel);
115-
level.getServer().getCommands().performPrefixedCommand(source, command);
116-
});
117-
if (oldBefore != null) {
118-
PackTest.LOGGER.error("Only one @{}batch is allowed per batch. Batch '{}' has more than one!", type, batchName);
119-
}
120-
}
121-
122-
public TestFunction toTestFunction(int permissionLevel) {
123-
return new TestFunction(
124-
this.getBatchName(),
125-
this.getTestName(),
126-
this.getTemplateName(),
127-
StructureUtils.getRotationForRotationSteps(0),
128-
this.getTimeout(),
129-
0L,
130-
this.isRequired(),
131-
false,
132-
1,
133-
1,
134-
this.needsSkyAccess(),
135-
createTestBody(permissionLevel));
136-
}
137-
138-
private Consumer<GameTestHelper> createTestBody(int permissionLevel) {
139-
return (helper) -> {
140-
CommandSourceStack source = helper.getLevel().getServer().createCommandSourceStack()
141-
.withPosition(helper.absoluteVec(Vec3.ZERO))
142-
.withPermission(permissionLevel)
143-
.withSuppressedOutput();
144-
((PackTestSourceStack) source).packtest$setHelper(helper);
145-
146-
Vec3 dummyPos = this.getDummyPos(source).orElse(null);
147-
Dummy dummy;
148-
if (dummyPos != null) {
115+
public record Step(String line, int lineNumber) {
116+
public void register(GameTestSequence sequence, CommandDispatcher<CommandSourceStack> dispatcher, CommandSourceStack source) {
117+
if (this.line.startsWith("await delay ")) {
149118
try {
150-
dummy = Dummy.createRandom(helper.getLevel().getServer(), helper.getLevel().dimension(), dummyPos);
151-
dummy.setOnGround(true); // little hack because we know the dummy will be on the ground
152-
source = source.withEntity(dummy);
153-
} catch (IllegalArgumentException e) {
154-
throw new GameTestAssertException("Failed to initialize test with dummy");
119+
String timeArgument = line.substring("await delay ".length());
120+
int ticks = TimeArgument.time().parse(new StringReader(timeArgument));
121+
((PackTestSequence)sequence).packtest$thenIdle(ticks, lineNumber, timeArgument);
122+
} catch (CommandSyntaxException e) {
123+
throw new LineNumberException(Component.literal("Whilst parsing command: " + e.getMessage()), 0, lineNumber);
155124
}
125+
return;
156126
}
157-
158-
ChatListener chatListener = new ChatListener();
159-
((PackTestInfo)((PackTestHelper)helper).packtest$getInfo()).packtest$setChatListener(chatListener);
160-
helper.onEachTick(chatListener::reset);
161-
162-
GameTestSequence sequence = helper.startSequence();
163-
for (Step step : this.steps) {
164-
step.register(sequence, source);
165-
}
166-
sequence.thenSucceed();
167-
};
168-
}
169-
170-
public interface Step {
171-
void register(GameTestSequence sequence, CommandSourceStack source);
172-
}
173-
174-
public record CommandStep(String line, int lineNumber, CommandDispatcher<CommandSourceStack> dispatcher) implements Step {
175-
@Override
176-
public void register(GameTestSequence sequence, CommandSourceStack source) {
177127
try {
178128
ResourceLocation id = ResourceLocation.fromNamespaceAndPath("packtest", "internal");
179-
CommandFunction<CommandSourceStack> function = CommandFunction.fromLines(id, this.dispatcher, source, List.of(this.line));
180-
InstantiatedFunction<CommandSourceStack> instantiated = function.instantiate(null, this.dispatcher);
129+
CommandFunction<CommandSourceStack> function = CommandFunction.fromLines(id, dispatcher, source, List.of(this.line));
130+
InstantiatedFunction<CommandSourceStack> instantiated = function.instantiate(null, dispatcher);
181131
Runnable runCommands = () -> {
182132
try {
183133
Commands.executeCommandInContext(
184134
source,
185135
e -> ExecutionContext.queueInitialFunctionCall(e, instantiated, source, CommandResultCallback.EMPTY)
186136
);
187137
} catch (GameTestAssertException e) {
188-
throw new LineNumberException(e.getMessage(), lineNumber);
138+
throw new LineNumberException(((PackTestAssertException)e).packtest$getMessage(), ((PackTestAssertException)e).packtest$getTick(), lineNumber);
189139
}
190140
};
191141
if (line.stripLeading().startsWith("await ")) {
@@ -198,22 +148,10 @@ public void register(GameTestSequence sequence, CommandSourceStack source) {
198148
if (message.equals("Line continuation at end of file")) {
199149
message = "Line continuation is not supported in tests";
200150
}
201-
throw new LineNumberException("Whilst parsing command: " + message, lineNumber);
151+
throw new LineNumberException(Component.literal("Whilst parsing command: " + message), 0, lineNumber);
202152
} catch (FunctionInstantiationException e) {
203153
String message = e.messageComponent().getString();
204-
throw new LineNumberException("Whilst instantiating command: " + message, lineNumber);
205-
}
206-
}
207-
}
208-
209-
public record IdleStep(String argument, int lineNumber) implements Step {
210-
@Override
211-
public void register(GameTestSequence sequence, CommandSourceStack source) {
212-
try {
213-
int ticks = TimeArgument.time().parse(new StringReader(argument));
214-
((PackTestSequence)sequence).packtest$thenIdle(ticks, lineNumber, argument);
215-
} catch (CommandSyntaxException e) {
216-
throw new LineNumberException("Whilst parsing command: " + e.getMessage(), lineNumber);
154+
throw new LineNumberException(Component.literal("Whilst instantiating command: " + message), 0, lineNumber);
217155
}
218156
}
219157
}

0 commit comments

Comments
 (0)