Skip to content

Commit 38f2271

Browse files
authored
improved test infrastructure to mock aspects of IdeContext (#775)
1 parent bc553c9 commit 38f2271

File tree

9 files changed

+185
-14
lines changed

9 files changed

+185
-14
lines changed

cli/src/main/java/com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
/**
4343
* Implementation of {@link CommandletManager}.
4444
*/
45-
public final class CommandletManagerImpl implements CommandletManager {
45+
public class CommandletManagerImpl implements CommandletManager {
4646

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

@@ -115,7 +115,10 @@ public CommandletManagerImpl(IdeContext context) {
115115
add(new LazyDocker(context));
116116
}
117117

118-
private void add(Commandlet commandlet) {
118+
/**
119+
* @param commandlet the {@link Commandlet} to add.
120+
*/
121+
protected void add(Commandlet commandlet) {
119122

120123
boolean hasRequiredProperty = false;
121124
List<Property<?>> properties = commandlet.getProperties();

cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,15 @@ public abstract class AbstractIdeContext implements IdeContext {
6868

6969
private Path confPath;
7070

71-
private Path settingsPath;
71+
protected Path settingsPath;
7272

7373
private Path softwarePath;
7474

7575
private Path softwareExtraPath;
7676

7777
private Path softwareRepositoryPath;
7878

79-
private Path pluginsPath;
79+
protected Path pluginsPath;
8080

8181
private Path workspacePath;
8282

@@ -108,7 +108,7 @@ public abstract class AbstractIdeContext implements IdeContext {
108108

109109
private final FileAccess fileAccess;
110110

111-
private final CommandletManager commandletManager;
111+
protected CommandletManager commandletManager;
112112

113113
protected ToolRepository defaultToolRepository;
114114

cli/src/main/java/com/devonfw/tools/ide/tool/LocalToolCommandlet.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ protected void installDependencies() {
6767
}
6868

6969
@Override
70-
public final boolean install(boolean silent, EnvironmentContext environmentContext) {
70+
public boolean install(boolean silent, EnvironmentContext environmentContext) {
7171

7272
installDependencies();
7373
VersionIdentifier configuredVersion = getConfiguredVersion();

cli/src/main/java/com/devonfw/tools/ide/tool/ide/IdeToolCommandlet.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ public IdeToolCommandlet(IdeContext context, String tool, Set<Tag> tags) {
3535
private boolean hasIde(Set<Tag> tags) {
3636

3737
for (Tag tag : tags) {
38-
if (tag.isAncestorOf(Tag.IDE)) {
38+
if (tag.isAncestorOf(Tag.IDE) || (tag == Tag.IDE)) {
3939
return true;
4040
}
4141
}
42-
throw new IllegalStateException("Tags of IdeTool hat to be connected with tag IDE: " + tags);
42+
throw new IllegalStateException("Tags of IdeTool has to be connected with tag IDE: " + tags);
4343
}
4444

4545
@Override
@@ -62,7 +62,7 @@ protected void configureWorkspace() {
6262

6363
Path settingsWorkspaceFolder = this.context.getSettingsPath().resolve(this.tool)
6464
.resolve(IdeContext.FOLDER_WORKSPACE);
65-
Path genericWorkspaceFolder = this.context.getSettingsPath().resolve(IdeContext.FOLDER_WORKSPACE);
65+
Path genericWorkspaceFolder = this.context.getSettingsPath().resolve(IdeContext.FOLDER_WORKSPACE);
6666
Path workspaceUpdateFolder = genericWorkspaceFolder.resolve(IdeContext.FOLDER_UPDATE);
6767
Path workspaceSetupFolder = genericWorkspaceFolder.resolve(IdeContext.FOLDER_SETUP);
6868
FileAccess fileAccess = this.context.getFileAccess();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.devonfw.tools.ide.commandlet;
2+
3+
import com.devonfw.tools.ide.context.IdeContext;
4+
5+
/**
6+
* Extends {@link CommandletManagerImpl} to make {@link #add(Commandlet)} method visible for testing and mocking.
7+
*/
8+
public class TestCommandletManager extends CommandletManagerImpl {
9+
10+
/**
11+
* @param context the {@link IdeContext}.
12+
*/
13+
public TestCommandletManager(IdeContext context) {
14+
15+
super(context);
16+
}
17+
18+
@Override
19+
public void add(Commandlet commandlet) {
20+
21+
super.add(commandlet);
22+
}
23+
24+
25+
}

cli/src/test/java/com/devonfw/tools/ide/context/AbstractIdeTestContext.java

+51-5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import java.util.HashMap;
66
import java.util.Map;
77

8+
import com.devonfw.tools.ide.commandlet.Commandlet;
9+
import com.devonfw.tools.ide.commandlet.CommandletManager;
10+
import com.devonfw.tools.ide.commandlet.TestCommandletManager;
811
import com.devonfw.tools.ide.common.SystemPath;
912
import com.devonfw.tools.ide.environment.AbstractEnvironmentVariables;
1013
import com.devonfw.tools.ide.environment.EnvironmentVariables;
@@ -37,14 +40,15 @@ public class AbstractIdeTestContext extends AbstractIdeContext {
3740

3841
private ProcessContext mockContext;
3942

43+
private TestCommandletManager testCommandletManager;
44+
4045
/**
4146
* The constructor.
4247
*
4348
* @param logger the {@link IdeLogger}.
4449
* @param workingDirectory the optional {@link Path} to current working directory.
45-
* @param answers the automatic answers simulating a user in test.
4650
*/
47-
public AbstractIdeTestContext(IdeStartContextImpl logger, Path workingDirectory, String... answers) {
51+
public AbstractIdeTestContext(IdeStartContextImpl logger, Path workingDirectory) {
4852

4953
super(logger, workingDirectory);
5054
this.answers = new String[0];
@@ -83,6 +87,10 @@ protected String readLine() {
8387
return this.answers[this.answerIndex++];
8488
}
8589

90+
/**
91+
* @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
92+
* question).
93+
*/
8694
public void setAnswers(String... answers) {
8795
requireMutable();
8896
this.answers = answers;
@@ -103,9 +111,7 @@ public IdeProgressBar prepareProgressBar(String taskName, long size) {
103111
IdeProgressBarTestImpl progressBar = new IdeProgressBarTestImpl(taskName, size);
104112
IdeProgressBarTestImpl duplicate = this.progressBarMap.put(taskName, progressBar);
105113
// If we have multiple downloads or unpacking, we may have an existing "Downloading" or "Unpacking" key
106-
if ((!taskName.equals("Downloading")) && (!taskName.equals("Unpacking"))) {
107-
assert duplicate == null;
108-
}
114+
assert (taskName.equals("Downloading")) || (taskName.equals("Unpacking")) || duplicate == null;
109115
return progressBar;
110116
}
111117

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

200206
this.defaultToolRepository = defaultToolRepository;
201207
}
208+
209+
/**
210+
* @param settingsPath the new value of {@link #getSettingsPath()}.
211+
*/
212+
public void setSettingsPath(Path settingsPath) {
213+
214+
this.settingsPath = settingsPath;
215+
}
216+
217+
/**
218+
* @param pluginsPath the new value of {@link #getPluginsPath()}.
219+
*/
220+
public void setPluginsPath(Path pluginsPath) {
221+
222+
this.pluginsPath = pluginsPath;
223+
}
224+
225+
/**
226+
* @param commandletManager the new value of {@link #getCommandletManager()}.
227+
*/
228+
public void setCommandletManager(CommandletManager commandletManager) {
229+
if (commandletManager instanceof TestCommandletManager tcm) {
230+
this.testCommandletManager = tcm;
231+
} else {
232+
this.testCommandletManager = null;
233+
}
234+
this.commandletManager = commandletManager;
235+
}
236+
237+
/**
238+
* @param commandlet the {@link Commandlet} to add to {@link #getCommandletManager()} for testing.
239+
*/
240+
public void addCommandlet(Commandlet commandlet) {
241+
242+
if (this.testCommandletManager == null) {
243+
setCommandletManager(new TestCommandletManager(this));
244+
}
245+
this.testCommandletManager.add(commandlet);
246+
}
247+
202248
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package com.devonfw.tools.ide.tool.ide;
2+
3+
import java.nio.file.Path;
4+
import java.util.ArrayList;
5+
import java.util.List;
6+
import java.util.Set;
7+
8+
import org.junit.jupiter.api.Test;
9+
import org.junit.jupiter.api.io.TempDir;
10+
11+
import com.devonfw.tools.ide.commandlet.Commandlet;
12+
import com.devonfw.tools.ide.common.Tag;
13+
import com.devonfw.tools.ide.context.AbstractIdeContextTest;
14+
import com.devonfw.tools.ide.context.AbstractIdeTestContext;
15+
import com.devonfw.tools.ide.context.IdeContext;
16+
import com.devonfw.tools.ide.context.IdeSlf4jContext;
17+
import com.devonfw.tools.ide.process.ProcessErrorHandling;
18+
import com.devonfw.tools.ide.process.ProcessMode;
19+
import com.devonfw.tools.ide.process.ProcessResult;
20+
import com.devonfw.tools.ide.process.ProcessResultImpl;
21+
import com.devonfw.tools.ide.step.Step;
22+
import com.devonfw.tools.ide.tool.plugin.ToolPluginDescriptor;
23+
import com.devonfw.tools.ide.version.GenericVersionRange;
24+
25+
/**
26+
* Test of {@link IdeToolCommandlet} using {@link IdeToolDummyCommandlet}.
27+
*/
28+
public class IdeToolDummyCommandletTest extends AbstractIdeContextTest {
29+
30+
/**
31+
* Run the dummy commandlet and test that only active plugins are passed to installPlugin method.
32+
*
33+
* @param tempDir the {@link TempDir}.
34+
*/
35+
@Test
36+
public void testDummyCommandlet(@TempDir Path tempDir) {
37+
38+
AbstractIdeTestContext context = new IdeSlf4jContext();
39+
context.setPluginsPath(tempDir);
40+
context.setSettingsPath(Path.of("src/test/resources/settings/dummy"));
41+
IdeToolDummyCommandlet dummyCommandlet = new IdeToolDummyCommandlet(context, "dummy", Set.of(Tag.IDE));
42+
43+
context.addCommandlet(dummyCommandlet);
44+
45+
Commandlet dummy = context.getCommandletManager().getCommandlet("dummy");
46+
assertThat(dummy).isSameAs(dummyCommandlet);
47+
dummy.run();
48+
assertThat(dummyCommandlet.installedPlugins).hasSize(1);
49+
ToolPluginDescriptor plugin = dummyCommandlet.installedPlugins.get(0);
50+
assertThat(plugin.id()).isEqualTo("plugin1-id");
51+
assertThat(plugin.url()).isEqualTo("https://dummy.com/plugins/plugin1-url");
52+
}
53+
54+
/**
55+
* Dummy commandlet extending {@link IdeToolCommandlet} for testing.
56+
*/
57+
public static class IdeToolDummyCommandlet extends IdeToolCommandlet {
58+
59+
final List<ToolPluginDescriptor> installedPlugins;
60+
61+
IdeToolDummyCommandlet(IdeContext context, String tool, Set<Tag> tags) {
62+
63+
super(context, tool, tags);
64+
this.installedPlugins = new ArrayList<>();
65+
}
66+
67+
@Override
68+
protected void configureWorkspace() {
69+
70+
// disable workspace configuration since we have no IDE_HOME and therefore no settings
71+
}
72+
73+
@Override
74+
public ProcessResult runTool(ProcessMode processMode, GenericVersionRange toolVersion, ProcessErrorHandling errorHandling, String... args) {
75+
76+
// skip installation but trigger postInstall to test mocked plugin installation
77+
postInstall(true);
78+
return new ProcessResultImpl(0, List.of(), List.of());
79+
}
80+
81+
@Override
82+
public void installPlugin(ToolPluginDescriptor plugin, Step step) {
83+
84+
this.installedPlugins.add(plugin);
85+
step.success("Dummy plugin " + plugin.name() + " installed.");
86+
}
87+
88+
}
89+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
plugin_id=plugin1-id
2+
plugin_active=true
3+
plugin_url=https://dummy.com/plugins/plugin1-url
4+
tags=dummy
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
plugin_id=plugin2-id
2+
plugin_active=false
3+
plugin_url=https://dummy.com/plugins/plugin2-url
4+
tags=dummy2

0 commit comments

Comments
 (0)