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

test(MTE): IntegrationEnvironment is the only annotation you need (maybe) #5046

Merged
merged 10 commits into from
Dec 18, 2022
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,12 @@
* host. Currently all engine instances are headless, though it is possible to use headed engines in the future.
*/
public class Engines {
public static final String DEFAULT_WORLD_GENERATOR = ModuleTestingEnvironment.DEFAULT_WORLD_GENERATOR;

private static final Logger logger = LoggerFactory.getLogger(Engines.class);

protected final Set<String> dependencies = Sets.newHashSet("engine");
protected String worldGeneratorUri = ModuleTestingEnvironment.DEFAULT_WORLD_GENERATOR;
protected final Set<String> dependencies = Sets.newHashSet();
protected String worldGeneratorUri = DEFAULT_WORLD_GENERATOR;
protected boolean doneLoading;
protected Context hostContext;
protected final List<TerasologyEngine> engines = Lists.newArrayList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.integrationenvironment;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.engine.config.Config;
import org.terasology.engine.config.ModuleConfig;
import org.terasology.engine.config.WorldGenerationConfig;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.SimpleUri;
import org.terasology.engine.core.TerasologyConstants;
import org.terasology.engine.core.TerasologyEngine;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.core.subsystem.headless.mode.StateHeadlessSetup;
import org.terasology.engine.game.GameManifest;
import org.terasology.engine.network.NetworkMode;
import org.terasology.engine.world.time.WorldTime;
import org.terasology.gestalt.naming.Name;

import java.nio.file.Path;
import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;
Expand All @@ -27,6 +31,8 @@ public class TestingStateHeadlessSetup extends StateHeadlessSetup {
static final String WORLD_TITLE = "testworld";
static final String DEFAULT_SEED = "seed";

private static final Logger logger = LoggerFactory.getLogger(TestingStateHeadlessSetup.class);

private final Collection<String> dependencies;
private final SimpleUri worldGeneratorUri;

Expand All @@ -41,9 +47,18 @@ public TestingStateHeadlessSetup(Collection<String> dependencies, String worldGe
checkArgument(this.worldGeneratorUri.isValid(), "Not a valid URI `%s`", worldGeneratorUri);
}

void configForTest(Config config) {
void configForTest(Config config, ModuleManager moduleManager) {
Set<Name> dependencyNames = dependencies.stream().map(Name::new).collect(Collectors.toSet());

if (dependencyNames.isEmpty()) {
Path workingDirectory = Path.of(".").toAbsolutePath().normalize();
var defaultModule = moduleManager.getModuleAt(workingDirectory);
logger.info(
"No module dependencies given. Checked current directory `{}`, found `{}` to use as default.",
workingDirectory, defaultModule.orElse(null));
defaultModule.ifPresent(m -> dependencyNames.add(m.getId()));
}

// Include the MTE module to provide world generators and suchlike.
dependencyNames.add(MTE_MODULE_NAME);

Expand All @@ -70,7 +85,8 @@ public GameManifest createGameManifest() {
public void init(GameEngine engine) {
// We want to modify Config before super.init calls createGameManifest, but the child context
// does not exist before we call super.init.
configForTest(((TerasologyEngine) engine).getFromEngineContext(Config.class));
var tEngine = (TerasologyEngine) engine;
configForTest(tEngine.getFromEngineContext(Config.class), tEngine.getFromEngineContext(ModuleManager.class));
super.init(engine);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
/**
* Declares the modules to load in the environment.
*
* @see MTEExtension
* @deprecated Replace with {@link IntegrationEnvironment#dependencies}
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Deprecated(since = "5.3.0", forRemoval = true)
public @interface Dependencies {
/**
* Names of modules, as defined by the <code>id</code> in their module.txt.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,32 @@

package org.terasology.engine.integrationenvironment.jupiter;

import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.extension.ExtendWith;
import org.terasology.engine.core.subsystem.EngineSubsystem;
import org.terasology.engine.integrationenvironment.Engines;
import org.terasology.engine.logic.players.LocalPlayer;
import org.terasology.engine.network.NetworkMode;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Tag("MteTest")
@ExtendWith(MTEExtension.class)
public @interface IntegrationEnvironment {
/**
* Modules to include in the environment.
* <p>
* Names of modules, as defined by the {@code id} in their {@code module.txt}.
*/
String[] dependencies() default { };

/**
* The network mode the host engine starts with.
* <p>
Expand All @@ -38,6 +52,13 @@
*/
Class<? extends EngineSubsystem> subsystem() default NO_SUBSYSTEM.class;

/**
* The URN of the world generator.
* <p>
* For example, {@code "CoreWorlds:facetedSimplex"}
*/
String worldGenerator() default Engines.DEFAULT_WORLD_GENERATOR;

/**
* Do not add an extra subsystem to the integration environment.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import org.terasology.engine.integrationenvironment.ModuleTestingHelper;
import org.terasology.engine.network.NetworkMode;
import org.terasology.engine.registry.In;
import org.terasology.unittest.worlds.DummyWorldGenerator;

import java.util.Arrays;
import java.util.Collections;
Expand All @@ -37,13 +36,10 @@
* <p>
* Example:
* <pre><code>
* import org.junit.jupiter.api.extension.ExtendWith;
* import org.junit.jupiter.api.Test;
* import org.terasology.engine.registry.In;
*
* &#64;{@link org.junit.jupiter.api.extension.ExtendWith ExtendWith}(MTEExtension.class)
* &#64;{@link Dependencies}("MyModule")
* &#64;{@link UseWorldGenerator}("Pathfinding:pathfinder")
* &#64;{@link IntegrationEnvironment}(worldGenerator="Pathfinding:pathfinder")
* public class ExampleTest {
*
* &#64;In
Expand All @@ -65,18 +61,8 @@
* }
* </code></pre>
* <p>
* You can configure the environment with these additional annotations:
* <dl>
* <dt>{@link IntegrationEnvironment @IntegrationEnvironment}</dt>
* <dd>Configure the network mode and add subsystems.</dd>
* <dt>{@link Dependencies @Dependencies}</dt>
* <dd>Specify which modules to include in the environment. Put the name of your module under test here.
* Any dependencies these modules declare in <code>module.txt</code> will be pulled in as well.</dd>
* <dt>{@link UseWorldGenerator @UseWorldGenerator}</dt>
* <dd>The URN of the world generator to use. Defaults to {@link DummyWorldGenerator},
* a flat world.</dd>
* </dl>
*
* See {@link IntegrationEnvironment @IntegrationEnvironment} for information on how to configure the
* environment's dependencies, world type, and subsystems.
* <p>
* By default, JUnit uses a {@link org.junit.jupiter.api.TestInstance.Lifecycle#PER_METHOD PER_METHOD} lifecycle
* for test instances. The <i>instance</i> of your test class—i.e. {@code this} when your test method executes—
Expand Down Expand Up @@ -163,14 +149,20 @@ private Object getDIInstance(Engines engines, Class<?> type) {
}
}

@SuppressWarnings("removal") // TODO: replace UseWorldGenerator in modules
jdrueckert marked this conversation as resolved.
Show resolved Hide resolved
public String getWorldGeneratorUri(ExtensionContext context) {
return findAnnotation(context.getRequiredTestClass(), UseWorldGenerator.class)
.map(UseWorldGenerator::value).orElse(null);
.map(UseWorldGenerator::value)
.orElseGet(() -> getAnnotationWithDefault(context, IntegrationEnvironment::worldGenerator));
}

@SuppressWarnings("removal") // TODO: replace or remove Dependencies in modules
public List<String> getDependencyNames(ExtensionContext context) {
return findAnnotation(context.getRequiredTestClass(), Dependencies.class)
.map(a -> Arrays.asList(a.value())).orElse(Collections.emptyList());
.map(a -> Arrays.asList(a.value()))
.orElseGet(() -> Arrays.asList(
getAnnotationWithDefault(context, IntegrationEnvironment::dependencies)
));
}

public NetworkMode getNetworkMode(ExtensionContext context) {
Expand All @@ -193,7 +185,7 @@ private <T> T getAnnotationWithDefault(ExtensionContext context, Function<Integr
/**
* Get the Engines for this test.
* <p>
* The new Engines instance is configured using the {@link Dependencies} and {@link UseWorldGenerator}
* The new Engines instance is configured using the {@link IntegrationEnvironment}
* annotations for the test class.
* <p>
* This will create a new instance when necessary. It will be stored in the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
/**
* Declares which {@index "world generator"} to use.
*
* @see MTEExtension
* @deprecated Replace with {@link IntegrationEnvironment#worldGenerator}
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Deprecated(since = "5.3.0", forRemoval = true)
public @interface UseWorldGenerator {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.integrationenvironment;

import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.terasology.engine.entitySystem.prefab.Prefab;
import org.terasology.engine.integrationenvironment.jupiter.MTEExtension;
import org.terasology.engine.integrationenvironment.jupiter.IntegrationEnvironment;
import org.terasology.engine.registry.In;
import org.terasology.engine.world.block.Block;
import org.terasology.engine.world.block.BlockManager;
Expand All @@ -16,8 +14,7 @@
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.terasology.engine.testUtil.Assertions.assertNotEmpty;

@Tag("MteTest")
@ExtendWith(MTEExtension.class)
@IntegrationEnvironment
public class AssetLoadingTest {

@In
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,9 @@
import org.joml.Vector3fc;
import org.joml.Vector3i;
import org.joml.Vector3ic;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.terasology.engine.entitySystem.entity.EntityManager;
import org.terasology.engine.integrationenvironment.jupiter.IntegrationEnvironment;
import org.terasology.engine.integrationenvironment.jupiter.MTEExtension;
import org.terasology.engine.network.NetworkMode;
import org.terasology.engine.registry.In;
import org.terasology.engine.world.WorldProvider;
Expand All @@ -25,8 +22,6 @@
import static org.terasology.engine.world.block.BlockManager.AIR_ID;
import static org.terasology.engine.world.block.BlockManager.UNLOADED_ID;

@Tag("MteTest")
@ExtendWith(MTEExtension.class)
@IntegrationEnvironment(networkMode = NetworkMode.LISTEN_SERVER)
class ChunkRegionFutureTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,18 @@
package org.terasology.engine.integrationenvironment;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.TerasologyEngine;
import org.terasology.engine.core.modes.StateIngame;
import org.terasology.engine.integrationenvironment.jupiter.IntegrationEnvironment;
import org.terasology.engine.integrationenvironment.jupiter.MTEExtension;
import org.terasology.engine.network.NetworkMode;

import java.io.IOException;
import java.util.List;

@Tag("MteTest")
@ExtendWith(MTEExtension.class)
@IntegrationEnvironment(networkMode = NetworkMode.LISTEN_SERVER)
public class ClientConnectionTest {
private static final Logger logger = LoggerFactory.getLogger(ClientConnectionTest.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,15 @@
package org.terasology.engine.integrationenvironment;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.terasology.engine.entitySystem.entity.EntityManager;
import org.terasology.engine.entitySystem.entity.EntityRef;
import org.terasology.engine.integrationenvironment.jupiter.MTEExtension;
import org.terasology.engine.integrationenvironment.jupiter.IntegrationEnvironment;
import org.terasology.engine.registry.In;
import org.terasology.unittest.stubs.DummyComponent;
import org.terasology.unittest.stubs.DummyEvent;

@Tag("MteTest")
@ExtendWith(MTEExtension.class)
@IntegrationEnvironment
public class ComponentSystemTest {
@In
private EntityManager entityManager;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,17 @@

package org.terasology.engine.integrationenvironment;

import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.terasology.engine.config.PlayerConfig;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.TerasologyEngine;
import org.terasology.engine.core.subsystem.NonPlayerVisibleSubsystem;
import org.terasology.engine.integrationenvironment.jupiter.IntegrationEnvironment;
import org.terasology.engine.integrationenvironment.jupiter.MTEExtension;

import static com.google.common.truth.Truth.assertThat;
import static org.terasology.engine.testUtil.Correspondences.instanceOfExpected;

@Tag("MteTest")
@ExtendWith(MTEExtension.class)
@IntegrationEnvironment(subsystem = CustomSubsystemTest.MySubsystem.class)
public class CustomSubsystemTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,11 @@
import com.google.common.collect.Lists;
import org.joml.Vector3i;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.Time;
import org.terasology.engine.entitySystem.entity.EntityManager;
import org.terasology.engine.integrationenvironment.jupiter.IntegrationEnvironment;
import org.terasology.engine.integrationenvironment.jupiter.MTEExtension;
import org.terasology.engine.logic.players.LocalPlayer;
import org.terasology.engine.logic.players.event.ResetCameraEvent;
import org.terasology.engine.network.ClientComponent;
Expand All @@ -23,8 +20,6 @@

import java.io.IOException;

@Tag("MteTest")
@ExtendWith(MTEExtension.class)
@IntegrationEnvironment(networkMode = NetworkMode.LISTEN_SERVER)
public class ExampleTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,19 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.extension.ExtendWith;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.integrationenvironment.jupiter.MTEExtension;
import org.terasology.engine.integrationenvironment.jupiter.IntegrationEnvironment;
import org.terasology.engine.registry.In;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;


@Tag("MteTest")
@ExtendWith(MTEExtension.class)
@IntegrationEnvironment
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class LifecyclePerClassInjectionTest {
Expand Down
Loading