Skip to content

Commit 8c7b70b

Browse files
committed
Better e2e tests coverage
- Add integration tests for e2e samples. - Add some missing commands for new annotation system. - Backport #654 - Fixes #655
1 parent edfe67c commit 8c7b70b

12 files changed

+523
-11
lines changed

spring-shell-samples/src/main/java/org/springframework/shell/samples/e2e/ErrorHandlingCommands.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ public CommandHandlingResult resolve(Exception e) {
167167
return CommandHandlingResult.of("Hi, handled custom exception 3\n", 3);
168168
}
169169
if (e instanceof CustomException4) {
170-
return CommandHandlingResult.of("Hi, handled custom exception\n", 42);
170+
String msg = String.format("Hi, handled custom exception %s\n", e);
171+
return CommandHandlingResult.of(msg, 42);
171172
}
172173
if (e instanceof IllegalArgumentException) {
173174
return CommandHandlingResult.of("Hi, handled illegal exception\n", 42);

spring-shell-samples/src/test/java/org/springframework/shell/samples/AbstractSampleTests.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022 the original author or authors.
2+
* Copyright 2022-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,8 +15,11 @@
1515
*/
1616
package org.springframework.shell.samples;
1717

18+
import java.util.List;
1819
import java.util.concurrent.TimeUnit;
1920

21+
import org.assertj.core.api.Condition;
22+
2023
import org.springframework.beans.factory.annotation.Autowired;
2124
import org.springframework.context.annotation.Import;
2225
import org.springframework.shell.samples.standard.ResolvedCommands;
@@ -29,9 +32,10 @@
2932
import org.springframework.test.annotation.DirtiesContext;
3033
import org.springframework.test.annotation.DirtiesContext.ClassMode;
3134

35+
import static org.assertj.core.api.Assertions.assertThat;
3236
import static org.awaitility.Awaitility.await;
3337

34-
@ShellTest
38+
@ShellTest(terminalWidth = 120)
3539
@Import(ResolvedCommands.ResolvedCommandsConfiguration.class)
3640
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
3741
public class AbstractSampleTests {
@@ -45,6 +49,17 @@ protected void assertScreenContainsText(BaseShellSession<?> session, String text
4549
});
4650
}
4751

52+
protected void assertScreenNotContainsText(BaseShellSession<?> session, String textFound, String textNotFound) {
53+
Condition<String> notCondition = new Condition<>(line -> line.contains(textNotFound),
54+
String.format("Text '%s' not found", textNotFound));
55+
56+
await().atMost(2, TimeUnit.SECONDS).untilAsserted(() -> {
57+
ShellAssertions.assertThat(session.screen()).containsText(textFound);
58+
List<String> lines = session.screen().lines();
59+
assertThat(lines).areNot(notCondition);
60+
});
61+
}
62+
4863
protected BaseShellSession<?> createSession(String command, boolean interactive) {
4964
if (interactive) {
5065
InteractiveShellSession session = client.interactive().run();
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.shell.samples.e2e;
17+
18+
import org.junit.jupiter.params.ParameterizedTest;
19+
20+
import org.springframework.shell.samples.AbstractSampleTests;
21+
import org.springframework.shell.samples.e2e.ArityCommands.LegacyAnnotation;
22+
import org.springframework.shell.samples.e2e.ArityCommands.Registration;
23+
import org.springframework.shell.test.ShellTestClient.BaseShellSession;
24+
import org.springframework.test.context.ContextConfiguration;
25+
26+
@ContextConfiguration(classes = { LegacyAnnotation.class, Registration.class })
27+
class ArityCommandsTests extends AbstractSampleTests {
28+
29+
@ParameterizedTest
30+
@E2ESource(command = "arity-boolean-default-true")
31+
void defaultBooleanValue(String command, boolean interactive) {
32+
BaseShellSession<?> session = createSession(command, interactive);
33+
assertScreenContainsText(session, "Hello true");
34+
}
35+
36+
@ParameterizedTest
37+
@E2ESource(command = "arity-boolean-default-true --overwrite false")
38+
void defaultBooleanValueOverwrite(String command, boolean interactive) {
39+
BaseShellSession<?> session = createSession(command, interactive);
40+
assertScreenContainsText(session, "Hello false");
41+
}
42+
43+
@ParameterizedTest
44+
@E2ESource(command = "arity-string-array --arg1 foo bar")
45+
void arityStringArray(String command, boolean interactive) {
46+
BaseShellSession<?> session = createSession(command, interactive);
47+
assertScreenContainsText(session, "Hello [foo, bar]");
48+
}
49+
50+
@ParameterizedTest
51+
@E2ESource(command = "arity-float-array --arg1 1 2")
52+
void arityFloatArray(String command, boolean interactive) {
53+
BaseShellSession<?> session = createSession(command, interactive);
54+
assertScreenContainsText(session, "Hello [1.0,2.0]");
55+
}
56+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.shell.samples.e2e;
17+
18+
import org.junit.jupiter.params.ParameterizedTest;
19+
20+
import org.springframework.shell.samples.AbstractSampleTests;
21+
import org.springframework.shell.samples.e2e.DefaultValueCommands.LegacyAnnotation;
22+
import org.springframework.shell.samples.e2e.DefaultValueCommands.Registration;
23+
import org.springframework.shell.test.ShellTestClient.BaseShellSession;
24+
import org.springframework.test.context.ContextConfiguration;
25+
26+
@ContextConfiguration(classes = { LegacyAnnotation.class, Registration.class })
27+
class DefaultValueCommandsTests extends AbstractSampleTests {
28+
29+
@ParameterizedTest
30+
@E2ESource(command = "default-value")
31+
void defaultValue(String command, boolean interactive) {
32+
BaseShellSession<?> session = createSession(command, interactive);
33+
assertScreenContainsText(session, "Hello hi");
34+
}
35+
36+
@ParameterizedTest
37+
@E2ESource(command = "default-value-boolean1")
38+
void defaultValueBoolean1(String command, boolean interactive) {
39+
BaseShellSession<?> session = createSession(command, interactive);
40+
assertScreenContainsText(session, "Hello false");
41+
}
42+
43+
@ParameterizedTest
44+
@E2ESource(command = "default-value-boolean2")
45+
void defaultValueBoolean2(String command, boolean interactive) {
46+
BaseShellSession<?> session = createSession(command, interactive);
47+
assertScreenContainsText(session, "Hello true");
48+
}
49+
50+
@ParameterizedTest
51+
@E2ESource(command = "default-value-boolean3")
52+
void defaultValueBoolean3(String command, boolean interactive) {
53+
BaseShellSession<?> session = createSession(command, interactive);
54+
assertScreenContainsText(session, "Hello false");
55+
}
56+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.shell.samples.e2e;
17+
18+
import java.util.ArrayList;
19+
import java.util.List;
20+
import java.util.stream.Stream;
21+
22+
import org.junit.jupiter.api.extension.ExtensionContext;
23+
import org.junit.jupiter.params.provider.Arguments;
24+
import org.junit.jupiter.params.provider.ArgumentsProvider;
25+
import org.junit.jupiter.params.support.AnnotationConsumer;
26+
27+
class E2EArgumentsProvider implements ArgumentsProvider, AnnotationConsumer<E2ESource> {
28+
29+
private E2ESource annotation;
30+
31+
@Override
32+
public void accept(E2ESource annotation) {
33+
this.annotation = annotation;
34+
}
35+
36+
@Override
37+
public Stream<? extends Arguments> provideArguments(ExtensionContext context) throws Exception {
38+
String command = this.annotation.command();
39+
List<Arguments> arguments = new ArrayList<>();
40+
boolean anno = this.annotation.anno();
41+
boolean reg = this.annotation.reg();
42+
if (anno) {
43+
arguments.add(Arguments.of(String.format("e2e %s %s", "anno", command), false));
44+
arguments.add(Arguments.of(String.format("e2e %s %s", "anno", command), true));
45+
}
46+
if (reg) {
47+
arguments.add(Arguments.of(String.format("e2e %s %s", "reg", command), false));
48+
arguments.add(Arguments.of(String.format("e2e %s %s", "reg", command), true));
49+
}
50+
return arguments.stream();
51+
}
52+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.shell.samples.e2e;
17+
18+
import java.lang.annotation.Documented;
19+
import java.lang.annotation.ElementType;
20+
import java.lang.annotation.Retention;
21+
import java.lang.annotation.RetentionPolicy;
22+
import java.lang.annotation.Target;
23+
24+
import org.junit.jupiter.params.provider.ArgumentsSource;
25+
26+
/**
27+
* JUnit source creating a matrix for command combinations.
28+
*
29+
* @author Janne Valkealahti
30+
*/
31+
@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
32+
@Retention(RetentionPolicy.RUNTIME)
33+
@Documented
34+
@ArgumentsSource(E2EArgumentsProvider.class)
35+
@interface E2ESource {
36+
37+
String command();
38+
39+
boolean anno() default true;
40+
41+
boolean reg() default true;
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.shell.samples.e2e;
17+
18+
import org.junit.jupiter.api.Disabled;
19+
import org.junit.jupiter.params.ParameterizedTest;
20+
21+
import org.springframework.shell.samples.AbstractSampleTests;
22+
import org.springframework.shell.samples.e2e.ErrorHandlingCommands.LegacyAnnotation;
23+
import org.springframework.shell.samples.e2e.ErrorHandlingCommands.Registration;
24+
import org.springframework.shell.test.ShellTestClient.BaseShellSession;
25+
import org.springframework.test.context.ContextConfiguration;
26+
27+
@ContextConfiguration(classes = { LegacyAnnotation.class, Registration.class })
28+
class ErrorHandlingCommandsTests extends AbstractSampleTests {
29+
30+
@ParameterizedTest
31+
@E2ESource(command = "error-handling --arg1 throw1")
32+
void testErrorHandling1(String command, boolean interactive) {
33+
BaseShellSession<?> session = createSession(command, interactive);
34+
assertScreenContainsText(session, "Hi, handled custom exception");
35+
}
36+
37+
@Disabled("trouble with spring-shell-test")
38+
@ParameterizedTest
39+
@E2ESource(command = "error-handling --arg1 throw2")
40+
void testErrorHandling2(String command, boolean interactive) {
41+
BaseShellSession<?> session = createSession(command, interactive);
42+
assertScreenContainsText(session, "org.springframework.shell.samples.e2e.ErrorHandlingCommands$CustomException2");
43+
}
44+
45+
@Disabled("trouble with spring-shell-test")
46+
@ParameterizedTest
47+
@E2ESource(command = "error-handling --arg1 throw3")
48+
void testErrorHandling3(String command, boolean interactive) {
49+
BaseShellSession<?> session = createSession(command, interactive);
50+
assertScreenContainsText(session, "java.lang.RuntimeException");
51+
}
52+
53+
@ParameterizedTest
54+
@E2ESource(command = "error-handling --arg1 throw4")
55+
void testErrorHandling4(String command, boolean interactive) {
56+
BaseShellSession<?> session = createSession(command, interactive);
57+
assertScreenContainsText(session, "Hi, handled illegal exception");
58+
}
59+
60+
@ParameterizedTest
61+
@E2ESource(command = "error-handling --arg1 throw5")
62+
void testErrorHandling5(String command, boolean interactive) {
63+
BaseShellSession<?> session = createSession(command, interactive);
64+
assertScreenContainsText(session, "Hi, handled custom exception 3");
65+
}
66+
67+
@ParameterizedTest
68+
@E2ESource(command = "error-handling --arg1 throw6")
69+
void testErrorHandling6(String command, boolean interactive) {
70+
BaseShellSession<?> session = createSession(command, interactive);
71+
assertScreenContainsText(session, "Hi, handled custom exception org.springframework.shell.samples.e2e.ErrorHandlingCommands$CustomException4");
72+
}
73+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.shell.samples.e2e;
17+
18+
import org.junit.jupiter.params.ParameterizedTest;
19+
20+
import org.springframework.shell.samples.AbstractSampleTests;
21+
import org.springframework.shell.samples.e2e.HelpOptionCommands.LegacyAnnotation;
22+
import org.springframework.shell.samples.e2e.HelpOptionCommands.Registration;
23+
import org.springframework.shell.test.ShellTestClient.BaseShellSession;
24+
import org.springframework.test.context.ContextConfiguration;
25+
26+
@ContextConfiguration(classes = { LegacyAnnotation.class, Registration.class })
27+
class HelpOptionCommandsTests extends AbstractSampleTests {
28+
29+
@ParameterizedTest
30+
@E2ESource(command = "help-option-default -h")
31+
void testHelpOptionDefault(String command, boolean interactive) {
32+
BaseShellSession<?> session = createSession(command, interactive);
33+
assertScreenContainsText(session, "NAME");
34+
}
35+
36+
@ParameterizedTest
37+
@E2ESource(command = "help-option-exists --help hi", anno = false)
38+
void testHelpOptionExists1(String command, boolean interactive) {
39+
BaseShellSession<?> session = createSession(command, interactive);
40+
assertScreenContainsText(session, "Hello hi");
41+
}
42+
43+
@ParameterizedTest
44+
@E2ESource(command = "help-option-exists --myhelp", anno = false)
45+
void testHelpOptionExists2(String command, boolean interactive) {
46+
BaseShellSession<?> session = createSession(command, interactive);
47+
assertScreenContainsText(session, "NAME");
48+
}
49+
}

0 commit comments

Comments
 (0)