Author: hlship
Date: Tue Jan 2 16:56:26 2007
New Revision: 491996
URL: http://svn.apache.org/viewvc?view=rev&rev=491996
Log:
Convert template parser to use XMLReader interface, rather than the older
SAXParser interface.
Added:
tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/root_element_is_component.html
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java?view=diff&rev=491996&r1=491995&r2=491996
==============================================================================
---
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java
(original)
+++
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java
Tue Jan 2 16:56:26 2007
@@ -25,9 +25,6 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
import org.apache.commons.logging.Log;
import org.apache.tapestry.internal.parser.AttributeToken;
import org.apache.tapestry.internal.parser.BodyToken;
@@ -50,19 +47,19 @@
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.helpers.XMLReaderFactory;
/**
- * Non-threadsafe implementation.
+ * Non-threadsafe implementation; the IOC service uses the perthread lifecycle.
*/
public class TemplateParserImpl extends DefaultHandler implements
TemplateParser, LexicalHandler
{
public static final String TAPESTRY_SCHEMA_5_0_0 =
"http://tapestry.apache.org/schema/tapestry_5_0_0.xsd";
- private final SAXParserFactory _parserFactory;
-
- private SAXParser _parser;
+ private XMLReader _reader;
// Resource being parsed
private Resource _templateResource;
@@ -105,10 +102,6 @@
{
_log = log;
- _parserFactory = SAXParserFactory.newInstance();
-
- _parserFactory.setNamespaceAware(true);
-
reset();
}
@@ -130,13 +123,19 @@
public ComponentTemplate parseTemplate(Resource templateResource)
{
- if (_parser == null)
+ if (_reader == null)
{
try
{
- _parser = _parserFactory.newSAXParser();
+ _reader = XMLReaderFactory.createXMLReader();
-
_parser.setProperty("http://xml.org/sax/properties/lexical-handler", this);
+ _reader.setContentHandler(this);
+ _reader.setErrorHandler(this);
+ _reader.setEntityResolver(this);
+
+
_reader.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
+
+
_reader.setProperty("http://xml.org/sax/properties/lexical-handler", this);
}
catch (Exception ex)
{
@@ -159,7 +158,7 @@
{
InputSource source = new InputSource(resourceURL.openStream());
- _parser.parse(source, this);
+ _reader.parse(source);
return new ComponentTemplateImpl(_templateResource, _tokens,
_componentIds);
}
@@ -168,7 +167,7 @@
// Some parsers get in an unknown state when an error occurs, and
are are not
// subsequently useable.
- _parser = null;
+ _reader = null;
throw new
TapestryException(ServicesMessages.templateParseError(templateResource, ex),
getCurrentLocation(), ex);
@@ -318,6 +317,8 @@
{
String name = attributes.getLocalName(i);
+ // The name will be blank for an xmlns: attribute
+
if (InternalUtils.isBlank(name))
continue;
@@ -404,6 +405,12 @@
continue;
}
+ // The name will be blank for an xmlns: attribute; we sometimes
see this
+ // in the root element if the root element is a component.
+
+ if (name.equals(""))
+ continue;
+
attributeTokens.add(new AttributeToken(name, value, location));
}
@@ -513,10 +520,4 @@
{
}
-
- @Override
- public void ignorableWhitespace(char[] ch, int start, int length) throws
SAXException
- {
- }
-
}
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java?view=diff&rev=491996&r1=491995&r2=491996
==============================================================================
---
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java
(original)
+++
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java
Tue Jan 2 16:56:26 2007
@@ -12,465 +12,485 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry.internal.services;
-
+package org.apache.tapestry.internal.services;
+
import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newSet;
-import static org.easymock.EasyMock.contains;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.commons.logging.Log;
-import org.apache.tapestry.internal.parser.AttributeToken;
-import org.apache.tapestry.internal.parser.BodyToken;
-import org.apache.tapestry.internal.parser.CDATAToken;
-import org.apache.tapestry.internal.parser.CommentToken;
-import org.apache.tapestry.internal.parser.ComponentTemplate;
-import org.apache.tapestry.internal.parser.EndElementToken;
-import org.apache.tapestry.internal.parser.ExpansionToken;
-import org.apache.tapestry.internal.parser.StartComponentToken;
-import org.apache.tapestry.internal.parser.StartElementToken;
-import org.apache.tapestry.internal.parser.TemplateToken;
-import org.apache.tapestry.internal.parser.TextToken;
+import static org.easymock.EasyMock.contains;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.tapestry.internal.parser.AttributeToken;
+import org.apache.tapestry.internal.parser.BodyToken;
+import org.apache.tapestry.internal.parser.CDATAToken;
+import org.apache.tapestry.internal.parser.CommentToken;
+import org.apache.tapestry.internal.parser.ComponentTemplate;
+import org.apache.tapestry.internal.parser.EndElementToken;
+import org.apache.tapestry.internal.parser.ExpansionToken;
+import org.apache.tapestry.internal.parser.StartComponentToken;
+import org.apache.tapestry.internal.parser.StartElementToken;
+import org.apache.tapestry.internal.parser.TemplateToken;
+import org.apache.tapestry.internal.parser.TextToken;
import org.apache.tapestry.ioc.Locatable;
import org.apache.tapestry.ioc.Location;
import org.apache.tapestry.ioc.Resource;
import org.apache.tapestry.ioc.internal.util.ClasspathResource;
import org.apache.tapestry.ioc.internal.util.TapestryException;
-import org.apache.tapestry.test.TapestryTestCase;
-import org.testng.annotations.Test;
-
-/**
- * This is used to test the template parser ... and in some cases, the
underlying behavior of the
- * SAX APIs.
- * <p>
- * The tests are run sequentially, as they all share a single template parser.
- */
-public class TemplateParserImplTest extends TapestryTestCase
-{
-
- private TemplateParser newParser(Log log)
- {
- return new TemplateParserImpl(log);
- }
-
- private synchronized ComponentTemplate parse(Log log, String file)
- {
- Resource resource = getResource(file);
-
- return newParser(log).parseTemplate(resource);
- }
-
- private List<TemplateToken> tokens(String file)
- {
- Log log = newLog();
-
- replay();
-
- List<TemplateToken> tokens = parse(log, file).getTokens();
-
- verify();
-
- return tokens;
- }
-
- private Resource getResource(String file)
- {
- String packageName = getClass().getPackage().getName();
-
- String path = packageName.replace('.', '/') + "/" + file;
-
- ClassLoader loader = getClass().getClassLoader();
-
- return new ClasspathResource(loader, path);
- }
-
- @SuppressWarnings("unchecked")
- private <T extends TemplateToken> T get(List l, int index)
- {
- Object raw = l.get(index);
-
- return (T) raw;
- }
-
- private void checkLine(Locatable l, int expectedLineNumber)
- {
- assertEquals(l.getLocation().getLine(), expectedLineNumber);
- }
-
- @Test
- synchronized void just_HTML()
- {
- Log log = newLog();
- Resource resource = getResource("justHTML.html");
-
- replay();
-
- ComponentTemplate template = newParser(log).parseTemplate(resource);
-
- assertSame(template.getResource(), resource);
-
- List<TemplateToken> tokens = template.getTokens();
-
- // They add up quick ...
-
- assertEquals(tokens.size(), 20);
-
- StartElementToken t0 = get(tokens, 0);
-
- // Spot check a few things ...
-
- assertEquals(t0.getName(), "html");
- checkLine(t0, 1);
-
- TextToken t1 = get(tokens, 1);
- // Concerned this may not work cross platform.
- assertEquals(t1.getText(), "\n ");
-
- StartElementToken t2 = get(tokens, 2);
- assertEquals(t2.getName(), "head");
- checkLine(t2, 2);
-
- TextToken t5 = get(tokens, 5);
- assertEquals(t5.getText(), "title");
- checkLine(t5, 3);
-
- get(tokens, 6);
-
- StartElementToken t12 = get(tokens, 12);
- assertEquals(t12.getName(), "p");
-
- AttributeToken t13 = get(tokens, 13);
- assertEquals(t13.getName(), "class");
- assertEquals(t13.getValue(), "important");
-
- TextToken t14 = get(tokens, 14);
- // Simplify the text, converting consecutive whitespace to just a
single space.
- assertEquals(t14.getText().replaceAll("\\s+", " ").trim(), "Tapestry
rocks! Line 2");
-
- // Line number is the *start* line of the whole text block.
- checkLine(t14, 6);
-
- verify();
- }
-
- @Test
- void xml_entity()
- {
- List<TemplateToken> tokens = tokens("xmlEntity.html");
-
- assertEquals(tokens.size(), 3);
-
- TextToken t = get(tokens, 1);
-
- // This is OK because the org.apache.tapestry.dom.Text will convert
the characters back into
- // XML entities.
-
- assertEquals(t.getText().trim(), "lt:< gt:> amp:&");
- }
-
- /** Test disabled when not online. */
- @Test (enabled=false)
- void html_entity()
- {
- List<TemplateToken> tokens = tokens("html_entity.html");
-
- assertEquals(tokens.size(), 3);
-
- TextToken t = get(tokens, 1);
-
- // HTML entities are parsed into values that will ultimately
- // be output as numeric entities. This is less than ideal; would like
- // to find a way to keep the entities in their original form (possibly
- // involving a new type of token), but SAX seems to be fighting me on
this.
- // You have to have a DOCTYPE just to parse a template that uses
- // an HTML entity.
-
- assertEquals(t.getText().trim(), "nbsp:[\u00a0]");
- }
-
- @Test
- void cdata()
- {
- List<TemplateToken> tokens = tokens("cdata.html");
-
- // Whitespace text tokens around the CDATA
-
- assertEquals(tokens.size(), 5);
-
- CDATAToken t = get(tokens, 2);
-
- assertEquals(t.getText(), "CDATA: <foo> & <bar> and
<baz>");
- checkLine(t, 2);
- }
-
- @Test
- void comment()
- {
- List<TemplateToken> tokens = tokens("comment.html");
-
- // Again, whitespace before and after the comment adds some tokens
-
- assertEquals(tokens.size(), 5);
-
- CommentToken t = get(tokens, 2);
-
- assertEquals(t.getComment(), " Single line comment ");
- }
-
- @Test
- void multiline_comment()
- {
- List<TemplateToken> tokens = tokens("multilineComment.html");
-
- // Again, whitespace before and after the comment adds some tokens
-
- assertEquals(tokens.size(), 5);
-
- CommentToken t = get(tokens, 2);
-
- String comment = t.getComment().trim().replaceAll("\\s+", " ");
-
- assertEquals(comment, "Line one Line two Line three");
- }
-
- @Test
- void component()
- {
- List<TemplateToken> tokens = tokens("component.html");
-
- assertEquals(tokens.size(), 6);
-
- StartComponentToken t = get(tokens, 2);
- assertEquals(t.getId(), "fred");
- assertEquals(t.getType(), "Fred");
- assertNull(t.getMixins());
- checkLine(t, 2);
-
- get(tokens, 3);
- }
-
- @Test
- void component_with_body()
- {
- List<TemplateToken> tokens = tokens("componentWithBody.html");
-
- assertEquals(tokens.size(), 7);
-
- get(tokens, 2);
-
- TextToken t = get(tokens, 3);
-
- assertEquals(t.getText().trim(), "fred's body");
-
- get(tokens, 4);
- }
-
- @Test
- void body_element()
- {
- List<TemplateToken> tokens = tokens("body_element.html");
-
- // start(html), text, body, text, end(html)
- assertEquals(tokens.size(), 5);
-
- // javac bug is requires use of isInstance() instead of instanceof
- // https://bugs.eclipse.org/bugs/show_bug.cgi?id=113218
- assertTrue(BodyToken.class.isInstance(get(tokens, 2)));
- }
-
- @Test
- void illegal_nesting_within_body_element()
- {
- try
- {
- tokens("illegal_nesting_within_body_element.html");
- unreachable();
- }
- catch (TapestryException ex)
- {
- assertTrue(ex.getMessage().contains(
- "Element 'xyz' is nested within a Tapestry body element"));
- assertEquals(ex.getLocation().getLine(), 2);
- }
- }
-
- @Test
- void content_within_body_element()
- {
- Log log = newLog();
-
- log.error(contains("Content inside a Tapestry body element is not
allowed"));
-
- replay();
-
- List<TemplateToken> tokens = parse(log,
"content_within_body_element.html").getTokens();
-
- assertEquals(tokens.size(), 5);
-
- // javac bug is requires use of isInstance() instead of instanceof
- // https://bugs.eclipse.org/bugs/show_bug.cgi?id=113218
-
- assertTrue(BodyToken.class.isInstance(get(tokens, 2)));
- assertTrue(TextToken.class.isInstance(get(tokens, 3)));
- assertTrue(EndElementToken.class.isInstance(get(tokens, 4)));
-
- verify();
- }
-
- @Test
- void component_with_parameters()
- {
- List<TemplateToken> tokens = tokens("componentWithParameters.html");
-
- assertEquals(tokens.size(), 9);
-
- TemplateToken templateToken = get(tokens, 2);
- Location l = templateToken.getLocation();
-
- AttributeToken t1 = get(tokens, 3);
-
- // TODO: Not sure what order the attributes appear in. Order in the
XML? Sorted
- // alphabetically? Random 'cause they're hashed?
-
- assertEquals(t1.getName(), "cherry");
- assertEquals(t1.getValue(), "bomb");
- assertSame(t1.getLocation(), l);
-
- AttributeToken t2 = get(tokens, 4);
- assertEquals(t2.getName(), "align");
- assertEquals(t2.getValue(), "right");
- assertSame(t2.getLocation(), l);
-
- TextToken t3 = get(tokens, 5);
-
- assertEquals(t3.getText().trim(), "fred's body");
-
- get(tokens, 6);
- }
-
- @Test
- public void component_with_mixins()
- {
- List<TemplateToken> tokens = tokens("component_with_mixins.html");
-
- assertEquals(tokens.size(), 6);
-
- StartComponentToken t = get(tokens, 2);
-
- assertEquals(t.getId(), "fred");
- assertNull(t.getType());
- assertEquals(t.getMixins(), "Barney");
- }
-
- @Test
- public void empty_string_mixins_is_null()
- {
- List<TemplateToken> tokens =
tokens("empty_string_mixins_is_null.html");
-
- assertEquals(tokens.size(), 6);
-
- StartComponentToken t = get(tokens, 2);
-
- assertEquals(t.getId(), "fred");
- // We also check that empty string type is null ..
- assertNull(t.getType());
- assertNull(t.getMixins());
- }
-
- @Test
- public void component_without_id_or_type()
- {
- try
- {
- tokens("component_without_id_or_type.html");
- unreachable();
- }
- catch (TapestryException ex)
- {
- assertEquals(ex.getCause().getMessage(),
ServicesMessages.compRequiresIdOrType());
- assertEquals(ex.getLocation().getLine(), 2);
- }
- }
-
- @Test
- public void component_ids()
- {
- Log log = newLog();
-
- replay();
-
- ComponentTemplate template = parse(log, "component_ids.html");
-
- Set<String> ids = template.getComponentIds();
-
- assertEquals(ids, newSet(Arrays.asList("bomb", "border", "zebra")));
-
- verify();
- }
-
- @Test
- public void expansions_in_normal_text()
- {
- List<TemplateToken> tokens = tokens("expansions_in_normal_text.html");
-
- assertEquals(tokens.size(), 7);
-
- TextToken t1 = get(tokens, 1);
-
- assertEquals(t1.getText().trim(), "Expansion #1[");
-
- ExpansionToken t2 = get(tokens, 2);
- assertEquals(t2.getExpression(), "expansion1");
-
- TextToken t3 = get(tokens, 3);
- assertEquals(t3.getText().replaceAll("\\s+", " "), "] Expansion #2[");
-
- ExpansionToken t4 = get(tokens, 4);
- assertEquals(t4.getExpression(), "expansion2");
-
- TextToken t5 = get(tokens, 5);
- assertEquals(t5.getText().trim(), "]");
- }
-
- @Test
- public void expansions_must_be_on_one_line()
- {
- List<TemplateToken> tokens =
tokens("expansions_must_be_on_one_line.html");
-
- assertEquals(tokens.size(), 3);
-
- TextToken t1 = get(tokens, 1);
-
- assertEquals(
- t1.getText().replaceAll("\\s+", " "),
- " ${expansions must be on a single line} ");
-
- }
-
- @Test
- public void expansions_not_allowed_in_cdata()
- {
- List<TemplateToken> tokens =
tokens("expansions_not_allowed_in_cdata.html");
-
- assertEquals(tokens.size(), 5);
-
- CDATAToken t2 = get(tokens, 2);
-
- assertEquals(t2.getText(), "${not-an-expansion}");
- }
-
- @Test
- public void expansions_not_allowed_in_attributes()
- {
- List<TemplateToken> tokens =
tokens("expansions_not_allowed_in_attributes.html");
-
- assertEquals(tokens.size(), 4);
-
- AttributeToken t1 = get(tokens, 1);
-
- assertEquals(t1.getName(), "exp");
- assertEquals(t1.getValue(), "${not-an-expansion}");
- }
-}
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+/**
+ * This is used to test the template parser ... and in some cases, the
underlying behavior of the
+ * SAX APIs.
+ * <p>
+ * The tests are run sequentially, as they all share a single template parser.
+ */
+public class TemplateParserImplTest extends TapestryTestCase
+{
+
+ private TemplateParser newParser(Log log)
+ {
+ return new TemplateParserImpl(log);
+ }
+
+ private synchronized ComponentTemplate parse(Log log, String file)
+ {
+ Resource resource = getResource(file);
+
+ return newParser(log).parseTemplate(resource);
+ }
+
+ private List<TemplateToken> tokens(String file)
+ {
+ Log log = newLog();
+
+ replay();
+
+ List<TemplateToken> tokens = parse(log, file).getTokens();
+
+ verify();
+
+ return tokens;
+ }
+
+ private Resource getResource(String file)
+ {
+ String packageName = getClass().getPackage().getName();
+
+ String path = packageName.replace('.', '/') + "/" + file;
+
+ ClassLoader loader = getClass().getClassLoader();
+
+ return new ClasspathResource(loader, path);
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T extends TemplateToken> T get(List l, int index)
+ {
+ Object raw = l.get(index);
+
+ return (T) raw;
+ }
+
+ private void checkLine(Locatable l, int expectedLineNumber)
+ {
+ assertEquals(l.getLocation().getLine(), expectedLineNumber);
+ }
+
+ @Test
+ synchronized void just_HTML()
+ {
+ Log log = newLog();
+ Resource resource = getResource("justHTML.html");
+
+ replay();
+
+ ComponentTemplate template = newParser(log).parseTemplate(resource);
+
+ assertSame(template.getResource(), resource);
+
+ List<TemplateToken> tokens = template.getTokens();
+
+ // They add up quick ...
+
+ assertEquals(tokens.size(), 20);
+
+ StartElementToken t0 = get(tokens, 0);
+
+ // Spot check a few things ...
+
+ assertEquals(t0.getName(), "html");
+ checkLine(t0, 1);
+
+ TextToken t1 = get(tokens, 1);
+ // Concerned this may not work cross platform.
+ assertEquals(t1.getText(), "\n ");
+
+ StartElementToken t2 = get(tokens, 2);
+ assertEquals(t2.getName(), "head");
+ checkLine(t2, 2);
+
+ TextToken t5 = get(tokens, 5);
+ assertEquals(t5.getText(), "title");
+ checkLine(t5, 3);
+
+ get(tokens, 6);
+
+ StartElementToken t12 = get(tokens, 12);
+ assertEquals(t12.getName(), "p");
+
+ AttributeToken t13 = get(tokens, 13);
+ assertEquals(t13.getName(), "class");
+ assertEquals(t13.getValue(), "important");
+
+ TextToken t14 = get(tokens, 14);
+ // Simplify the text, converting consecutive whitespace to just a
single space.
+ assertEquals(t14.getText().replaceAll("\\s+", " ").trim(), "Tapestry
rocks! Line 2");
+
+ // Line number is the *start* line of the whole text block.
+ checkLine(t14, 6);
+
+ verify();
+ }
+
+ @Test
+ void xml_entity()
+ {
+ List<TemplateToken> tokens = tokens("xmlEntity.html");
+
+ assertEquals(tokens.size(), 3);
+
+ TextToken t = get(tokens, 1);
+
+ // This is OK because the org.apache.tapestry.dom.Text will convert
the characters back into
+ // XML entities.
+
+ assertEquals(t.getText().trim(), "lt:< gt:> amp:&");
+ }
+
+ /** Test disabled when not online. */
+ @Test(enabled = false)
+ void html_entity()
+ {
+ List<TemplateToken> tokens = tokens("html_entity.html");
+
+ assertEquals(tokens.size(), 3);
+
+ TextToken t = get(tokens, 1);
+
+ // HTML entities are parsed into values that will ultimately
+ // be output as numeric entities. This is less than ideal; would like
+ // to find a way to keep the entities in their original form (possibly
+ // involving a new type of token), but SAX seems to be fighting me on
this.
+ // You have to have a DOCTYPE just to parse a template that uses
+ // an HTML entity.
+
+ assertEquals(t.getText().trim(), "nbsp:[\u00a0]");
+ }
+
+ @Test
+ void cdata()
+ {
+ List<TemplateToken> tokens = tokens("cdata.html");
+
+ // Whitespace text tokens around the CDATA
+
+ assertEquals(tokens.size(), 5);
+
+ CDATAToken t = get(tokens, 2);
+
+ assertEquals(t.getText(), "CDATA: <foo> & <bar> and
<baz>");
+ checkLine(t, 2);
+ }
+
+ @Test
+ void comment()
+ {
+ List<TemplateToken> tokens = tokens("comment.html");
+
+ // Again, whitespace before and after the comment adds some tokens
+
+ assertEquals(tokens.size(), 5);
+
+ CommentToken t = get(tokens, 2);
+
+ assertEquals(t.getComment(), " Single line comment ");
+ }
+
+ @Test
+ void multiline_comment()
+ {
+ List<TemplateToken> tokens = tokens("multilineComment.html");
+
+ // Again, whitespace before and after the comment adds some tokens
+
+ assertEquals(tokens.size(), 5);
+
+ CommentToken t = get(tokens, 2);
+
+ String comment = t.getComment().trim().replaceAll("\\s+", " ");
+
+ assertEquals(comment, "Line one Line two Line three");
+ }
+
+ @Test
+ void component()
+ {
+ List<TemplateToken> tokens = tokens("component.html");
+
+ assertEquals(tokens.size(), 6);
+
+ StartComponentToken t = get(tokens, 2);
+ assertEquals(t.getId(), "fred");
+ assertEquals(t.getType(), "Fred");
+ assertNull(t.getMixins());
+ checkLine(t, 2);
+
+ get(tokens, 3);
+ }
+
+ @Test
+ void component_with_body()
+ {
+ List<TemplateToken> tokens = tokens("componentWithBody.html");
+
+ assertEquals(tokens.size(), 7);
+
+ get(tokens, 2);
+
+ TextToken t = get(tokens, 3);
+
+ assertEquals(t.getText().trim(), "fred's body");
+
+ get(tokens, 4);
+ }
+
+ @Test
+ public void root_element_is_component()
+ {
+ List<TemplateToken> tokens = tokens("root_element_is_component.html");
+
+ assertEquals(tokens.size(), 3);
+
+ StartComponentToken start = get(tokens, 0);
+
+ assertEquals(start.getId(), "fred");
+ assertEquals(start.getType(), "Fred");
+
+ AttributeToken attr = get(tokens, 1);
+
+ assertEquals(attr.getName(), "param");
+ assertEquals(attr.getValue(), "value");
+
+ assertTrue(EndElementToken.class.isInstance(tokens.get(2)));
+ }
+
+ @Test
+ void body_element()
+ {
+ List<TemplateToken> tokens = tokens("body_element.html");
+
+ // start(html), text, body, text, end(html)
+ assertEquals(tokens.size(), 5);
+
+ // javac bug is requires use of isInstance() instead of instanceof
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=113218
+ assertTrue(BodyToken.class.isInstance(get(tokens, 2)));
+ }
+
+ @Test
+ void illegal_nesting_within_body_element()
+ {
+ try
+ {
+ tokens("illegal_nesting_within_body_element.html");
+ unreachable();
+ }
+ catch (TapestryException ex)
+ {
+ assertTrue(ex.getMessage().contains(
+ "Element 'xyz' is nested within a Tapestry body element"));
+ assertEquals(ex.getLocation().getLine(), 2);
+ }
+ }
+
+ @Test
+ void content_within_body_element()
+ {
+ Log log = newLog();
+
+ log.error(contains("Content inside a Tapestry body element is not
allowed"));
+
+ replay();
+
+ List<TemplateToken> tokens = parse(log,
"content_within_body_element.html").getTokens();
+
+ assertEquals(tokens.size(), 5);
+
+ // javac bug is requires use of isInstance() instead of instanceof
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=113218
+
+ assertTrue(BodyToken.class.isInstance(get(tokens, 2)));
+ assertTrue(TextToken.class.isInstance(get(tokens, 3)));
+ assertTrue(EndElementToken.class.isInstance(get(tokens, 4)));
+
+ verify();
+ }
+
+ @Test
+ void component_with_parameters()
+ {
+ List<TemplateToken> tokens = tokens("componentWithParameters.html");
+
+ assertEquals(tokens.size(), 9);
+
+ TemplateToken templateToken = get(tokens, 2);
+ Location l = templateToken.getLocation();
+
+ AttributeToken t1 = get(tokens, 3);
+
+ // TODO: Not sure what order the attributes appear in. Order in the
XML? Sorted
+ // alphabetically? Random 'cause they're hashed?
+
+ assertEquals(t1.getName(), "cherry");
+ assertEquals(t1.getValue(), "bomb");
+ assertSame(t1.getLocation(), l);
+
+ AttributeToken t2 = get(tokens, 4);
+ assertEquals(t2.getName(), "align");
+ assertEquals(t2.getValue(), "right");
+ assertSame(t2.getLocation(), l);
+
+ TextToken t3 = get(tokens, 5);
+
+ assertEquals(t3.getText().trim(), "fred's body");
+
+ get(tokens, 6);
+ }
+
+ @Test
+ public void component_with_mixins()
+ {
+ List<TemplateToken> tokens = tokens("component_with_mixins.html");
+
+ assertEquals(tokens.size(), 6);
+
+ StartComponentToken t = get(tokens, 2);
+
+ assertEquals(t.getId(), "fred");
+ assertNull(t.getType());
+ assertEquals(t.getMixins(), "Barney");
+ }
+
+ @Test
+ public void empty_string_mixins_is_null()
+ {
+ List<TemplateToken> tokens =
tokens("empty_string_mixins_is_null.html");
+
+ assertEquals(tokens.size(), 6);
+
+ StartComponentToken t = get(tokens, 2);
+
+ assertEquals(t.getId(), "fred");
+ // We also check that empty string type is null ..
+ assertNull(t.getType());
+ assertNull(t.getMixins());
+ }
+
+ @Test
+ public void component_without_id_or_type()
+ {
+ try
+ {
+ tokens("component_without_id_or_type.html");
+ unreachable();
+ }
+ catch (TapestryException ex)
+ {
+ assertEquals(ex.getCause().getMessage(),
ServicesMessages.compRequiresIdOrType());
+ assertEquals(ex.getLocation().getLine(), 2);
+ }
+ }
+
+ @Test
+ public void component_ids()
+ {
+ Log log = newLog();
+
+ replay();
+
+ ComponentTemplate template = parse(log, "component_ids.html");
+
+ Set<String> ids = template.getComponentIds();
+
+ assertEquals(ids, newSet(Arrays.asList("bomb", "border", "zebra")));
+
+ verify();
+ }
+
+ @Test
+ public void expansions_in_normal_text()
+ {
+ List<TemplateToken> tokens = tokens("expansions_in_normal_text.html");
+
+ assertEquals(tokens.size(), 7);
+
+ TextToken t1 = get(tokens, 1);
+
+ assertEquals(t1.getText().trim(), "Expansion #1[");
+
+ ExpansionToken t2 = get(tokens, 2);
+ assertEquals(t2.getExpression(), "expansion1");
+
+ TextToken t3 = get(tokens, 3);
+ assertEquals(t3.getText().replaceAll("\\s+", " "), "] Expansion #2[");
+
+ ExpansionToken t4 = get(tokens, 4);
+ assertEquals(t4.getExpression(), "expansion2");
+
+ TextToken t5 = get(tokens, 5);
+ assertEquals(t5.getText().trim(), "]");
+ }
+
+ @Test
+ public void expansions_must_be_on_one_line()
+ {
+ List<TemplateToken> tokens =
tokens("expansions_must_be_on_one_line.html");
+
+ assertEquals(tokens.size(), 3);
+
+ TextToken t1 = get(tokens, 1);
+
+ assertEquals(
+ t1.getText().replaceAll("\\s+", " "),
+ " ${expansions must be on a single line} ");
+
+ }
+
+ @Test
+ public void expansions_not_allowed_in_cdata()
+ {
+ List<TemplateToken> tokens =
tokens("expansions_not_allowed_in_cdata.html");
+
+ assertEquals(tokens.size(), 5);
+
+ CDATAToken t2 = get(tokens, 2);
+
+ assertEquals(t2.getText(), "${not-an-expansion}");
+ }
+
+ @Test
+ public void expansions_not_allowed_in_attributes()
+ {
+ List<TemplateToken> tokens =
tokens("expansions_not_allowed_in_attributes.html");
+
+ assertEquals(tokens.size(), 4);
+
+ AttributeToken t1 = get(tokens, 1);
+
+ assertEquals(t1.getName(), "exp");
+ assertEquals(t1.getValue(), "${not-an-expansion}");
+ }
+}
Added:
tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/root_element_is_component.html
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/root_element_is_component.html?view=auto&rev=491996
==============================================================================
---
tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/root_element_is_component.html
(added)
+++
tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/root_element_is_component.html
Tue Jan 2 16:56:26 2007
@@ -0,0 +1 @@
+<t:comp id="fred" type="Fred" param="value"
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"/>