1 52 53 package freemarker.testcase; 54 55 import freemarker.template.*; 56 import freemarker.ext.beans.*; 57 import freemarker.ext.dom.NodeModel; 58 import freemarker.ext.jdom.NodeListModel; 59 import freemarker.testcase.models.*; 60 import freemarker.template.utility.*; 61 import freemarker.template.utility.NormalizeNewlines; 62 import freemarker.testcase.models.TransformHashWrapper; 63 import junit.framework.*; 64 import java.util.*; 65 import java.io.*; 66 import java.net.URL ; 67 import javax.xml.parsers.DocumentBuilder ; 68 import javax.xml.parsers.DocumentBuilderFactory ; 69 import org.jdom.input.SAXBuilder; 70 import org.xml.sax.InputSource ; 71 72 73 public class TemplateTestCase extends TestCase { 74 75 Template template; 76 HashMap dataModel = new HashMap(); 77 78 String filename, testName; 79 String inputDir = "template"; 80 String referenceDir = "reference"; 81 File outputDir; 82 83 Configuration conf = new Configuration(); 84 85 public TemplateTestCase(String name, String filename) { 86 super(name); 87 this.filename = filename; 88 this.testName = name; 89 } 90 91 public void setTemplateDirectory(String dirname) throws IOException { 92 URL url = getClass().getResource("TemplateTestCase.class"); 93 File parent = new File(url.getFile()).getParentFile(); 94 File dir = new File(parent, dirname); 95 conf.setDirectoryForTemplateLoading(dir); 96 System.out.println("Setting loading directory as: " + dir); 97 } 98 99 public void setOutputDirectory(String dirname) { 100 URL url = getClass().getResource("TemplateTestCase.class"); 101 File parent = new File(url.getFile()).getParentFile(); 102 this.outputDir = new File(parent, dirname); 103 System.out.println("Setting reference directory as: " + outputDir); 104 } 105 106 public void setConfigParam(String param, String value) throws IOException { 107 if ("templatedir".equals(param)) { 108 setTemplateDirectory(value); 109 } 110 else if ("auto_import".equals(param)) { 111 StringTokenizer st = new StringTokenizer(value); 112 if (!st.hasMoreTokens()) fail("Expecting libname"); 113 String libname = st.nextToken(); 114 if (!st.hasMoreTokens()) fail("Expecting 'as <alias>' in autoimport"); 115 String as = st.nextToken(); 116 if (!as.equals("as")) fail("Expecting 'as <alias>' in autoimport"); 117 if (!st.hasMoreTokens()) fail("Expecting alias after 'as' in autoimport"); 118 String alias = st.nextToken(); 119 conf.addAutoImport(alias, libname); 120 } 121 else if ("clear_encoding_map".equals(param)) { 122 if (StringUtil.getYesNo(value)) { 123 conf.clearEncodingMap(); 124 } 125 } 126 else if ("input_encoding".equals(param)) { 127 conf.setDefaultEncoding(value); 128 } 129 else if ("outputdir".equals(param)) { 130 setOutputDirectory(value); 131 } 132 else if ("output_encoding".equals(param)) { 133 conf.setOutputEncoding(value); 134 } 135 else if ("locale".equals(param)) { 136 String lang = "", country="", variant=""; 137 StringTokenizer st = new StringTokenizer(value,"_", false); 138 if (st.hasMoreTokens()) { 139 lang = st.nextToken(); 140 } 141 if (st.hasMoreTokens()) { 142 country = st.nextToken(); 143 } 144 if (st.hasMoreTokens()){ 145 variant = st.nextToken(); 146 } 147 if (lang != "") { 148 Locale loc = new Locale(lang, country, variant); 149 conf.setLocale(loc); 150 } 151 } 152 else if ("object_wrapper".equals(param)) { 153 try { 154 Class cl = Class.forName(value); 155 ObjectWrapper ow = (ObjectWrapper) cl.newInstance(); 156 conf.setObjectWrapper(ow); 157 } catch (Exception e) { 158 fail("Error setting object wrapper to " + value + "\n" + e.getMessage()); 159 } 160 } 161 else if ("input_encoding".equals(param)) { 162 conf.setDefaultEncoding(value); 163 } 164 else if ("output_encoding".equals(param)) { 165 conf.setOutputEncoding(value); 166 } 167 else if ("strict_syntax".equals(param)) { 168 boolean b = StringUtil.getYesNo(value); 169 conf.setStrictSyntaxMode(b); 170 } 171 else if ("url_escaping_charset".equals(param)) { 172 conf.setURLEscapingCharset(value); 173 } 174 } 175 176 182 183 public void setUp() throws Exception { 184 dataModel.put("message", "Hello, world!"); 185 186 if (testName.equals("bean-maps")) { 187 BeansWrapper w1 = new BeansWrapper(); 188 BeansWrapper w2 = new BeansWrapper(); 189 BeansWrapper w3 = new BeansWrapper(); 190 BeansWrapper w4 = new BeansWrapper(); 191 BeansWrapper w5 = new BeansWrapper(); 192 BeansWrapper w6 = new BeansWrapper(); 193 BeansWrapper w7 = new BeansWrapper(); 194 195 w1.setExposureLevel(BeansWrapper.EXPOSE_PROPERTIES_ONLY); 196 w2.setExposureLevel(BeansWrapper.EXPOSE_PROPERTIES_ONLY); 197 w3.setExposureLevel(BeansWrapper.EXPOSE_NOTHING); 198 w4.setExposureLevel(BeansWrapper.EXPOSE_NOTHING); 199 w5.setExposureLevel(BeansWrapper.EXPOSE_ALL); 200 w6.setExposureLevel(BeansWrapper.EXPOSE_ALL); 201 202 w1.setMethodsShadowItems(true); 203 w2.setMethodsShadowItems(false); 204 w3.setMethodsShadowItems(true); 205 w4.setMethodsShadowItems(false); 206 w5.setMethodsShadowItems(true); 207 w6.setMethodsShadowItems(false); 208 209 w7.setSimpleMapWrapper(true); 210 211 Object test = getTestBean(); 212 213 dataModel.put("m1", w1.wrap(test)); 214 dataModel.put("m2", w2.wrap(test)); 215 dataModel.put("m3", w3.wrap(test)); 216 dataModel.put("m4", w4.wrap(test)); 217 dataModel.put("m5", w5.wrap(test)); 218 dataModel.put("m6", w6.wrap(test)); 219 dataModel.put("m7", w7.wrap(test)); 220 221 dataModel.put("s1", w1.wrap("hello")); 222 dataModel.put("s2", w1.wrap("world")); 223 dataModel.put("s3", w5.wrap("hello")); 224 dataModel.put("s4", w5.wrap("world")); 225 } 226 227 else if (testName.equals("beans")) { 228 dataModel.put("array", new String [] { "array-0", "array-1"}); 229 dataModel.put("list", Arrays.asList(new String [] { "list-0", "list-1", "list-2"})); 230 Map tmap = new HashMap(); 231 tmap.put("key", "value"); 232 Object objKey = new Object (); 233 tmap.put(objKey, "objValue"); 234 dataModel.put("map", tmap); 235 dataModel.put("objKey", objKey); 236 dataModel.put("obj", new freemarker.testcase.models.BeanTestClass()); 237 dataModel.put("resourceBundle", new ResourceBundleModel(ResourceBundle.getBundle("freemarker.testcase.models.BeansTestResources"), BeansWrapper.getDefaultInstance())); 238 dataModel.put("date", new GregorianCalendar(1974, 10, 14).getTime()); 239 dataModel.put("statics", BeansWrapper.getDefaultInstance().getStaticModels()); 240 } 241 242 else if (testName.equals("boolean")) { 243 dataModel.put( "boolean1", TemplateBooleanModel.FALSE); 244 dataModel.put( "boolean2", TemplateBooleanModel.TRUE); 245 dataModel.put( "boolean3", TemplateBooleanModel.TRUE); 246 dataModel.put( "boolean4", TemplateBooleanModel.TRUE); 247 dataModel.put( "boolean5", TemplateBooleanModel.FALSE); 248 249 dataModel.put( "list1", new BooleanList1() ); 250 dataModel.put( "list2", new BooleanList2() ); 251 252 dataModel.put( "hash1", new BooleanHash1() ); 253 dataModel.put( "hash2", new BooleanHash2() ); 254 } 255 256 else if (testName.equals("dateformat")) { 257 GregorianCalendar cal = new GregorianCalendar(2002, 10, 15, 14, 54, 13); 258 cal.setTimeZone(TimeZone.getTimeZone("GMT")); 259 dataModel.put("date", new SimpleDate(cal.getTime(), TemplateDateModel.DATETIME)); 260 dataModel.put("unknownDate", new SimpleDate(cal.getTime(), TemplateDateModel.UNKNOWN)); 261 } 262 else if (testName.equals("default-xmlns")) { 263 InputSource is = new InputSource (getClass().getResourceAsStream("test-defaultxmlns1.xml")); 264 NodeModel nm = NodeModel.parse(is); 265 dataModel.put("doc", nm); 266 } 267 268 else if (testName.equals("multimodels")) { 269 dataModel.put("test", "selftest"); 270 dataModel.put("self", "self"); 271 dataModel.put("zero", new Integer (0)); 272 dataModel.put("data", new MultiModel1()); 273 } 274 275 else if (testName.equals("nodelistmodel")) { 276 org.jdom.Document doc = new SAXBuilder().build(new InputSource (getClass().getResourceAsStream("test-xml.xml"))); 277 dataModel.put("doc", new NodeListModel(doc)); 278 } 279 280 else if (testName.equals("string-builtins3")) { 281 dataModel.put("multi", new TestBoolean()); 282 } 283 284 else if (testName.equals("type-builtins")) { 285 dataModel.put("testmethod", new TestMethod()); 286 dataModel.put("testnode", new TestNode()); 287 dataModel.put("testcollection", new SimpleCollection(new ArrayList())); 288 } 289 290 else if (testName.equals("var-layers")) { 291 dataModel.put("x", new Integer (4)); 292 dataModel.put("z", new Integer (4)); 293 conf.setSharedVariable("y", new Integer (7)); 294 } 295 296 else if (testName.equals("xml-fragment")) { 297 DocumentBuilderFactory f = DocumentBuilderFactory.newInstance(); 298 f.setNamespaceAware(true); 299 DocumentBuilder db = f.newDocumentBuilder(); 300 org.w3c.dom.Document doc = db.parse(new InputSource (getClass().getResourceAsStream("test-xmlfragment.xml"))); 301 dataModel.put("node", NodeModel.wrap(doc.getDocumentElement().getFirstChild().getFirstChild())); 302 } 303 304 else if (testName.equals("xmlns1")) { 305 InputSource is = new InputSource (getClass().getResourceAsStream("test-xmlns.xml")); 306 NodeModel nm = NodeModel.parse(is); 307 dataModel.put("doc", nm); 308 } 309 310 else if (testName.equals("xmlns2")) { 311 InputSource is = new InputSource (getClass().getResourceAsStream("test-xmlns2.xml")); 312 NodeModel nm = NodeModel.parse(is); 313 dataModel.put("doc", nm); 314 } 315 316 else if (testName.equals("xmlns3") || testName.equals("xmlns4")) { 317 InputSource is = new InputSource (getClass().getResourceAsStream("test-xmlns3.xml")); 318 NodeModel nm = NodeModel.parse(is); 319 dataModel.put("doc", nm); 320 } 321 322 else if (testName.equals("xmlns5")) { 323 InputSource is = new InputSource (getClass().getResourceAsStream("test-defaultxmlns1.xml")); 324 NodeModel nm = NodeModel.parse(is); 325 dataModel.put("doc", nm); 326 } 327 } 328 329 public void runTest() { 330 try { 331 template = conf.getTemplate(filename); 332 } catch (Exception e) { 333 StringWriter sw = new StringWriter(); 334 PrintWriter pw = new PrintWriter(sw); 335 e.printStackTrace(pw); 336 fail("Could not load template " + filename + "\n" + sw.toString()); 337 } 338 File refFile = new File (outputDir, filename); 339 File outFile = new File (outputDir, filename+".out"); 340 Writer out = null; 341 String encoding = conf.getOutputEncoding(); 342 if (encoding == null) encoding = "UTF-8"; 343 try { 344 out = new OutputStreamWriter(new FileOutputStream(outFile), 345 encoding); 346 } catch (IOException ioe) { 347 fail("Cannot write to file: " + outFile + "\n" + ioe.getMessage()); 348 } 349 try { 350 template.process(dataModel, out); 351 out.close(); 352 } catch (Exception e) { 353 StringWriter sw = new StringWriter(); 354 PrintWriter pw = new PrintWriter(sw); 355 e.printStackTrace(pw); 356 fail("Could not process template " + filename + "\n" + sw.toString()); 357 } 358 try { 359 Reader ref = new InputStreamReader(new FileInputStream(refFile), 360 encoding); 361 Reader output = new InputStreamReader(new FileInputStream(outFile), 362 encoding); 363 compare(ref, output); 364 } catch (IOException e) { 365 StringWriter sw = new StringWriter(); 366 PrintWriter pw = new PrintWriter(sw); 367 e.printStackTrace(pw); 368 fail("Error comparing files " + refFile + " and " + outFile + "\n" + sw.toString()); 369 } 370 outFile.delete(); 371 } 372 373 static public void compare(Reader reference, Reader output) throws IOException { 374 LineNumberReader ref = new LineNumberReader(reference); 375 LineNumberReader out = new LineNumberReader(output); 376 String refLine = "", outLine = ""; 377 while (refLine != null || outLine != null) { 378 if (refLine == null) { 379 fail("Output text is longer than reference text"); 380 } 381 if (outLine == null) { 382 fail("Output text is shorter than reference text"); 383 } 384 refLine = ref.readLine(); 385 outLine = out.readLine(); 386 if (refLine != null && outLine != null & !refLine.equals(outLine)) { 387 fail("Difference found on line " + ref.getLineNumber() + 388 ".\nReference text is: " + refLine + 389 "\nOutput text is: " + outLine); 390 } 391 } 392 } 393 394 static class TestBoolean implements TemplateBooleanModel, TemplateScalarModel { 395 public boolean getAsBoolean() { 396 return true; 397 } 398 399 public String getAsString() { 400 return "de"; 401 } 402 } 403 404 static class TestMethod implements TemplateMethodModel { 405 public Object exec(java.util.List arguments) { 406 return "x"; 407 } 408 } 409 410 static class TestNode implements TemplateNodeModel { 411 412 public String getNodeName() { 413 return "name"; 414 } 415 416 public TemplateNodeModel getParentNode() { 417 return null; 418 } 419 420 public String getNodeType() { 421 return "element"; 422 } 423 424 public TemplateSequenceModel getChildNodes() { 425 return null; 426 } 427 428 public String getNodeNamespace() { 429 return null; 430 } 431 } 432 433 public Object getTestBean() 434 { 435 Map testBean = new TestBean(); 436 testBean.put("name", "Chris"); 437 testBean.put("location", "San Francisco"); 438 testBean.put("age", new Integer (27)); 439 return testBean; 440 } 441 442 public static class TestBean extends HashMap { 443 public String getName() { 444 return "Christopher"; 445 } 446 public int getLuckyNumber() { 447 return 7; 448 } 449 } 450 } 451 | Popular Tags |