1 package com.opensymphony.module.sitemesh.parser;
2
3 import com.opensymphony.module.sitemesh.HTMLPage;
4 import com.opensymphony.module.sitemesh.PageParser;
5
6 import java.io.ByteArrayInputStream;
7 import java.io.File;
8 import java.io.FileReader;
9 import java.io.FilenameFilter;
10 import java.io.IOException;
11 import java.io.LineNumberReader;
12 import java.io.Reader;
13 import java.io.StringWriter;
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Properties;
19
20 import junit.framework.TestCase;
21 import junit.framework.TestSuite;
22 import junit.framework.Test;
23
24 /**
25 * Test case for HTMLPageParser implementations. See parser-tests/readme.txt.
26 *
27 * @author Joe Walnes
28 */
29 public class HTMLPageParserTest extends TestCase {
30
31 /**
32 * This test case builds a custom suite, containing a collection of smaller suites (one for each file in src/parser-tests).
33 */
34 public static Test suite() throws IOException {
35 TestSuite result = new TestSuite(HTMLPageParserTest.class.getName());
36
37 File[] files = listParserTests(new File("src/parser-tests"));
38 PageParser[] parsers = new PageParser[] { /*new FastPageParser(),*/ new HTMLPageParser() };
39
40 for (int i = 0; i < parsers.length; i++) {
41 PageParser parser = parsers[i];
42 String name = parser.getClass().getName();
43 TestSuite suiteForParser = new TestSuite(name);
44 for (int j = 0; j < files.length; j++) {
45 File file = files[j];
46 TestSuite suiteForFile = new TestSuite(file.getName().replace('.', '_'));
47 suiteForFile.addTest(new HTMLPageParserTest(parser, file, "testTitle"));
48 suiteForFile.addTest(new HTMLPageParserTest(parser, file, "testBody"));
49 suiteForFile.addTest(new HTMLPageParserTest(parser, file, "testHead"));
50 suiteForFile.addTest(new HTMLPageParserTest(parser, file, "testFullPage"));
51 suiteForFile.addTest(new HTMLPageParserTest(parser, file, "testProperties"));
52 suiteForParser.addTest(suiteForFile);
53 }
54 result.addTest(suiteForParser);
55 }
56
57 return result;
58 }
59
60 private HTMLPage page;
61 private Map blocks;
62 private String encoding;
63 private final PageParser parser;
64 private File file;
65
66 public HTMLPageParserTest(PageParser parser, File inputFile, String test) {
67 super(test);
68 this.parser = parser;
69 file = inputFile;
70 encoding = "UTF8";
71 }
72
73 protected void setUp() throws Exception {
74 super.setUp();
75 // read blocks from input file.
76 this.blocks = readBlocks(new FileReader(file));
77 // create PageParser and parse input block into HTMLPage object.
78 String input = (String) blocks.get("INPUT");
79 this.page = (HTMLPage) parser.parse(input.toCharArray());
80 }
81
82 public void testTitle() throws Exception {
83 assertBlock("TITLE", page.getTitle());
84 }
85
86 public void testBody() throws Exception {
87 StringWriter body = new StringWriter();
88 page.writeBody(body);
89 body.flush();
90 assertBlock("BODY", body.toString());
91 }
92
93 public void testHead() throws Exception {
94 StringWriter head = new StringWriter();
95 page.writeHead(head);
96 head.flush();
97 assertBlock("HEAD", head.toString());
98 }
99
100 public void testFullPage() throws Exception {
101 StringWriter fullPage = new StringWriter();
102 page.writePage(fullPage);
103 fullPage.flush();
104 assertBlock("INPUT", fullPage.toString());
105 }
106
107 public void testProperties() throws Exception {
108 Properties props = new Properties();
109 String propsString = (String) blocks.get("PROPERTIES");
110 ByteArrayInputStream input = new ByteArrayInputStream(propsString.trim().getBytes(encoding));
111 props.load(input);
112
113 String[] pageKeys = page.getPropertyKeys();
114 assertEquals(file.getName() + " : Unexpected number of page properties [" + join(pageKeys) + "]",
115 props.size(), pageKeys.length);
116
117 for (int i = 0; i < pageKeys.length; i++) {
118 String pageKey = pageKeys[i];
119 String blockValue = props.getProperty(pageKey);
120 String pageValue = page.getProperty(pageKey);
121 assertEquals(file.getName(),
122 blockValue == null ? null : blockValue.trim(),
123 pageValue == null ? null : pageValue.trim());
124 }
125 }
126
127 private String join(String[] values) {
128 StringBuffer result = new StringBuffer();
129 for (int i = 0; i < values.length; i++) {
130 if (i > 0) {
131 result.append(',');
132 }
133 result.append(values[i]);
134 }
135 return result.toString();
136 }
137
138 //-------------------------------------------------
139
140 private static File[] listParserTests(File dir) throws IOException {
141 // get list of files to ignore
142 LineNumberReader ignoreReader = new LineNumberReader(new FileReader(new File(dir, "ignore.txt")));
143 final List ignoreFileNames = new ArrayList();
144 String line;
145 while ((line = ignoreReader.readLine()) != null) {
146 ignoreFileNames.add(line);
147 }
148 return dir.listFiles(new FilenameFilter() {
149 public boolean accept(File currentDir, String name) {
150 return name.startsWith("test") && !ignoreFileNames.contains(name);
151 }
152 });
153 }
154
155 private void assertBlock(String blockName, String result) throws Exception {
156 String expected = (String) blocks.get(blockName);
157 assertEquals(file.getName() + " : Block did not match", expected.trim(), result.trim());
158 }
159
160 /**
161 * Read input to test and break down into blocks. See parser-tests/readme.txt
162 */
163 private Map readBlocks(Reader input) throws IOException {
164 Map blocks = new HashMap();
165 LineNumberReader reader = new LineNumberReader(input);
166 String line;
167 String blockName = null;
168 StringBuffer blockContents = null;
169 while ((line = reader.readLine()) != null) {
170 if (line.startsWith("~~~ ") && line.endsWith(" ~~~")) {
171 if (blockName != null) {
172 blocks.put(blockName, blockContents.toString());
173 }
174 blockName = line.substring(4, line.length() - 4);
175 blockContents = new StringBuffer();
176 } else {
177 if (blockName != null) {
178 blockContents.append(line);
179 blockContents.append('\n');
180 }
181 }
182 }
183
184 if (blockName != null) {
185 blocks.put(blockName, blockContents.toString());
186 }
187
188 return blocks;
189 }
190
191 }