Skip to content

Commit

Permalink
improved test infrastructure to mock aspects of IdeContext (#775)
Browse files Browse the repository at this point in the history
  • Loading branch information
hohwille authored Nov 26, 2024
1 parent bc553c9 commit 38f2271
Show file tree
Hide file tree
Showing 9 changed files with 185 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
/**
* Implementation of {@link CommandletManager}.
*/
public final class CommandletManagerImpl implements CommandletManager {
public class CommandletManagerImpl implements CommandletManager {

private final Map<Class<? extends Commandlet>, Commandlet> commandletTypeMap;

Expand Down Expand Up @@ -115,7 +115,10 @@ public CommandletManagerImpl(IdeContext context) {
add(new LazyDocker(context));
}

private void add(Commandlet commandlet) {
/**
* @param commandlet the {@link Commandlet} to add.
*/
protected void add(Commandlet commandlet) {

boolean hasRequiredProperty = false;
List<Property<?>> properties = commandlet.getProperties();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,15 @@ public abstract class AbstractIdeContext implements IdeContext {

private Path confPath;

private Path settingsPath;
protected Path settingsPath;

private Path softwarePath;

private Path softwareExtraPath;

private Path softwareRepositoryPath;

private Path pluginsPath;
protected Path pluginsPath;

private Path workspacePath;

Expand Down Expand Up @@ -108,7 +108,7 @@ public abstract class AbstractIdeContext implements IdeContext {

private final FileAccess fileAccess;

private final CommandletManager commandletManager;
protected CommandletManager commandletManager;

protected ToolRepository defaultToolRepository;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ protected void installDependencies() {
}

@Override
public final boolean install(boolean silent, EnvironmentContext environmentContext) {
public boolean install(boolean silent, EnvironmentContext environmentContext) {

installDependencies();
VersionIdentifier configuredVersion = getConfiguredVersion();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ public IdeToolCommandlet(IdeContext context, String tool, Set<Tag> tags) {
private boolean hasIde(Set<Tag> tags) {

for (Tag tag : tags) {
if (tag.isAncestorOf(Tag.IDE)) {
if (tag.isAncestorOf(Tag.IDE) || (tag == Tag.IDE)) {
return true;
}
}
throw new IllegalStateException("Tags of IdeTool hat to be connected with tag IDE: " + tags);
throw new IllegalStateException("Tags of IdeTool has to be connected with tag IDE: " + tags);
}

@Override
Expand All @@ -62,7 +62,7 @@ protected void configureWorkspace() {

Path settingsWorkspaceFolder = this.context.getSettingsPath().resolve(this.tool)
.resolve(IdeContext.FOLDER_WORKSPACE);
Path genericWorkspaceFolder = this.context.getSettingsPath().resolve(IdeContext.FOLDER_WORKSPACE);
Path genericWorkspaceFolder = this.context.getSettingsPath().resolve(IdeContext.FOLDER_WORKSPACE);
Path workspaceUpdateFolder = genericWorkspaceFolder.resolve(IdeContext.FOLDER_UPDATE);
Path workspaceSetupFolder = genericWorkspaceFolder.resolve(IdeContext.FOLDER_SETUP);
FileAccess fileAccess = this.context.getFileAccess();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.devonfw.tools.ide.commandlet;

import com.devonfw.tools.ide.context.IdeContext;

/**
* Extends {@link CommandletManagerImpl} to make {@link #add(Commandlet)} method visible for testing and mocking.
*/
public class TestCommandletManager extends CommandletManagerImpl {

/**
* @param context the {@link IdeContext}.
*/
public TestCommandletManager(IdeContext context) {

super(context);
}

@Override
public void add(Commandlet commandlet) {

super.add(commandlet);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import java.util.HashMap;
import java.util.Map;

import com.devonfw.tools.ide.commandlet.Commandlet;
import com.devonfw.tools.ide.commandlet.CommandletManager;
import com.devonfw.tools.ide.commandlet.TestCommandletManager;
import com.devonfw.tools.ide.common.SystemPath;
import com.devonfw.tools.ide.environment.AbstractEnvironmentVariables;
import com.devonfw.tools.ide.environment.EnvironmentVariables;
Expand Down Expand Up @@ -37,14 +40,15 @@ public class AbstractIdeTestContext extends AbstractIdeContext {

private ProcessContext mockContext;

private TestCommandletManager testCommandletManager;

/**
* The constructor.
*
* @param logger the {@link IdeLogger}.
* @param workingDirectory the optional {@link Path} to current working directory.
* @param answers the automatic answers simulating a user in test.
*/
public AbstractIdeTestContext(IdeStartContextImpl logger, Path workingDirectory, String... answers) {
public AbstractIdeTestContext(IdeStartContextImpl logger, Path workingDirectory) {

super(logger, workingDirectory);
this.answers = new String[0];
Expand Down Expand Up @@ -83,6 +87,10 @@ protected String readLine() {
return this.answers[this.answerIndex++];
}

/**
* @param answers the answers for interactive questions in order (e.g. if "yes" is given as first answer, this will be used to answer the first
* question).
*/
public void setAnswers(String... answers) {
requireMutable();
this.answers = answers;
Expand All @@ -103,9 +111,7 @@ public IdeProgressBar prepareProgressBar(String taskName, long size) {
IdeProgressBarTestImpl progressBar = new IdeProgressBarTestImpl(taskName, size);
IdeProgressBarTestImpl duplicate = this.progressBarMap.put(taskName, progressBar);
// If we have multiple downloads or unpacking, we may have an existing "Downloading" or "Unpacking" key
if ((!taskName.equals("Downloading")) && (!taskName.equals("Unpacking"))) {
assert duplicate == null;
}
assert (taskName.equals("Downloading")) || (taskName.equals("Unpacking")) || duplicate == null;
return progressBar;
}

Expand Down Expand Up @@ -199,4 +205,44 @@ public void setDefaultToolRepository(ToolRepository defaultToolRepository) {

this.defaultToolRepository = defaultToolRepository;
}

/**
* @param settingsPath the new value of {@link #getSettingsPath()}.
*/
public void setSettingsPath(Path settingsPath) {

this.settingsPath = settingsPath;
}

/**
* @param pluginsPath the new value of {@link #getPluginsPath()}.
*/
public void setPluginsPath(Path pluginsPath) {

this.pluginsPath = pluginsPath;
}

/**
* @param commandletManager the new value of {@link #getCommandletManager()}.
*/
public void setCommandletManager(CommandletManager commandletManager) {
if (commandletManager instanceof TestCommandletManager tcm) {
this.testCommandletManager = tcm;
} else {
this.testCommandletManager = null;
}
this.commandletManager = commandletManager;
}

/**
* @param commandlet the {@link Commandlet} to add to {@link #getCommandletManager()} for testing.
*/
public void addCommandlet(Commandlet commandlet) {

if (this.testCommandletManager == null) {
setCommandletManager(new TestCommandletManager(this));
}
this.testCommandletManager.add(commandlet);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.devonfw.tools.ide.tool.ide;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import com.devonfw.tools.ide.commandlet.Commandlet;
import com.devonfw.tools.ide.common.Tag;
import com.devonfw.tools.ide.context.AbstractIdeContextTest;
import com.devonfw.tools.ide.context.AbstractIdeTestContext;
import com.devonfw.tools.ide.context.IdeContext;
import com.devonfw.tools.ide.context.IdeSlf4jContext;
import com.devonfw.tools.ide.process.ProcessErrorHandling;
import com.devonfw.tools.ide.process.ProcessMode;
import com.devonfw.tools.ide.process.ProcessResult;
import com.devonfw.tools.ide.process.ProcessResultImpl;
import com.devonfw.tools.ide.step.Step;
import com.devonfw.tools.ide.tool.plugin.ToolPluginDescriptor;
import com.devonfw.tools.ide.version.GenericVersionRange;

/**
* Test of {@link IdeToolCommandlet} using {@link IdeToolDummyCommandlet}.
*/
public class IdeToolDummyCommandletTest extends AbstractIdeContextTest {

/**
* Run the dummy commandlet and test that only active plugins are passed to installPlugin method.
*
* @param tempDir the {@link TempDir}.
*/
@Test
public void testDummyCommandlet(@TempDir Path tempDir) {

AbstractIdeTestContext context = new IdeSlf4jContext();
context.setPluginsPath(tempDir);
context.setSettingsPath(Path.of("src/test/resources/settings/dummy"));
IdeToolDummyCommandlet dummyCommandlet = new IdeToolDummyCommandlet(context, "dummy", Set.of(Tag.IDE));

context.addCommandlet(dummyCommandlet);

Commandlet dummy = context.getCommandletManager().getCommandlet("dummy");
assertThat(dummy).isSameAs(dummyCommandlet);
dummy.run();
assertThat(dummyCommandlet.installedPlugins).hasSize(1);
ToolPluginDescriptor plugin = dummyCommandlet.installedPlugins.get(0);
assertThat(plugin.id()).isEqualTo("plugin1-id");
assertThat(plugin.url()).isEqualTo("https://dummy.com/plugins/plugin1-url");
}

/**
* Dummy commandlet extending {@link IdeToolCommandlet} for testing.
*/
public static class IdeToolDummyCommandlet extends IdeToolCommandlet {

final List<ToolPluginDescriptor> installedPlugins;

IdeToolDummyCommandlet(IdeContext context, String tool, Set<Tag> tags) {

super(context, tool, tags);
this.installedPlugins = new ArrayList<>();
}

@Override
protected void configureWorkspace() {

// disable workspace configuration since we have no IDE_HOME and therefore no settings
}

@Override
public ProcessResult runTool(ProcessMode processMode, GenericVersionRange toolVersion, ProcessErrorHandling errorHandling, String... args) {

// skip installation but trigger postInstall to test mocked plugin installation
postInstall(true);
return new ProcessResultImpl(0, List.of(), List.of());
}

@Override
public void installPlugin(ToolPluginDescriptor plugin, Step step) {

this.installedPlugins.add(plugin);
step.success("Dummy plugin " + plugin.name() + " installed.");
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
plugin_id=plugin1-id
plugin_active=true
plugin_url=https://dummy.com/plugins/plugin1-url
tags=dummy
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
plugin_id=plugin2-id
plugin_active=false
plugin_url=https://dummy.com/plugins/plugin2-url
tags=dummy2

0 comments on commit 38f2271

Please sign in to comment.