tapestry-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hls...@apache.org
Subject svn commit: r491996 - in /tapestry/tapestry5/tapestry-core/trunk/src: main/java/org/apache/tapestry/internal/services/ test/java/org/apache/tapestry/internal/services/ test/resources/org/apache/tapestry/internal/services/
Date Wed, 03 Jan 2007 00:56:26 GMT
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: &lt;foo&gt; &amp; &lt;bar&gt;
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: &lt;foo&gt; &amp; &lt;bar&gt;
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"/>



Mime
View raw message