Skip to content

Commit f339cb2

Browse files
committed
Provoke a more visible and intuitive error if a user tries to use ParameterParser without ANTLR runtime
1 parent cb47dae commit f339cb2

File tree

16 files changed

+430
-7
lines changed

16 files changed

+430
-7
lines changed

config/codenarc/codenarc.groovy

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,10 @@ ruleset {
499499
UnusedObject
500500
UnusedPrivateField
501501
UnusedPrivateMethod {
502-
doNotApplyToClassNames = 'net.kautler.command.integ.test.spock.AddBeansExtension'
502+
doNotApplyToClassNames = [
503+
'net.kautler.command.integ.test.spock.AddBeansExtension',
504+
'net.kautler.command.integ.test.spock.VetoBeansExtension'
505+
].join(', ')
503506
}
504507
UnusedPrivateMethodParameter
505508
UnusedVariable

src/integTestCommon/groovy/net/kautler/command/integ/test/spock/AddBean.groovy

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019 Björn Kautler
2+
* Copyright 2020 Björn Kautler
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.
@@ -21,10 +21,11 @@ import java.lang.annotation.Retention
2121
import java.lang.annotation.Target
2222

2323
import static java.lang.annotation.ElementType.METHOD
24+
import static java.lang.annotation.ElementType.TYPE
2425
import static java.lang.annotation.RetentionPolicy.RUNTIME
2526

2627
@Retention(RUNTIME)
27-
@Target(METHOD)
28+
@Target([TYPE, METHOD])
2829
@Repeatable(AddBeans)
2930
@interface AddBean {
3031
Class<?> value()

src/integTestCommon/groovy/net/kautler/command/integ/test/spock/AddBeans.groovy

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019 Björn Kautler
2+
* Copyright 2020 Björn Kautler
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.
@@ -20,10 +20,11 @@ import java.lang.annotation.Retention
2020
import java.lang.annotation.Target
2121

2222
import static java.lang.annotation.ElementType.METHOD
23+
import static java.lang.annotation.ElementType.TYPE
2324
import static java.lang.annotation.RetentionPolicy.RUNTIME
2425

2526
@Retention(RUNTIME)
26-
@Target(METHOD)
27+
@Target([TYPE, METHOD])
2728
@interface AddBeans {
2829
AddBean[] value()
2930
}

src/integTestCommon/groovy/net/kautler/command/integ/test/spock/CDIExtension.groovy

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019 Björn Kautler
2+
* Copyright 2020 Björn Kautler
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.
@@ -30,10 +30,13 @@ class CDIExtension extends AbstractGlobalExtension {
3030
void visitSpec(SpecInfo spec) {
3131
spec.allFeatures.featureMethod.each { featureMethod ->
3232
featureMethod.addInterceptor { invocation ->
33+
def annotatedElements = [spec.reflection, featureMethod.reflection]
3334
def seContainer = SeContainerInitializer.newInstance()
3435
.addProperty('javax.enterprise.inject.scan.implicit', TRUE)
3536
.addExtensions(new AddBeansExtension(
36-
featureMethod.reflection.getAnnotationsByType(AddBean)*.value()))
37+
annotatedElements*.getAnnotationsByType(AddBean).flatten()*.value()))
38+
.addExtensions(new VetoBeansExtension(
39+
annotatedElements*.getAnnotationsByType(VetoBean).flatten()*.value()))
3740
.initialize()
3841
try {
3942
invocation.proceed()
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2020 Björn Kautler
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+
* http://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+
17+
package net.kautler.command.integ.test.spock
18+
19+
import java.lang.annotation.Repeatable
20+
import java.lang.annotation.Retention
21+
import java.lang.annotation.Target
22+
23+
import static java.lang.annotation.ElementType.METHOD
24+
import static java.lang.annotation.ElementType.TYPE
25+
import static java.lang.annotation.RetentionPolicy.RUNTIME
26+
27+
@Retention(RUNTIME)
28+
@Target([TYPE, METHOD])
29+
@Repeatable(VetoBeans)
30+
@interface VetoBean {
31+
Class<?> value()
32+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright 2020 Björn Kautler
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+
* http://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+
17+
package net.kautler.command.integ.test.spock
18+
19+
import java.lang.annotation.Retention
20+
import java.lang.annotation.Target
21+
22+
import static java.lang.annotation.ElementType.METHOD
23+
import static java.lang.annotation.ElementType.TYPE
24+
import static java.lang.annotation.RetentionPolicy.RUNTIME
25+
26+
@Retention(RUNTIME)
27+
@Target([TYPE, METHOD])
28+
@interface VetoBeans {
29+
VetoBean[] value()
30+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright 2020 Björn Kautler
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+
* http://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+
17+
package net.kautler.command.integ.test.spock
18+
19+
import javax.enterprise.event.Observes
20+
import javax.enterprise.inject.spi.Extension
21+
import javax.enterprise.inject.spi.ProcessAnnotatedType
22+
23+
class VetoBeansExtension implements Extension {
24+
def beans
25+
26+
VetoBeansExtension(Collection<Class<?>> beans) {
27+
this.beans = beans
28+
}
29+
30+
private void vetoBean(@Observes ProcessAnnotatedType processAnnotatedType) {
31+
if (processAnnotatedType.annotatedType.javaClass in beans) {
32+
processAnnotatedType.veto()
33+
}
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright 2020 Björn Kautler
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+
* http://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+
17+
package net.kautler.command.integ.test.javacord.parameter
18+
19+
import net.kautler.command.api.Command
20+
import net.kautler.command.api.parameter.ParameterParser
21+
import net.kautler.command.integ.test.spock.AddBean
22+
import net.kautler.command.integ.test.spock.VetoBean
23+
import net.kautler.command.parameter.parser.UntypedParameterParser
24+
import net.kautler.command.parameter.parser.missingdependency.MissingDependencyParameterParser
25+
import org.javacord.api.entity.channel.ServerTextChannel
26+
import org.javacord.api.entity.message.Message
27+
import spock.lang.Specification
28+
import spock.lang.Subject
29+
import spock.util.concurrent.BlockingVariable
30+
import spock.util.concurrent.PollingConditions
31+
32+
import javax.enterprise.context.ApplicationScoped
33+
import javax.enterprise.inject.Vetoed
34+
import javax.inject.Inject
35+
36+
import static org.apache.logging.log4j.Level.ERROR
37+
import static org.apache.logging.log4j.test.appender.ListAppender.getListAppender
38+
39+
@Subject(MissingDependencyParameterParser)
40+
@VetoBean(UntypedParameterParser)
41+
class MissingDependencyParameterParserIntegTest extends Specification {
42+
@AddBean(PingCommand)
43+
def 'missing dependency parameter parser should throw UnsupportedOperationException'(
44+
ServerTextChannel serverTextChannelAsBot, ServerTextChannel serverTextChannelAsUser) {
45+
given:
46+
def commandReceived = new BlockingVariable<Boolean>(System.properties.testResponseTimeout as double)
47+
48+
and:
49+
def listenerManager = serverTextChannelAsBot.addMessageCreateListener {
50+
if ((it.message.userAuthor.orElse(null) == serverTextChannelAsUser.api.yourself) &&
51+
(it.message.content == '!ping')) {
52+
commandReceived.set(true)
53+
}
54+
}
55+
56+
when:
57+
serverTextChannelAsUser
58+
.sendMessage('!ping')
59+
.join()
60+
61+
then:
62+
commandReceived.get()
63+
64+
and:
65+
new PollingConditions(timeout: System.properties.testResponseTimeout as double).eventually {
66+
getListAppender('Test Appender')
67+
.events
68+
.any {
69+
(it.level == ERROR) &&
70+
(it.thrown instanceof UnsupportedOperationException) &&
71+
(it.thrown.message == 'ANTLR runtime is missing')
72+
}
73+
}
74+
75+
cleanup:
76+
listenerManager?.remove()
77+
78+
and:
79+
getListAppender('Test Appender').@events.removeIf {
80+
(it.level == ERROR) &&
81+
(it.thrown instanceof UnsupportedOperationException) &&
82+
(it.thrown.message == 'ANTLR runtime is missing')
83+
}
84+
}
85+
86+
@Vetoed
87+
@ApplicationScoped
88+
static class PingCommand implements Command<Message> {
89+
@Inject
90+
ParameterParser parameterParser
91+
92+
@Override
93+
void execute(Message incomingMessage, String prefix, String usedAlias, String parameterString) {
94+
parameterParser.toString()
95+
}
96+
}
97+
}

src/javacordIntegTest/groovy/net/kautler/command/integ/test/javacord/parameter/TypedParameterParserIntegTest.groovy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ import net.kautler.command.api.parameter.ParameterParser
2424
import net.kautler.command.api.parameter.ParameterParser.Typed
2525
import net.kautler.command.api.parameter.ParameterType
2626
import net.kautler.command.integ.test.spock.AddBean
27+
import net.kautler.command.integ.test.spock.VetoBean
2728
import net.kautler.command.parameter.parser.TypedParameterParser
29+
import net.kautler.command.parameter.parser.missingdependency.MissingDependencyParameterParser
2830
import org.javacord.api.entity.channel.ServerTextChannel
2931
import org.javacord.api.entity.message.Message
3032
import org.javacord.api.util.logging.ExceptionLogger
@@ -41,6 +43,7 @@ import javax.inject.Inject
4143
import static java.util.UUID.randomUUID
4244

4345
@Subject(TypedParameterParser)
46+
@VetoBean(MissingDependencyParameterParser)
4447
class TypedParameterParserIntegTest extends Specification {
4548
@AddBean(PingCommand)
4649
@AddBean(CustomStringsConverter)

src/javacordIntegTest/groovy/net/kautler/command/integ/test/javacord/parameter/UntypedParameterParserIntegTest.groovy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ import net.kautler.command.api.Command
2020
import net.kautler.command.api.annotation.Usage
2121
import net.kautler.command.api.parameter.ParameterParser
2222
import net.kautler.command.integ.test.spock.AddBean
23+
import net.kautler.command.integ.test.spock.VetoBean
2324
import net.kautler.command.parameter.parser.UntypedParameterParser
25+
import net.kautler.command.parameter.parser.missingdependency.MissingDependencyParameterParser
2426
import org.javacord.api.entity.channel.ServerTextChannel
2527
import org.javacord.api.entity.message.Message
2628
import org.javacord.api.util.logging.ExceptionLogger
@@ -35,6 +37,7 @@ import javax.inject.Inject
3537
import static java.util.UUID.randomUUID
3638

3739
@Subject(UntypedParameterParser)
40+
@VetoBean(MissingDependencyParameterParser)
3841
class UntypedParameterParserIntegTest extends Specification {
3942
@AddBean(PingCommand)
4043
def 'untyped parameter parser should work properly'(

0 commit comments

Comments
 (0)