PageRenderTime 43ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/sitebricks/src/test/java/com/google/sitebricks/compiler/FreemarkerTemplateCompilerTest.java

https://github.com/mgenov/sitebricks
Java | 429 lines | 222 code | 80 blank | 127 comment | 7 complexity | 8812e2d7d2aa8993860da1ed7bd8a2b2 MD5 | raw file
  1. package com.google.sitebricks.compiler;
  2. import com.google.common.collect.Maps;
  3. import com.google.inject.AbstractModule;
  4. import com.google.inject.Guice;
  5. import com.google.inject.Injector;
  6. import com.google.inject.Provider;
  7. import com.google.inject.TypeLiteral;
  8. import com.google.sitebricks.Bricks;
  9. import com.google.sitebricks.Evaluator;
  10. import com.google.sitebricks.MemoryTemplateSource;
  11. import com.google.sitebricks.MvelEvaluator;
  12. import com.google.sitebricks.Renderable;
  13. import com.google.sitebricks.Respond;
  14. import com.google.sitebricks.RespondersForTesting;
  15. import com.google.sitebricks.Template;
  16. import com.google.sitebricks.compiler.template.freemarker.FreemarkerTemplateCompiler;
  17. import com.google.sitebricks.http.Delete;
  18. import com.google.sitebricks.http.Get;
  19. import com.google.sitebricks.http.Patch;
  20. import com.google.sitebricks.http.Post;
  21. import com.google.sitebricks.http.Put;
  22. import com.google.sitebricks.rendering.EmbedAs;
  23. import com.google.sitebricks.rendering.control.WidgetRegistry;
  24. import com.google.sitebricks.routing.PageBook;
  25. import com.google.sitebricks.routing.SystemMetrics;
  26. import org.testng.annotations.BeforeMethod;
  27. import org.testng.annotations.DataProvider;
  28. import org.testng.annotations.Test;
  29. import java.lang.annotation.Annotation;
  30. import java.util.Map;
  31. import javax.servlet.http.HttpServletRequest;
  32. import static org.easymock.EasyMock.createMock;
  33. import static org.easymock.EasyMock.createNiceMock;
  34. import static org.easymock.EasyMock.expect;
  35. import static org.easymock.EasyMock.replay;
  36. import static org.testng.Assert.assertEquals;
  37. /**
  38. * @author Dhanji R. Prasanna (dhanji@gmail.com)
  39. */
  40. public class FreemarkerTemplateCompilerTest {
  41. private static final String ANNOTATION_EXPRESSIONS = "Annotation expressions";
  42. private Injector injector;
  43. private PageBook pageBook;
  44. private SystemMetrics metrics;
  45. private final Map<String, Class<? extends Annotation>> methods = Maps.newHashMap();
  46. @BeforeMethod
  47. public void pre() {
  48. methods.put("get", Get.class);
  49. methods.put("post", Post.class);
  50. methods.put("put", Put.class);
  51. methods.put("patch", Patch.class);
  52. methods.put("delete", Delete.class);
  53. injector = Guice.createInjector(new AbstractModule() {
  54. protected void configure() {
  55. bind(HttpServletRequest.class).toProvider(mockRequestProviderForContext());
  56. bind(new TypeLiteral<Map<String, Class<? extends Annotation>>>() {
  57. })
  58. .annotatedWith(Bricks.class)
  59. .toInstance(methods);
  60. }
  61. });
  62. pageBook = createNiceMock(PageBook.class);
  63. metrics = createNiceMock(SystemMetrics.class);
  64. }
  65. @Test
  66. public final void annotationKeyExtraction() {
  67. assert "link".equals(Dom.extractKeyAndContent("@Link")[0]) : "Extraction wrong: ";
  68. assert "thing".equals(Dom.extractKeyAndContent("@Thing()")[0]) : "Extraction wrong: ";
  69. assert "thing".equals(Dom.extractKeyAndContent("@Thing(asodkoas)")[0]) : "Extraction wrong: ";
  70. assert "thing".equals(Dom.extractKeyAndContent("@Thing(asodkoas) ")[0]) : "Extraction wrong: ";
  71. assert "thing".equals(Dom.extractKeyAndContent("@Thing(asodkoas) kko")[0]) : "Extraction wrong: ";
  72. assert "".equals(Dom.extractKeyAndContent("@Link")[1]) : "Extraction wrong: ";
  73. final String val = Dom.extractKeyAndContent("@Thing()")[1];
  74. assert null == (val) : "Extraction wrong: " + val;
  75. assert "asodkoas".equals(Dom.extractKeyAndContent("@Thing(asodkoas)")[1]) : "Extraction wrong: ";
  76. assert "asodkoas".equals(Dom.extractKeyAndContent("@Thing(asodkoas) ")[1]) : "Extraction wrong: ";
  77. assert "asodkoas".equals(Dom.extractKeyAndContent("@Thing(asodkoas) kko")[1]) : "Extraction wrong: ";
  78. }
  79. private Template template(String text) {
  80. return new Template("template.fml", text, new MemoryTemplateSource());
  81. }
  82. @Test
  83. public final void readShowIfWidgetTrue() {
  84. Renderable widget =
  85. new FreemarkerTemplateCompiler()
  86. .compile(Object.class, template("<html><#if true><p>hello</p></#if></html>"));
  87. assert null != widget : " null ";
  88. final StringBuilder builder = new StringBuilder();
  89. final Respond mockRespond = RespondersForTesting.newRespond();
  90. widget.render(new Object(), mockRespond);
  91. final String value = mockRespond.toString();
  92. System.out.println(value);
  93. assert "<html><p>hello</p></html>".equals(value) : "Did not write expected output, instead: " + value;
  94. }
  95. @DataProvider(name = ANNOTATION_EXPRESSIONS)
  96. public Object[][] get() {
  97. return new Object[][]{
  98. {"true"},
  99. // {"java.lang.Boolean.TRUE"},
  100. // {"java.lang.Boolean.valueOf('true')"},
  101. // {"true ? true : true"}, @TODO (BD): Disabled until I actually investigate if this is a valid test.
  102. {"'x' == 'x'"},
  103. {"\"x\" == \"x\""},
  104. // {"'hello' instanceof java.io.Serializable"},
  105. // {"true; return true"},
  106. // {" 5 >= 2 "},
  107. };
  108. }
  109. @Test(dataProvider = ANNOTATION_EXPRESSIONS)
  110. public final void readAWidgetWithVariousExpressions(String expression) {
  111. final Evaluator evaluator = new MvelEvaluator();
  112. final WidgetRegistry registry = injector.getInstance(WidgetRegistry.class);
  113. String templateValue = String.format("<html><#if %s><p>hello</p></#if></html>", expression);
  114. System.out.println( templateValue );
  115. Renderable widget =
  116. new FreemarkerTemplateCompiler()
  117. .compile(Object.class, template(templateValue));
  118. assert null != widget : " null ";
  119. final StringBuilder builder = new StringBuilder();
  120. final Respond mockRespond = RespondersForTesting.newRespond();
  121. widget.render(new Object(), mockRespond);
  122. final String value = mockRespond.toString();
  123. System.out.println(value);
  124. assert "<html><p>hello</p></html>".equals(value) : "Did not write expected output, instead: " + value;
  125. }
  126. @Test
  127. public final void readShowIfWidgetFalse() {
  128. final Injector injector = Guice.createInjector(new AbstractModule() {
  129. protected void configure() {
  130. bind(HttpServletRequest.class).toProvider(mockRequestProviderForContext());
  131. }
  132. });
  133. final Evaluator evaluator = new MvelEvaluator();
  134. final WidgetRegistry registry = injector.getInstance(WidgetRegistry.class);
  135. Renderable widget =
  136. new FreemarkerTemplateCompiler()
  137. .compile(Object.class, template("<html><#if false><p>hello</p></#if></html>"));
  138. assert null != widget : " null ";
  139. final StringBuilder builder = new StringBuilder();
  140. final Respond mockRespond = RespondersForTesting.newRespond();
  141. widget.render(new Object(), mockRespond);
  142. final String value = mockRespond.toString();
  143. assert "<html></html>".equals(value) : "Did not write expected output, instead: " + value;
  144. }
  145. @Test
  146. public final void readTextWidgetValues() {
  147. final Injector injector = Guice.createInjector(new AbstractModule() {
  148. protected void configure() {
  149. bind(HttpServletRequest.class).toProvider(mockRequestProviderForContext());
  150. }
  151. });
  152. Renderable widget =
  153. new FreemarkerTemplateCompiler()
  154. .compile(Object.class, template("<html><div class='${clazz}'>hello <a href='/people/${id}'>${name}</a></div></html>"));
  155. assert null != widget : " null ";
  156. final Respond mockRespond = RespondersForTesting.newRespond();
  157. widget.render(new TestBackingType("Dhanji", "content", 12), mockRespond);
  158. final String value = mockRespond.toString();
  159. assert "<html><div class='content'>hello <a href='/people/12'>Dhanji</a></div></html>"
  160. .replace("\"", "'")
  161. .equals(value) : "Did not write expected output, instead: " + value;
  162. }
  163. public static class TestBackingType {
  164. private String name;
  165. private String clazz;
  166. private Integer id;
  167. public TestBackingType(String name, String clazz, Integer id) {
  168. this.name = name;
  169. this.clazz = clazz;
  170. this.id = id;
  171. }
  172. public String getName() {
  173. return name;
  174. }
  175. public String getClazz() {
  176. return clazz;
  177. }
  178. public Integer getId() {
  179. return id;
  180. }
  181. }
  182. // @Test
  183. // public final void readAndRenderRequireWidget() {
  184. // final Injector injector = Guice.createInjector(new AbstractModule() {
  185. // protected void configure() {
  186. // bind(HttpServletRequest.class).toProvider(mockRequestProviderForContext());
  187. // bind(new TypeLiteral<Map<String, Class<? extends Annotation>>>() {
  188. // })
  189. // .annotatedWith(Bricks.class)
  190. // .toInstance(methods);
  191. // }
  192. // });
  193. //
  194. //
  195. // final PageBook pageBook = injector.getInstance(PageBook.class);
  196. //
  197. //
  198. // final WidgetRegistry registry = injector.getInstance(WidgetRegistry.class);
  199. //
  200. //
  201. // Renderable widget =
  202. // new FreemarkerTemplateCompiler(Object.class)
  203. // .compile("<html> <head>" +
  204. // " @Require <script type='text/javascript' src='my.js'> </script>" +
  205. // " @Require <script type='text/javascript' src='my.js'> </script>" +
  206. // "</head><body>" +
  207. // "<div class='${clazz}'>hello <a href='/people/${id}'>${name}</a></div>" +
  208. // "</body></html>");
  209. //
  210. // assert null != widget : " null ";
  211. //
  212. // final Respond respond = RespondersForTesting.newRespond();
  213. //
  214. // widget.render(new TestBackingType("Dhanji", "content", 12), respond);
  215. //
  216. // final String value = respond.toString();
  217. // String expected = "<html> <head>" +
  218. // " <script type='text/javascript' src='my.js'></script>" +
  219. // "</head><body>" +
  220. // "<div class='content'>hello <a href='/people/12'>Dhanji</a></div></body></html>";
  221. // expected = expected.replaceAll("'", "\"");
  222. //
  223. // assertEquals(value, expected);
  224. // }
  225. @Test
  226. public final void readHtmlWidget() {
  227. final WidgetRegistry registry = injector.getInstance(WidgetRegistry.class);
  228. Renderable widget =
  229. new FreemarkerTemplateCompiler()
  230. .compile(Object.class, template("<html><div class='${clazz}'>hello</div></html>"));
  231. assert null != widget : " null ";
  232. final Respond mockRespond = RespondersForTesting.newRespond();
  233. widget.render(new TestBackingType("Dhanji", "content", 12), mockRespond);
  234. final String s = mockRespond.toString();
  235. assert "<html><div class=\"content\">hello</div></html>"
  236. .replace( "\"", "'")
  237. .equals(s) : "Did not write expected output, instead: " + s;
  238. }
  239. @Test
  240. public final void readHtmlWidgetWithChildren() {
  241. final WidgetRegistry registry = injector.getInstance(WidgetRegistry.class);
  242. Renderable widget =
  243. new FreemarkerTemplateCompiler()
  244. .compile(Object.class, template("<!doctype html><html><body><div class='${clazz}'>hello <#if false><a href='/hi/${id}'>hideme</a></#if></div></body></html>"));
  245. assert null != widget : " null ";
  246. final Respond mockRespond = RespondersForTesting.newRespond();
  247. widget.render(new TestBackingType("Dhanji", "content", 12), mockRespond);
  248. final String s = mockRespond.toString();
  249. assertEquals(s, "<!doctype html><html><body><div class=\"content\">hello </div></body></html>".replace("\"", "'"));
  250. }
  251. @EmbedAs(MyEmbeddedPage.MY_FAVE_ANNOTATION)
  252. public static class MyEmbeddedPage {
  253. protected static final String MY_FAVE_ANNOTATION = "MyFave";
  254. private boolean should = true;
  255. public boolean isShould() {
  256. return should;
  257. }
  258. public void setShould(boolean should) {
  259. this.should = should;
  260. }
  261. }
  262. // @Test
  263. // public final void readEmbedWidgetAndStoreAsPage() {
  264. // final Injector injector = Guice.createInjector(new AbstractModule() {
  265. // protected void configure() {
  266. // bind(HttpServletRequest.class).toProvider(mockRequestProviderForContext());
  267. // bind(new TypeLiteral<Map<String, Class<? extends Annotation>>>() {
  268. // })
  269. // .annotatedWith(Bricks.class)
  270. // .toInstance(methods);
  271. // }
  272. // });
  273. // final PageBook book = injector //hacky, where are you super-packages!
  274. // .getInstance(PageBook.class);
  275. //
  276. // book.at("/somewhere", MyEmbeddedPage.class).apply(Chains.terminal());
  277. //
  278. //
  279. // final WidgetRegistry registry = injector.getInstance(WidgetRegistry.class);
  280. // registry.addEmbed("myfave");
  281. //
  282. // Renderable widget =
  283. // new FreemarkerTemplateCompiler(Object.class)
  284. // .compile("<xml><div class='content'>hello @MyFave(should=false)<a href='/hi/${id}'>hideme</a></div></xml>");
  285. //
  286. // assert null != widget : " null ";
  287. //
  288. // //tell pagebook to track this as an embedded widget
  289. // book.embedAs(MyEmbeddedPage.class, MyEmbeddedPage.MY_FAVE_ANNOTATION)
  290. // .apply(Chains.terminal());
  291. //
  292. // final Respond mockRespond = RespondersForTesting.newRespond();
  293. //
  294. // widget.render(new TestBackingType("Dhanji", "content", 12), mockRespond);
  295. //
  296. // final String s = mockRespond.toString();
  297. // assert "<xml><div class=\"content\">hello </div></xml>"
  298. // .equals(s) : "Did not write expected output, instead: " + s;
  299. // }
  300. // @Test
  301. // public final void readEmbedWidgetOnly() {
  302. // final Injector injector = Guice.createInjector(new AbstractModule() {
  303. // protected void configure() {
  304. // bind(HttpServletRequest.class).toProvider(mockRequestProviderForContext());
  305. // bind(new TypeLiteral<Map<String, Class<? extends Annotation>>>() {
  306. // })
  307. // .annotatedWith(Bricks.class)
  308. // .toInstance(methods);
  309. // }
  310. // });
  311. // final PageBook book = injector //hacky, where are you super-packages!
  312. // .getInstance(PageBook.class);
  313. //
  314. //
  315. // final WidgetRegistry registry = injector.getInstance(WidgetRegistry.class);
  316. // registry.addEmbed("myfave");
  317. //
  318. // Renderable widget =
  319. // new FreemarkerTemplateCompiler(Object.class)
  320. // .compile("<html><div class='content'>hello @MyFave(should=false)<a href='/hi/${id}'>hideme</a></div></html>");
  321. //
  322. // assert null != widget : " null ";
  323. //
  324. // //tell pagebook to track this as an embedded widget
  325. // book.embedAs(MyEmbeddedPage.class, MyEmbeddedPage.MY_FAVE_ANNOTATION)
  326. // .apply(Chains.terminal());
  327. //
  328. // final Respond mockRespond = RespondersForTesting.newRespond();
  329. //
  330. // widget.render(new TestBackingType("Dhanji", "content", 12), mockRespond);
  331. //
  332. // final String s = mockRespond.toString();
  333. // assert "<html><div class=\"content\">hello </div></html>"
  334. // .replace( "\"", "'" )
  335. // .equals(s) : "Did not write expected output, instead: " + s;
  336. // }
  337. static Provider<HttpServletRequest> mockRequestProviderForContext() {
  338. return new Provider<HttpServletRequest>() {
  339. public HttpServletRequest get() {
  340. final HttpServletRequest request = createMock(HttpServletRequest.class);
  341. expect(request.getContextPath())
  342. .andReturn("")
  343. .anyTimes();
  344. replay(request);
  345. return request;
  346. }
  347. };
  348. }
  349. }