Skip to content

Commit fc1c9ad

Browse files
authored
Merge pull request #203 from grails/commands/create-interceptor
Add command create-interceptor
2 parents 1fdad47 + b2e50fa commit fc1c9ad

File tree

5 files changed

+290
-0
lines changed

5 files changed

+290
-0
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright 2017-2020 original 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.grails.forge.cli.command;
17+
18+
import io.micronaut.context.annotation.Parameter;
19+
import io.micronaut.core.annotation.ReflectiveAccess;
20+
import io.micronaut.core.util.functional.ThrowingSupplier;
21+
import jakarta.inject.Inject;
22+
import org.grails.forge.application.Project;
23+
import org.grails.forge.cli.CodeGenConfig;
24+
import org.grails.forge.cli.command.templates.interceptor;
25+
import org.grails.forge.cli.command.templates.interceptorSpec;
26+
import org.grails.forge.io.ConsoleOutput;
27+
import org.grails.forge.io.OutputHandler;
28+
import org.grails.forge.template.RenderResult;
29+
import org.grails.forge.template.RockerTemplate;
30+
import org.grails.forge.template.TemplateRenderer;
31+
import picocli.CommandLine;
32+
33+
import java.io.IOException;
34+
35+
@CommandLine.Command(name = CreateInterceptorCommand.NAME, description = "Creates a Interceptor Class")
36+
public class CreateInterceptorCommand extends CodeGenCommand {
37+
38+
public static final String NAME = "create-interceptor";
39+
40+
@ReflectiveAccess
41+
@CommandLine.Parameters(paramLabel = "INTERCEPTOR-NAME", description = "The name of the interceptor to create")
42+
String interceptorName;
43+
44+
@Inject
45+
public CreateInterceptorCommand(@Parameter CodeGenConfig config) {
46+
super(config);
47+
}
48+
49+
public CreateInterceptorCommand(CodeGenConfig config,
50+
ThrowingSupplier<OutputHandler, IOException> outputHandlerSupplier,
51+
ConsoleOutput consoleOutput) {
52+
super(config, outputHandlerSupplier, consoleOutput);
53+
}
54+
55+
@Override
56+
public boolean applies() {
57+
return true;
58+
}
59+
60+
@Override
61+
public Integer call() throws Exception {
62+
final Project project = getProject(interceptorName);
63+
final TemplateRenderer templateRenderer = getTemplateRenderer(project);
64+
final RenderResult renderResult = templateRenderer.render(new RockerTemplate("grails-app/controllers/{packagePath}/{className}Interceptor.groovy", interceptor.template(project)), overwrite);
65+
final RenderResult specRenderResult = templateRenderer.render(new RockerTemplate("src/test/groovy/{packagePath}/{className}InterceptorSpec.groovy", interceptorSpec.template(project)), overwrite);
66+
if (renderResult != null && specRenderResult != null) {
67+
logRenderResult(renderResult);
68+
logRenderResult(specRenderResult);
69+
}
70+
71+
return 0;
72+
}
73+
74+
private void logRenderResult(RenderResult result) throws Exception {
75+
if (result != null) {
76+
if (result.isSuccess()) {
77+
out("@|blue ||@ Rendered interceptor class to " + result.getPath());
78+
} else if (result.isSkipped()) {
79+
warning("Rendering skipped for " + result.getPath() + " because it already exists. Run again with -f to overwrite.");
80+
} else if (result.getError() != null) {
81+
throw result.getError();
82+
}
83+
}
84+
}
85+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
@import org.grails.forge.application.Project
2+
3+
@args (
4+
Project project
5+
)
6+
7+
@if(project.getPackageName() != null) {
8+
package @project.getPackageName()
9+
10+
}
11+
12+
class @project.getClassName()Interceptor {
13+
14+
boolean before() { true }
15+
16+
boolean after() { true }
17+
18+
void afterView() {
19+
// no-op
20+
}
21+
22+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
@import org.grails.forge.application.Project
2+
3+
@args (
4+
Project project
5+
)
6+
7+
@if(project.getPackageName() != null) {
8+
package @project.getPackageName()
9+
10+
}
11+
12+
import grails.testing.web.interceptor.InterceptorUnitTest
13+
import spock.lang.Specification
14+
15+
class @project.getClassName()InterceptorSpec extends Specification implements InterceptorUnitTest<@project.getClassName()Interceptor> {
16+
17+
void "test interceptor matching"() {
18+
when:
19+
withRequest(controller: "@project.getClassName().toLowerCase()")
20+
21+
then:
22+
interceptor.doesMatch()
23+
}
24+
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package org.grails.forge.cli.command
2+
3+
import io.micronaut.context.ApplicationContext
4+
import org.grails.forge.application.ApplicationType
5+
import org.grails.forge.cli.CodeGenConfig
6+
import org.grails.forge.cli.CommandFixture
7+
import org.grails.forge.cli.CommandSpec
8+
import org.grails.forge.io.ConsoleOutput
9+
import spock.lang.AutoCleanup
10+
import spock.lang.Shared
11+
12+
class CreateInterceptorCommandSpec extends CommandSpec implements CommandFixture {
13+
14+
@Shared
15+
@AutoCleanup
16+
ApplicationContext beanContext = ApplicationContext.run()
17+
18+
19+
void "test creating a service"() {
20+
21+
setup:
22+
generateProject(ApplicationType.WEB)
23+
CodeGenConfig codeGenConfig = CodeGenConfig.load(beanContext, dir, ConsoleOutput.NOOP)
24+
ConsoleOutput consoleOutput = Mock(ConsoleOutput)
25+
CreateInterceptorCommand command = new CreateInterceptorCommand(codeGenConfig, getOutputHandler(consoleOutput), consoleOutput)
26+
command.interceptorName = "test"
27+
28+
when:
29+
Integer exitCode = command.call()
30+
File output = new File(dir, "grails-app/controllers/example/grails/TestInterceptor.groovy")
31+
File specOutput = new File(dir, "src/test/groovy/example/grails/TestInterceptorSpec.groovy")
32+
33+
then:
34+
exitCode == 0
35+
output.exists()
36+
specOutput.exists()
37+
2 * consoleOutput.out({ it.contains("Rendered interceptor") })
38+
}
39+
40+
void "test app with interceptor"() {
41+
setup:
42+
generateProject(ApplicationType.WEB)
43+
CodeGenConfig codeGenConfig = CodeGenConfig.load(beanContext, dir, ConsoleOutput.NOOP)
44+
ConsoleOutput consoleOutput = Mock(ConsoleOutput)
45+
CreateInterceptorCommand command = new CreateInterceptorCommand(codeGenConfig, getOutputHandler(consoleOutput), consoleOutput)
46+
47+
new File(dir, "grails-app/controllers/example/grails/TestController.groovy").text = '''package example.grails
48+
49+
class TestController {
50+
51+
def index() {
52+
render request.getAttribute('foo')
53+
}
54+
55+
}'''
56+
57+
58+
when:
59+
command.interceptorName = 'test'
60+
Integer exitCode = command.call()
61+
executeGradleCommand("test")
62+
63+
then:
64+
exitCode == 0
65+
testOutputContains("BUILD SUCCESSFUL")
66+
67+
when:
68+
new File(dir, "src/test/groovy/example/grails/TestInterceptorSpec.groovy").text = '''package example.grails
69+
70+
import grails.testing.web.interceptor.InterceptorUnitTest
71+
import spock.lang.Specification
72+
73+
class TestInterceptorSpec extends Specification implements InterceptorUnitTest<TestInterceptor> {
74+
75+
void "test interceptor matching"() {
76+
when:
77+
withRequest(controller: "test")
78+
79+
then:
80+
interceptor.doesMatch()
81+
82+
when:
83+
withRequest(controller: "person")
84+
85+
then:
86+
!interceptor.doesMatch()
87+
}
88+
89+
void "test controller execution with interceptors"() {
90+
given:
91+
def controller = (TestController)mockController(TestController)
92+
93+
when:
94+
withInterceptors([controller: "test"]) {
95+
controller.renderAttribute()
96+
}
97+
98+
then:
99+
response.text == "Foo is Bar"
100+
}
101+
}'''
102+
executeGradleCommand("test")
103+
104+
then:
105+
testOutputContains("TestInterceptorSpec > test controller execution with interceptors FAILED")
106+
107+
when:
108+
new File(dir, "grails-app/controllers/example/grails/TestInterceptor.groovy").text = '''package example.grails
109+
110+
class TestInterceptor {
111+
112+
TestInterceptor() {
113+
match(controller: "test")
114+
}
115+
116+
boolean before() {
117+
request.setAttribute('foo', 'Foo is Bar')
118+
true
119+
}
120+
}'''
121+
122+
executeGradleCommand("test")
123+
124+
then:
125+
testOutputContains("BUILD SUCCESSFUL")
126+
}
127+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.grails.forge.cli.command
2+
3+
import io.micronaut.configuration.picocli.PicocliRunner
4+
import org.grails.forge.cli.CodeGenConfig
5+
import org.grails.forge.utils.CommandSpec
6+
import spock.lang.Ignore
7+
8+
class CreateInterceptorSpec extends CommandSpec {
9+
10+
@Ignore
11+
void "test create-interceptor command"() {
12+
when:
13+
generateProjectWithDefaults()
14+
applicationContext.createBean(CodeGenConfig.class, new CodeGenConfig())
15+
16+
then:
17+
applicationContext.getBean(CodeGenConfig.class)
18+
19+
when:
20+
PicocliRunner.run(CreateInterceptorCommand.class, applicationContext, "test")
21+
22+
then:
23+
new File(dir, "grails-app/controllers/example/grails/TestInterceptor.groovy").exists()
24+
new File(dir, "src/tests/example/grails/TestInterceptorSpec.groovy").exists()
25+
26+
}
27+
28+
@Override
29+
String getTempDirectoryPrefix() {
30+
return "test-app"
31+
}
32+
}

0 commit comments

Comments
 (0)