blob: 09714aa91e825d188624e23116c0bb038bb3169b [file] [log] [blame]
// Copyright 2006, 2007, 2008 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.tapestry5.internal.model;
import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.internal.test.InternalBaseTestCase;
import org.apache.tapestry5.ioc.Location;
import org.apache.tapestry5.ioc.Resource;
import org.apache.tapestry5.model.ComponentModel;
import org.apache.tapestry5.model.MutableComponentModel;
import org.apache.tapestry5.model.MutableEmbeddedComponentModel;
import org.apache.tapestry5.model.ParameterModel;
import org.slf4j.Logger;
import org.testng.annotations.Test;
import java.util.Arrays;
/**
* Tests {@link org.apache.tapestry5.internal.model.MutableComponentModelImpl} and {@link
* org.apache.tapestry5.internal.model.MutableEmbeddedComponentModelImpl}.
*/
public class MutableComponentModelImplTest extends InternalBaseTestCase
{
private static final String COMPONENT_CLASS_NAME = "org.example.components.Fred";
private static final String CLASS_NAME = "org.example.components.Foo";
@Test
public void root_class_vs_sub_class()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
assertTrue(model.isRootClass());
MutableComponentModel subModel = new MutableComponentModelImpl(CLASS_NAME, logger, r, model);
assertFalse(subModel.isRootClass());
verify();
}
@Test
public void add_new_parameter()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
assertTrue(model.getParameterNames().isEmpty());
String parameterName = "value";
model.addParameter(parameterName, true, BindingConstants.PROP);
ParameterModel pm = model.getParameterModel(parameterName);
assertEquals(pm.getName(), parameterName);
assertEquals(true, pm.isRequired());
assertEquals(pm.getDefaultBindingPrefix(), BindingConstants.PROP);
assertEquals(model.getDeclaredParameterNames(), Arrays.asList(parameterName));
// Verify that the binding prefix is actually stored:
model.addParameter("fred", true, "flint");
// Checks that parameter names are case insensitive
assertEquals(model.getParameterModel("Fred").getDefaultBindingPrefix(), "flint");
verify();
}
@Test
public void parameter_names_are_sorted()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
model.addParameter("fred", true, BindingConstants.PROP);
model.addParameter("wilma", true, BindingConstants.PROP);
model.addParameter("barney", true, BindingConstants.PROP);
assertEquals(model.getDeclaredParameterNames(), Arrays.asList("barney", "fred", "wilma"));
verify();
}
@Test
public void declared_parameter_names_does_not_include_superclass_parameters()
{
Resource r = mockResource();
Logger logger = mockLogger();
ComponentModel parent = mockComponentModel();
train_getPersistentFieldNames(parent);
train_getParameterNames(parent, "betty");
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
model.addParameter("fred", true, BindingConstants.PROP);
model.addParameter("wilma", true, BindingConstants.PROP);
model.addParameter("barney", true, BindingConstants.PROP);
assertEquals(model.getDeclaredParameterNames(), Arrays.asList("barney", "fred", "wilma"));
assertEquals(model.getParameterNames(), Arrays.asList("barney", "betty", "fred", "wilma"));
verify();
}
@Test
public void add_duplicate_parameter()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
model.addParameter("fred", true, BindingConstants.PROP);
try
{
// This also helps check that the comparison is caseless!
model.addParameter("Fred", true, BindingConstants.PROP);
unreachable();
}
catch (IllegalArgumentException ex)
{
assertEquals(ex.getMessage(),
"Parameter 'Fred' of component org.example.components.Foo is already defined.");
}
verify();
}
@Test
public void get_parameter_by_name_with_no_parameters_defined()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
assertNull(model.getParameterModel("foo"));
verify();
}
@Test
public void get_unknown_parameter()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
model.addParameter("fred", true, BindingConstants.PROP);
assertNull(model.getParameterModel("barney"));
verify();
}
@Test
public void add_embedded()
{
Resource r = mockResource();
Logger logger = mockLogger();
Location l = mockLocation();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
assertTrue(model.getEmbeddedComponentIds().isEmpty());
MutableEmbeddedComponentModel fred = model.addEmbeddedComponent("fred", "Fred", COMPONENT_CLASS_NAME, false, l);
assertEquals(fred.getId(), "fred");
assertEquals(fred.getComponentType(), "Fred");
assertFalse(fred.getInheritInformalParameters());
assertSame(fred.getLocation(), l);
MutableEmbeddedComponentModel barney = model.addEmbeddedComponent("barney", "Barney", COMPONENT_CLASS_NAME,
false, null);
assertEquals(model.getEmbeddedComponentIds(), Arrays.asList("barney", "fred"));
assertSame(model.getEmbeddedComponentModel("fred"), fred);
assertSame(model.getEmbeddedComponentModel("barney"), barney);
// Access by id is case insensitive
assertSame(model.getEmbeddedComponentModel("FRED"), fred);
assertSame(model.getEmbeddedComponentModel("BARNEY"), barney);
assertEquals(fred.toString(),
"EmbeddedComponentModel[id=fred type=Fred class=org.example.components.Fred inheritInformals=false]");
verify();
}
@Test
public void add_embedded_component_with_duplicate_id()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
model.addEmbeddedComponent("fred", "Fred1", COMPONENT_CLASS_NAME, false, null);
try
{
model.addEmbeddedComponent("fred", "Fred2", COMPONENT_CLASS_NAME, false, null);
unreachable();
}
catch (IllegalArgumentException ex)
{
assertEquals(ex.getMessage(),
"Embedded component 'fred' has already been defined for component class org.example.components.Foo.");
}
verify();
}
@Test
public void add_embedded_with_inherit_informal_parameters()
{
Resource r = mockResource();
Logger logger = mockLogger();
Location l = mockLocation();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
assertTrue(model.getEmbeddedComponentIds().isEmpty());
MutableEmbeddedComponentModel fred = model.addEmbeddedComponent("fred", "Fred", COMPONENT_CLASS_NAME, true, l);
assertTrue(fred.getInheritInformalParameters());
assertEquals(fred.toString(),
"EmbeddedComponentModel[id=fred type=Fred class=org.example.components.Fred inheritInformals=true]");
verify();
}
@Test
public void add_embedded_is_case_insensitive()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
model.addEmbeddedComponent("fred", "Fred1", COMPONENT_CLASS_NAME, false, null);
try
{
model.addEmbeddedComponent("FRED", "Fred2", COMPONENT_CLASS_NAME, false, null);
unreachable();
}
catch (IllegalArgumentException ex)
{
assertEquals(ex.getMessage(),
"Embedded component 'FRED' has already been defined for component class org.example.components.Foo.");
}
verify();
}
@Test
public void add_parameters_to_embedded()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
MutableEmbeddedComponentModel fred = model.addEmbeddedComponent("fred", "Fred", COMPONENT_CLASS_NAME, false,
null);
assertTrue(fred.getParameterNames().isEmpty());
fred.addParameter("city", "bedrock");
fred.addParameter("job", "crane operator");
assertEquals(fred.getParameterNames(), Arrays.asList("city", "job"));
assertEquals(fred.getParameterValue("city"), "bedrock");
verify();
}
@Test
public void add_duplicate_parameters_to_embedded()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
MutableEmbeddedComponentModel fred = model.addEmbeddedComponent("fred", "Fred", COMPONENT_CLASS_NAME, false,
null);
fred.addParameter("city", "bedrock");
try
{
fred.addParameter("city", "slateville");
unreachable();
}
catch (IllegalArgumentException ex)
{
assertEquals(ex.getMessage(),
"A value for parameter 'city' of embedded component fred (of component class org.example.components.Foo) has already been provided.");
}
verify();
}
@Test
public void mixin_names_is_initially_empty_list()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
MutableEmbeddedComponentModel fred = model.addEmbeddedComponent("fred", "Fred", COMPONENT_CLASS_NAME, false,
null);
assertTrue(fred.getMixinClassNames().isEmpty());
verify();
}
@Test
public void mixin_class_names_remembered_in_order_added()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
MutableEmbeddedComponentModel fred = model.addEmbeddedComponent("fred", "Fred", COMPONENT_CLASS_NAME, false,
null);
fred.addMixin("zip.zop.Zoom");
fred.addMixin("foo.bar.Baz");
assertEquals(fred.getMixinClassNames(), Arrays.asList("zip.zop.Zoom", "foo.bar.Baz"));
verify();
}
@Test
public void mixin_name_conflict()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
MutableEmbeddedComponentModel fred = model.addEmbeddedComponent("fred", "Fred", COMPONENT_CLASS_NAME, false,
null);
fred.addMixin("zip.zop.Zoom");
try
{
fred.addMixin("zip.zop.Zoom");
unreachable();
}
catch (IllegalArgumentException ex)
{
assertEquals(ex.getMessage(), "Mixin zip.zop.Zoom (for component fred) has already been defined.");
}
// Make sure it wasn't actually added.
assertEquals(fred.getMixinClassNames(), Arrays.asList("zip.zop.Zoom"));
verify();
}
@Test
public void get_persistent_field_names_when_none_defined()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
assertTrue(model.getPersistentFieldNames().isEmpty());
verify();
}
@Test
public void get_persistent_field_names_are_sorted()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
assertEquals(model.setFieldPersistenceStrategy("fred", "session"), "fred");
assertEquals(model.setFieldPersistenceStrategy("barney", "client"), "barney");
assertEquals(model.getPersistentFieldNames(), Arrays.asList("barney", "fred"));
verify();
}
@Test
public void get_persistent_field_names_reflects_parent_model()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel parent = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
assertEquals(parent.setFieldPersistenceStrategy("wilma", "session"), "wilma");
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
assertEquals(model.setFieldPersistenceStrategy("fred", "session"), "fred");
assertEquals(model.setFieldPersistenceStrategy("barney", "client"), "barney");
assertEquals(model.getPersistentFieldNames(), Arrays.asList("barney", "fred", "wilma"));
verify();
}
@Test
public void persistent_field_names_allocated_in_subclasses_are_unique()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel parent = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
assertEquals(parent.setFieldPersistenceStrategy("wilma", "session"), "wilma");
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
assertEquals(model.setFieldPersistenceStrategy("wilma", "session"), "wilma_0");
assertEquals(model.getPersistentFieldNames(), Arrays.asList("wilma", "wilma_0"));
verify();
}
@Test
public void get_persistent_field_defined_in_model()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
model.setFieldPersistenceStrategy("fred", "session");
model.setFieldPersistenceStrategy("barney", "client");
assertEquals(model.getFieldPersistenceStrategy("fred"), "session");
assertEquals(model.getFieldPersistenceStrategy("barney"), "client");
verify();
}
@Test
public void no_persistence_defined_for_field()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
try
{
model.getFieldPersistenceStrategy("someField");
unreachable();
}
catch (IllegalArgumentException ex)
{
assertEquals(ex.getMessage(), "No field persistence strategy has been defined for field \'someField\'.");
}
verify();
}
@Test
public void get_persistent_field_defined_in_parent()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel parent = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
parent.setFieldPersistenceStrategy("wilma", "parent");
model.setFieldPersistenceStrategy("fred", "session");
assertEquals(model.getFieldPersistenceStrategy("wilma"), "parent");
verify();
}
@Test
public void default_for_supports_informal_parameters_is_false()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
assertFalse(model.getSupportsInformalParameters());
model.enableSupportsInformalParameters();
assertTrue(model.getSupportsInformalParameters());
verify();
}
@Test
public void get_mixin_class_names_with_no_mixins()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
ComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
assertTrue(model.getMixinClassNames().isEmpty());
verify();
}
@Test
public void get_mixin_class_names_mixes_with_parent_model()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel parent = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
parent.addMixinClassName("Wilma");
MutableComponentModel child = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
child.addMixinClassName("Fred");
child.addMixinClassName("Barney");
assertEquals(child.getMixinClassNames(), Arrays.asList("Barney", "Fred", "Wilma"));
verify();
}
@Test
public void get_parent_from_subclass()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel parent = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
MutableComponentModel child = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
assertSame(child.getParentModel(), parent);
assertNull(parent.getParentModel());
verify();
}
@Test
public void set_and_get_meta()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
model.setMeta("fred", "flintstone");
model.setMeta("barney", "rubble");
assertEquals(model.getMeta("fred"), "flintstone");
assertEquals(model.getMeta("barney"), "rubble");
// Ensure case insensitive:
assertEquals(model.getMeta("FRED"), "flintstone");
assertEquals(model.getMeta("BARNEY"), "rubble");
verify();
}
@Test
public void get_meta_from_parent()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel parent = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
MutableComponentModel child = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
parent.setMeta("fred", "flintstone");
assertEquals(child.getMeta("fred"), "flintstone");
verify();
}
@Test
public void parent_does_not_have_meta()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel parent = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
MutableComponentModel child = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
parent.setMeta("fred", "flintstone");
assertNull(child.getMeta("wilma"));
verify();
}
@Test
public void child_meta_overrides_parent_meta()
{
Resource r = mockResource();
Logger logger = mockLogger();
replay();
MutableComponentModel parent = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
MutableComponentModel child = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
parent.setMeta("fred", "flintstone");
child.setMeta("fred", "mcmurray");
assertEquals(parent.getMeta("fred"), "flintstone");
assertEquals(child.getMeta("fred"), "mcmurray");
verify();
}
}