Skip to content

Commit badde3a

Browse files
committedJan 1, 2017
Add Kotlin based ScriptTemplateView rendering test
Kotlin JSR 223 support currently requires kotlin-script-util dependency (jcabi-aether, maven-core and aether-api can be excluded since they are only used for live import of dependencies and bring a lot of JARs in the classpath) and a /META-INF/services/javax.script.ScriptEngineFactory file specifying the ScriptEngineFactory to use, in that case org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory. Issue: SPR-15059
1 parent ef43400 commit badde3a

File tree

5 files changed

+121
-0
lines changed

5 files changed

+121
-0
lines changed
 

‎build.gradle

+9
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,15 @@ project("spring-webmvc") {
969969
testCompile("org.mozilla:rhino:1.7.7.1")
970970
testRuntime("org.jruby:jruby:9.1.6.0")
971971
testRuntime("org.python:jython-standalone:2.5.3")
972+
// Ideally, kotlin-script-runtime should be enough for JSR-223, but that's not
973+
// the case yet, so we depend on kotlin-script-util and exclude these
974+
// dependencies only used for artifact retrieval. Point raised to Kotlin team.
975+
testRuntime("org.jetbrains.kotlin:kotlin-compiler:${kotlinVersion}")
976+
testRuntime("org.jetbrains.kotlin:kotlin-script-util:${kotlinVersion}") {
977+
exclude group: "com.jcabi", module: "jcabi-aether"
978+
exclude group: "org.apache.maven", module: "maven-core"
979+
exclude group: "org.sonatype.aether", module: "aether-api"
980+
}
972981
testRuntime("org.webjars:underscorejs:1.8.3")
973982
testRuntime("org.glassfish:javax.el:3.0.1-b08")
974983
testRuntime("com.sun.xml.bind:jaxb-core:${jaxbVersion}")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Copyright 2002-2015 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+
* 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 org.springframework.web.servlet.view.script;
18+
19+
import java.util.HashMap;
20+
import java.util.Map;
21+
import javax.servlet.ServletContext;
22+
23+
import static org.junit.Assert.assertEquals;
24+
import org.junit.Before;
25+
import org.junit.Test;
26+
import static org.mockito.Mockito.mock;
27+
28+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
29+
import org.springframework.context.annotation.Bean;
30+
import org.springframework.context.annotation.Configuration;
31+
import org.springframework.mock.web.test.MockHttpServletRequest;
32+
import org.springframework.mock.web.test.MockHttpServletResponse;
33+
import org.springframework.mock.web.test.MockServletContext;
34+
import org.springframework.web.context.WebApplicationContext;
35+
36+
/**
37+
* Unit tests for Kotlin script templates running on Kotlin JSR 223 support
38+
*
39+
* @author Sebastien Deleuze
40+
*/
41+
public class KotlinScriptTemplateTests {
42+
43+
private WebApplicationContext webAppContext;
44+
45+
private ServletContext servletContext;
46+
47+
48+
@Before
49+
public void setup() {
50+
this.webAppContext = mock(WebApplicationContext.class);
51+
this.servletContext = new MockServletContext();
52+
this.servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.webAppContext);
53+
}
54+
55+
@Test
56+
public void renderTemplate() throws Exception {
57+
Map<String, Object> model = new HashMap<>();
58+
model.put("title", "Layout example");
59+
model.put("body", "This is the body");
60+
MockHttpServletResponse response = renderViewWithModel("org/springframework/web/servlet/view/script/kotlin/template.kts",
61+
model, ScriptTemplatingConfiguration.class);
62+
assertEquals("<html><head><title>Layout example</title></head><body><p>This is the body</p></body></html>",
63+
response.getContentAsString());
64+
}
65+
66+
private MockHttpServletResponse renderViewWithModel(String viewUrl, Map<String, Object> model, Class<?> configuration) throws Exception {
67+
ScriptTemplateView view = createViewWithUrl(viewUrl, configuration);
68+
MockHttpServletResponse response = new MockHttpServletResponse();
69+
MockHttpServletRequest request = new MockHttpServletRequest();
70+
view.renderMergedOutputModel(model, request, response);
71+
return response;
72+
}
73+
74+
private ScriptTemplateView createViewWithUrl(String viewUrl, Class<?> configuration) throws Exception {
75+
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
76+
ctx.register(configuration);
77+
ctx.refresh();
78+
79+
ScriptTemplateView view = new ScriptTemplateView();
80+
view.setApplicationContext(ctx);
81+
view.setUrl(viewUrl);
82+
view.afterPropertiesSet();
83+
return view;
84+
}
85+
86+
87+
@Configuration
88+
static class ScriptTemplatingConfiguration {
89+
90+
@Bean
91+
public ScriptTemplateConfigurer kotlinScriptConfigurer() {
92+
ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();
93+
configurer.setEngineName("kotlin");
94+
configurer.setScripts("org/springframework/web/servlet/view/script/kotlin/render.kts");
95+
configurer.setRenderFunction("render");
96+
return configurer;
97+
}
98+
}
99+
100+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import javax.script.*
2+
3+
// TODO Use engine.eval(String, Bindings) when https://youtrack.jetbrains.com/issue/KT-15450 will be fixed
4+
fun render(template: String, model: Map<String, Any>, url: String): String {
5+
val engine = ScriptEngineManager().getEngineByName("kotlin")
6+
val bindings = SimpleBindings()
7+
bindings.putAll(model)
8+
engine.setBindings(bindings, ScriptContext.ENGINE_SCOPE)
9+
return engine.eval(template) as String
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""<html><head><title>${bindings["title"]}</title></head><body><p>${bindings["body"]}</p></body></html>"""

0 commit comments

Comments
 (0)
Please sign in to comment.