blob: e959c9533a3446a9c6c98e4f3ba926b9082fe8fa [file] [log] [blame]
// Copyright 2004 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.junit.parse;
import java.util.Map;
import org.apache.tapestry.ILocatable;
import org.apache.tapestry.bean.MessageBeanInitializer;
import org.apache.tapestry.junit.TapestryTestCase;
import org.apache.tapestry.spec.BindingType;
import org.apache.tapestry.spec.IApplicationSpecification;
import org.apache.tapestry.spec.IBeanSpecification;
import org.apache.tapestry.spec.IBindingSpecification;
import org.apache.tapestry.spec.IComponentSpecification;
import org.apache.tapestry.spec.IContainedComponent;
import org.apache.tapestry.spec.ILibrarySpecification;
import org.apache.tapestry.spec.IListenerBindingSpecification;
import org.apache.tapestry.spec.IParameterSpecification;
import org.apache.tapestry.spec.IPropertySpecification;
import org.apache.tapestry.spec.ListenerBindingSpecification;
import org.apache.tapestry.util.xml.DocumentParseException;
/**
* Tests the specification parser (which reads page and component
* specifications). Came into being somewhat late, so it just
* tests new features for the meantime.
*
* @author Howard Lewis Ship
* @version $Id$
* @since 2.0.4
*
**/
public class TestSpecificationParser extends TapestryTestCase
{
private void checkLine(ILocatable locatable, int line)
{
assertEquals("Line", line, locatable.getLocation().getLineNumber());
}
/**
* Tests that the parser can handle a specification
* that includes a <string-binding> element.
*
**/
public void testStringBinding() throws Exception
{
IComponentSpecification spec = parseComponent("TestStringBinding.jwc");
IBindingSpecification bs = spec.getComponent("hello").getBinding("value");
assertEquals("type", BindingType.STRING, bs.getType());
assertEquals("key", "label.hello", bs.getValue());
checkLine(bs, 25);
}
/**
* Test new (in 3.0) <message-binding> element.
*/
public void tesMessageBinding() throws Exception
{
IComponentSpecification spec = parseComponent("TestMessageBinding.jwc");
IBindingSpecification bs = spec.getComponent("hello").getBinding("value");
assertEquals("type", BindingType.STRING, bs.getType());
assertEquals("key", "label.hello", bs.getValue());
checkLine(bs, 25);
}
/**
* Test valid parameter name.
*
* @since 2.2
*
**/
public void testValidParameterName() throws Exception
{
IComponentSpecification spec = parseComponent("ValidParameterName.jwc");
IParameterSpecification ps = spec.getParameter("valid");
assertNotNull("Parameter specification.", ps);
checkLine(ps, 24);
}
/**
* Test invalid parameter name.
*
* @since 2.2
*
**/
public void testInvalidParameterName() throws Exception
{
try
{
parseComponent("InvalidParameterName.jwc");
unreachable();
}
catch (DocumentParseException ex)
{
checkException(ex, "in-valid");
checkException(ex, "Parameter");
}
}
/**
* Test invalid parameter name.
*
* @since 2.2
*
**/
public void testInvalidComponentId() throws Exception
{
try
{
parseComponent("InvalidComponentId.jwc");
unreachable();
}
catch (DocumentParseException ex)
{
checkException(ex, "in.valid");
checkException(ex, "component id");
}
}
/**
* Test invalid library id in a library specification.
*
* @since 2.2
*
**/
public void testInvalidLibraryId() throws Exception
{
try
{
parseLib("InvalidLibraryId.library");
unreachable();
}
catch (DocumentParseException ex)
{
checkException(ex, "in.valid");
checkException(ex, "library id");
}
}
/**
* Parse a valid library.
*
* @since 2.2
*
**/
public void testValidLibrary() throws Exception
{
ILibrarySpecification spec = parseLib("ValidLibrary.library");
checkLine(spec, 24);
checkList("serviceNames", new String[] { "service1", "service2" }, spec.getServiceNames());
checkList("pageNames", new String[] { "FirstPage", "SecondPage" }, spec.getPageNames());
checkList(
"componentAliases",
new String[] { "FirstComponent", "SecondComponent" },
spec.getComponentTypes());
checkList("libraryIds", new String[] { "lib1", "lib2" }, spec.getLibraryIds());
}
/**
* Test invalid parameter name.
*
* @since 2.2
*
**/
public void testInvalidAssetName() throws Exception
{
try
{
parseComponent("InvalidAssetName.jwc");
unreachable();
}
catch (DocumentParseException ex)
{
checkException(ex, "in.valid");
checkException(ex, "asset name");
}
}
/**
* Test invalid page name.
*
* @since 2.2
*
**/
public void testInvalidPageName() throws Exception
{
try
{
parseApp("InvalidPageName.application");
unreachable();
}
catch (DocumentParseException ex)
{
checkException(ex, "in$valid");
checkException(ex, "page name");
}
}
/**
* Test invalid service name.
*
* @since 2.2
*
**/
public void testInvalidServiceName() throws Exception
{
try
{
parseApp("InvalidServiceName.application");
unreachable();
}
catch (DocumentParseException ex)
{
checkException(ex, "in$valid");
checkException(ex, "service");
}
}
/**
* Test invalid service name.
*
* @since 2.2
*
**/
public void testInvalidComponentAlias() throws Exception
{
try
{
parseApp("InvalidComponentAlias.application");
unreachable();
}
catch (DocumentParseException ex)
{
checkException(ex, "Invalid$Component");
checkException(ex, "type");
}
}
/**
* Test invalid extension name.
*
* @since 2.2
*
**/
public void testInvalidExtensionName() throws Exception
{
try
{
parseApp("InvalidExtensionName.application");
unreachable();
}
catch (DocumentParseException ex)
{
checkException(ex, "Invalid$Extension");
checkException(ex, "extension name");
}
}
/**
* Test case where the document does not have a DOCTYPE
*
* @since 2.2
*
**/
public void testMissingDoctype() throws Exception
{
try
{
parseApp("MissingDoctype.application");
unreachable();
}
catch (DocumentParseException ex)
{
// XML parsers tend to generate different exception messages,
// so make the condition as unspecific as possible
checkException(ex, "DOCTYPE");
}
}
/**
* Test case where the public id of the document is not known.
*
**/
public void testInvalidPublicId() throws Exception
{
try
{
parseApp("InvalidPublicId.application");
unreachable();
}
catch (DocumentParseException ex)
{
checkException(ex, "has an unexpected public id");
}
}
/**
* Test an an application specification can omit
* the name and engine-class attributes.
*
* @since 3.0
*
**/
public void testNulledApplication() throws Exception
{
IApplicationSpecification spec = parseApp("NulledApplication.application");
assertNull(spec.getEngineClassName());
assertNull(spec.getName());
checkLine(spec, 25);
}
/**
* Test new DTD 1.4 syntax for declaring components.
*
* @since 3.0
*
**/
public void testComponentType() throws Exception
{
IApplicationSpecification spec = parseApp("ComponentType.application");
assertEquals("/path/Fred.jwc", spec.getComponentSpecificationPath("Fred"));
}
/**
* Test omitting the class name from a component specification
* (new, in DTD 1.4).
*
**/
public void testNulledComponent() throws Exception
{
IComponentSpecification spec = parseComponent("NulledComponent.jwc");
assertNull(spec.getComponentClassName());
checkLine(spec, 22);
}
/**
* Test omitting the class name from a component specification
* (new, in DTD 1.4).
*
**/
public void testNulledPage() throws Exception
{
IComponentSpecification spec = parsePage("NulledPage.page");
assertNull(spec.getComponentClassName());
checkLine(spec, 22);
}
/**
* Test the value attribute for the property element
* (which is new in DTD 1.4).
*
* @since 3.0
*
**/
public void testPropertyValue() throws Exception
{
IComponentSpecification spec = parsePage("PropertyValue.page");
checkLine(spec, 22);
assertEquals("rubble", spec.getProperty("barney"));
assertEquals("flintstone", spec.getProperty("wilma"));
}
/**
* Tests the new (in DTD 1.4) value attribute on static-binding
* element.
*
* @since 3.0
*
**/
public void testStaticBindingValue() throws Exception
{
IComponentSpecification spec = parsePage("StaticBindingValue.page");
checkLine(spec, 22);
IContainedComponent c = spec.getComponent("c");
checkLine(c, 24);
IBindingSpecification b = c.getBinding("fred");
checkLine(b, 25);
assertEquals("flintstone", b.getValue());
b = c.getBinding("barney");
checkLine(b, 26);
assertEquals("rubble", b.getValue());
b = c.getBinding("rock");
checkLine(b, 27);
assertEquals("hudson", b.getValue());
}
public void testAttributeAndBody() throws Exception
{
try
{
parsePage("AttributeAndBody.page");
unreachable();
}
catch (DocumentParseException ex)
{
checkException(
ex,
"It is not valid to specify a value for attribute 'value' of <static-binding> and provide a value in the body of the element.");
}
}
/**
* Tests the new (in DTD 1.4) value attribute on a configure element.
*
* @since 3.0
*
**/
public void testConfigureValue() throws Exception
{
ILibrarySpecification spec = parseLib("ConfigureValue.library");
checkLine(spec, 22);
checkLine(spec.getExtensionSpecification("map"), 24);
Map map = (Map) spec.getExtension("map", Map.class);
assertEquals("flintstone", map.get("fred"));
}
/**
* Tests the new &lt;listener-binding&gt; element in the 1.4 DTD.
*
* @since 3.0
*
**/
public void testListenerBinding() throws Exception
{
IComponentSpecification spec = parsePage("ListenerBinding.page");
checkLine(spec, 22);
IContainedComponent c = spec.getComponent("c");
checkLine(c, 24);
IListenerBindingSpecification lbs = (ListenerBindingSpecification) c.getBinding("listener");
checkLine(lbs, 25);
String expectedScript =
buildExpectedScript(
new String[] {
"",
"if page.isFormInputValid():",
" cycle.page = \"Results\"",
"else:",
" page.message = \"Please fix errors before continuing.\";" });
assertEquals("jython", lbs.getLanguage());
assertEquals(expectedScript, lbs.getScript());
}
private String buildExpectedScript(String[] lines)
{
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < lines.length; i++)
{
if (i > 0)
buffer.append("\n");
buffer.append(lines[i]);
}
return buffer.toString();
}
/** @since 3.0 **/
public void testPropertySpecifications() throws Exception
{
IComponentSpecification spec = parsePage("PropertySpecifications.page");
checkList(
"propertySpecificationNames",
new String[] { "bool", "init", "persist" },
spec.getPropertySpecificationNames());
IPropertySpecification ps = spec.getPropertySpecification("bool");
assertEquals("name", "bool", ps.getName());
assertEquals("persistent", false, ps.isPersistent());
assertEquals("type", "boolean", ps.getType());
assertNull("initialValue", ps.getInitialValue());
checkLine(ps, 24);
ps = spec.getPropertySpecification("init");
assertEquals("name", "init", ps.getName());
assertEquals("persistent", false, ps.isPersistent());
assertEquals("type", "java.lang.Object", ps.getType());
assertEquals("initialValue", "pageName", ps.getInitialValue());
checkLine(ps, 26);
ps = spec.getPropertySpecification("persist");
assertEquals("name", "persist", ps.getName());
assertEquals("persistent", true, ps.isPersistent());
assertEquals("type", "java.lang.Object", ps.getType());
assertNull("initialValue", ps.getInitialValue());
checkLine(ps, 25);
ps = spec.getPropertySpecification("unknown");
assertNull("Unknown PropertySpecification", ps);
}
/** @since 3.0 **/
public void testDuplicatePropertySpecification() throws Exception
{
try
{
parsePage("DuplicatePropertySpecification.page");
unreachable();
}
catch (DocumentParseException ex)
{
checkException(ex, "already contains property specification for property 'bool'");
}
}
/** @since 3.0 **/
public void testMissingRequiredExtendedAttribute() throws Exception
{
try
{
parsePage("MissingRequiredExtendedAttribute.page");
unreachable();
}
catch (DocumentParseException ex)
{
checkException(
ex,
"Element <binding> does not specify a value for attribute 'expression', or contain a body value.");
}
}
/** @since 3.0 **/
public void testStringBeanInitializer() throws Exception
{
IComponentSpecification spec = parsePage("StringBeanInitializer.page");
IBeanSpecification bs = spec.getBeanSpecification("fred");
checkLine(bs, 24);
MessageBeanInitializer i = (MessageBeanInitializer) bs.getInitializers().get(0);
assertEquals("barney", i.getPropertyName());
assertEquals("rubble", i.getKey());
checkLine(i, 25);
}
/** @since 3.0 **/
public void testMessageBeanInitializer() throws Exception
{
IComponentSpecification spec = parsePage("MessageBeanInitializer.page");
IBeanSpecification bs = spec.getBeanSpecification("fred");
checkLine(bs, 24);
MessageBeanInitializer i = (MessageBeanInitializer) bs.getInitializers().get(0);
assertEquals("barney", i.getPropertyName());
assertEquals("rubble", i.getKey());
checkLine(i, 25);
}
public void testInheritInformalParameters() throws Exception
{
IComponentSpecification spec = parseComponent("TestInheritInformal.jwc");
IContainedComponent border = spec.getComponent("border");
assertEquals(border.getInheritInformalParameters(), false);
IContainedComponent textField = spec.getComponent("textField");
assertEquals(textField.getInheritInformalParameters(), true);
}
}