PageRenderTime 26ms CodeModel.GetById 1ms app.highlight 21ms RepoModel.GetById 1ms app.codeStats 0ms

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

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