You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2007/01/19 16:39:47 UTC
svn commit: r497845 - in /tapestry/tapestry5/tapestry-core/trunk/src:
main/java/org/apache/tapestry/
main/java/org/apache/tapestry/corelib/components/
main/java/org/apache/tapestry/internal/services/
main/java/org/apache/tapestry/test/ main/java/org/ap...
Author: hlship
Date: Fri Jan 19 07:39:41 2007
New Revision: 497845
URL: http://svn.apache.org/viewvc?view=rev&rev=497845
Log:
Add support for overriding validation messages on a per-component/per-validator basis.
Start documentation about Forms and Validation.
Added:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/MinLength.java
tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/validation.apt
tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/ValidForm.properties
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Validator.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Form.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/FieldValidatorSourceImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/Required.java
tapestry/tapestry5/tapestry-core/trunk/src/site/apt/index.apt
tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/FieldValidatorSourceImplTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/validator/RequiredTest.java
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Validator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Validator.java?view=diff&rev=497845&r1=497844&r2=497845
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Validator.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Validator.java Fri Jan 19 07:39:41 2007
@@ -14,7 +14,8 @@
package org.apache.tapestry;
-import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.apache.tapestry.services.ValidationMessagesSource;
/**
* Used by a {@link Field} to enforce a <strong>constraint</strong> related to a form submission.
@@ -30,7 +31,17 @@
* type int (the maximum length allowed). For constraints that do not have a constraint value,
* this method returns null.
*/
- public Class<C> getConstraintType();
+ Class<C> getConstraintType();
+
+ /**
+ * Returns the message key, within the validiation messages, normally used by this validator.
+ * This is used to provide the {@link MessageFormatter} passed to
+ * {@link #check(Field, Object, MessageFormatter, Object)} (unless overridden).
+ *
+ * @see ValidationMessagesSource
+ * @return a message key
+ */
+ String getMessageKey();
/**
* Invoked after the client-submitted value has been {@link Translator translated} to check that
@@ -41,13 +52,13 @@
* the field for which a client submitted value is being validated
* @param constraintValue
* the value used to constrain
- * @param messages
+ * @param formatter
* Validation messages, in the appropriate locale
* @param value
* the translated value supplied by the user
* @throws ValidationException
* if the value violates the constraint
*/
- void check(Field field, C constraintValue, Messages messages, T value)
+ void check(Field field, C constraintValue, MessageFormatter formatter, T value)
throws ValidationException;
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Form.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Form.java?view=diff&rev=497845&r1=497844&r2=497845
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Form.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/components/Form.java Fri Jan 19 07:39:41 2007
@@ -59,7 +59,7 @@
* An HTML form, which will enclose other components to render out the various types of fields.
* <p>
* A Form emits several notification events; when it renders it sends a
- * {@link #PREPARE_EVENT#prepare} notification event, to allow any listeners to set up the state of
+ * {@link #PREPARE_EVENT prepare} notification event, to allow any listeners to set up the state of
* the page prior to rendering out the form's content.
* <p>
* When the form is submitted, the component emits four notifications: first another prepare event
@@ -379,7 +379,7 @@
}
/**
- * A convienience for invoking {@link ValidationTracker#recordError(String).
+ * A convienience for invoking {@link ValidationTracker#recordError(String)}.
*/
public void recordError(String errorMessage)
{
@@ -391,7 +391,7 @@
}
/**
- * A convienience for invoking {@link ValidationTracker#recordError(Field, String).
+ * A convienience for invoking {@link ValidationTracker#recordError(Field, String)}.
*/
public void recordError(Field field, String errorMessage)
{
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/FieldValidatorSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/FieldValidatorSourceImpl.java?view=diff&rev=497845&r1=497844&r2=497845
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/FieldValidatorSourceImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/FieldValidatorSourceImpl.java Fri Jan 19 07:39:41 2007
@@ -22,10 +22,12 @@
import java.util.Locale;
import java.util.Map;
+import org.apache.tapestry.ComponentResources;
import org.apache.tapestry.Field;
import org.apache.tapestry.FieldValidator;
import org.apache.tapestry.ValidationException;
import org.apache.tapestry.Validator;
+import org.apache.tapestry.ioc.MessageFormatter;
import org.apache.tapestry.ioc.Messages;
import org.apache.tapestry.ioc.internal.util.InternalUtils;
import org.apache.tapestry.ioc.services.TypeCoercer;
@@ -68,18 +70,40 @@
final Object coercedConstraintValue = coerceConstraintValue(constraintValue, validator
.getConstraintType());
- Locale locale = component.getComponentResources().getLocale();
-
- final Messages messages = _messagesSource.getValidationMessages(locale);
+ final MessageFormatter formatter = findMessageFormatter(component, validatorType, validator);
return new FieldValidator()
{
@SuppressWarnings("unchecked")
public void check(Object value) throws ValidationException
{
- validator.check(field, coercedConstraintValue, messages, value);
+ validator.check(field, coercedConstraintValue, formatter, value);
}
};
+ }
+
+ private MessageFormatter findMessageFormatter(Component component, String validatorType,
+ Validator validator)
+ {
+ ComponentResources resources = component.getComponentResources();
+
+ String overrideKey = resources.getId() + "-" + validatorType;
+
+ // So, if you use a TextField on your EditUser page, we want to search the messages
+ // of the EditUser page (the container), not the TextField (which will always be the same).
+
+ Messages messages = resources.getContainerResources().getMessages();
+
+ if (messages.contains(overrideKey))
+ return messages.getFormatter(overrideKey);
+
+ Locale locale = resources.getLocale();
+
+ messages = _messagesSource.getValidationMessages(locale);
+
+ String key = validator.getMessageKey();
+
+ return messages.getFormatter(key);
}
public FieldValidator createValidators(Field field, String specification)
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java?view=diff&rev=497845&r1=497844&r2=497845
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java Fri Jan 19 07:39:41 2007
@@ -48,6 +48,7 @@
import org.apache.tapestry.annotations.Inject;
import org.apache.tapestry.annotations.Parameter;
import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.MessageFormatter;
import org.apache.tapestry.ioc.Messages;
import org.apache.tapestry.ioc.Resource;
import org.apache.tapestry.ioc.ServiceLocator;
@@ -670,5 +671,20 @@
protected final Heartbeat newHeartbeat()
{
return newMock(Heartbeat.class);
+ }
+
+ protected void train_getMessageKey(Validator validator, String messageKey)
+ {
+ expect(validator.getMessageKey()).andReturn(messageKey).atLeastOnce();
+ }
+
+ protected final void train_getMessageFormatter(Messages messages, String key, MessageFormatter formatter)
+ {
+ expect(messages.getFormatter(key)).andReturn(formatter).atLeastOnce();
+ }
+
+ protected final MessageFormatter newMessageFormatter()
+ {
+ return newMock(MessageFormatter.class);
}
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/MinLength.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/MinLength.java?view=auto&rev=497845
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/MinLength.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/MinLength.java Fri Jan 19 07:39:41 2007
@@ -0,0 +1,29 @@
+package org.apache.tapestry.validator;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.Validator;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+
+public class MinLength implements Validator<Integer, String>
+{
+ public String getMessageKey()
+ {
+ return "min-length";
+ }
+
+ public void check(Field field, Integer constraintValue, MessageFormatter formatter, String value)
+ throws ValidationException
+ {
+ if (InternalUtils.isBlank(value))
+ return;
+
+ }
+
+ public Class<Integer> getConstraintType()
+ {
+ return Integer.class;
+ }
+
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/Required.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/Required.java?view=diff&rev=497845&r1=497844&r2=497845
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/Required.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/Required.java Fri Jan 19 07:39:41 2007
@@ -17,7 +17,7 @@
import org.apache.tapestry.Field;
import org.apache.tapestry.ValidationException;
import org.apache.tapestry.Validator;
-import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.MessageFormatter;
/**
* A validator that enforces that the value is not null and not the empty string. This validator is
@@ -25,11 +25,16 @@
*/
public class Required implements Validator<Void, Object>
{
- public void check(Field field, Void constraintValue, Messages messages, Object value)
+ public String getMessageKey()
+ {
+ return "required";
+ }
+
+ public void check(Field field, Void constraintValue, MessageFormatter formatter, Object value)
throws ValidationException
{
if (value == null || value.toString().equals(""))
- throw new ValidationException(messages.format("required", field.getLabel()));
+ throw new ValidationException(formatter.format(field.getLabel()));
}
public Class<Void> getConstraintType()
Added: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/validation.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/validation.apt?view=auto&rev=497845
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/validation.apt (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/validation.apt Fri Jan 19 07:39:41 2007
@@ -0,0 +1,130 @@
+ ---
+ Form Input and Validation
+ ---
+
+Form Input and Validation
+
+ The life's blood of any application is form input; this is the most effective way to gather significant information from the user.
+ Whether it's a search form, a login screen or a multi-page registration wizard, forms are how the user really expresses themselves to the
+ application.
+
+ Tapestry excels at creating forms and validating input. Input validation is declarative, meaning you simply tell Tapestry what validations
+ to apply to a given field, and it takes care of it on the server and (once implemented) on the client as well.
+
+Form component
+
+ The core of Tapestry's form support is the
+ {{{../apidocs/org/apache/tapestry/corelib/components/Form.html}Form}} component. The Form component encloses (wraps around) all the
+ other <field components> (components that create HTML form element for the client web browser) such as
+ {{{../apidocs/org/apache/tapestry/corelib/components/TextField.html}TextField}},
+ {{{../apidocs/org/apache/tapestry/corelib/components/TextArea.html}TextArea}},
+ {{{../apidocs/org/apache/tapestry/corelib/components/Checkbox.html}Checkbox}}, etc.
+
+ The Form component generates a number of {{{event.html}component events}} that
+ you may provide event handler methods for.
+
+ When rendering, the Form component emits a "prepare" notification, to allow the
+ Form's container to setup any fields or properties that will be referenced in the form.
+ For example, this is a good chance to create a temporary entity object to be rendered, or
+ to load an entity from a database to be editted.
+
+ When user submits the form on the client, a series of steps occur on the server.
+
+ First, the Form emits a "prepare" notification, as it did when the Form was rendered.
+
+ Next, all the fields inside the form are activated to pull values out of the
+ incoming request, validate them and (if valid) store the changes.
+
+ <For Tapestry 4 Users: > Tapestry 5 does not use the fragile "form rewind" method
+ from Tapestry 4. Instead, a hidden field generated during the render stores
+ the information needed to process the form submission.
+
+ After the fields have done their processing, the Form emits a "validate" event.
+ This is a chance to perform cross-form validation that can't be described declaratively.
+
+ Next, the Form determines if there have been any validation errors. If there have been,
+ then the submission is considered a failure, and a "failure" event is emitted.
+ If there have been no validation errors, then a "success" event is emitted.
+
+ Last, the Form emits a "submit" event (for logic that doesn't care about success or
+ failure).
+
+Tracking Validation Errors
+
+ Associated with the Form is an
+ {{{../apidocs/org/apache/tapestry/ValidationTracker.html}ValidationTracker}}
+ that tracks all the provided user input and validation errors for every field in the
+ form. The tracker can be provided to the Form via the Form's tracker parameter,
+ but this is rarely necessary.
+
+ The Form includes methods isValid() and getHasErrors(), which are used to
+ see if the Form's validation tracker contains any errors.
+
+ In your own logic, it is possible to record your own errors. Form includes
+ two different versions of recordError(), one of which specifies a
+ {{{../apidocs/org/apache/tapestry/Field.html}Field}} (an interface implemented by
+ all form element components), and one of which is for "global" errors, unassociated
+ with any particular field.
+
+Storing Data Between Requests
+
+ As with other action requests, the result of a form submission is to send a redirect
+ to the client which re-renders the page. The ValidationTracker must be
+ stored {{{persist.html}persistently}} between requests, or all the validation
+ information will be lost (the default ValidationTracker provided by the Form is persistent).
+
+ Likewise, the individual fields updated by the components should also be persistent.
+
+ For example, a Login page, which collects a user name and a password, might look like:
+
++---+
+@ComponentClass
+public class Login
+{
+ @Retain
+ private String _userName;
+
+ private String _password;
+
+ @Inject
+ private UserAuthenticator _authenticator;
+
+ @Component(id = "password")
+ private PasswordField _passwordField;
+
+ @Component
+ private Form _form;
+
+ String onSuccess()
+ {
+ if (!_authenticator.isValid(_userName, _password))
+ {
+ _form.recordError(_passwordField, "Invalid user name or password.");
+ return null;
+ }
+
+ return "PostLogin";
+ }
+
+ public String getPassword()
+ {
+ return _password;
+ }
+
+ public void setPassword(String password)
+ {
+ _password = password;
+ }
+
+ public String getUserName()
+ {
+ return _userName;
+ }
+
+ public void setUserName(String userName)
+ {
+ _userName = userName;
+ }
+}
++---+
+
\ No newline at end of file
Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/index.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/index.apt?view=diff&rev=497845&r1=497844&r2=497845
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/index.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/index.apt Fri Jan 19 07:39:41 2007
@@ -38,6 +38,8 @@
Progress on Tapestry 5 is really taking off. This space lists some cool new features that have been added
recently.
+ * Input validation messages may not be overriden by providing a particular message key in the containing component's message catalog.
+
* Property expressions may now reference public methods (with no parameters) in addition to traditional property names.
* Page templates are now allowed to be stored in the web application root, as well as on the classpath.
Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml?view=diff&rev=497845&r1=497844&r2=497845
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml Fri Jan 19 07:39:41 2007
@@ -54,6 +54,7 @@
<item name="Component Classes" href="guide/component-classes.html"/>
<item name="Component Templates" href="guide/templates.html"/>
<item name="Component Parameters" href="guide/parameters.html"/>
+ <item name="Input Validation" href="guide/validation.html"/>
<item name="Component Events" href="guide/event.html"/>
<item name="Component Mixins" href="guide/mixins.html"/>
<item name="Localization" href="guide/localization.html"/>
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?view=diff&rev=497845&r1=497844&r2=497845
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Fri Jan 19 07:39:41 2007
@@ -456,7 +456,8 @@
clickAndWait("link=ValidForm");
clickAndWait("//input[@type='submit']");
assertTextPresent("You must provide a value for Email.");
- assertTextPresent("You must provide a value for Incident Message.");
+ // This is an overrdden validation error message:
+ assertTextPresent("Please provide a detailed description of the incident.");
// Check on decorations via the default validation decorator:
@@ -509,7 +510,7 @@
@Test
public void volatile_loop_inside_a_form()
{
- test_loop_inside_form("ToDo List (Volatile)");
+ test_loop_inside_form("ToDo List (Volatile)");
}
@Test
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/FieldValidatorSourceImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/FieldValidatorSourceImplTest.java?view=diff&rev=497845&r1=497844&r2=497845
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/FieldValidatorSourceImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/FieldValidatorSourceImplTest.java Fri Jan 19 07:39:41 2007
@@ -27,6 +27,7 @@
import org.apache.tapestry.FieldValidator;
import org.apache.tapestry.Validator;
import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.MessageFormatter;
import org.apache.tapestry.ioc.Messages;
import org.apache.tapestry.ioc.services.TypeCoercer;
import org.apache.tapestry.runtime.Component;
@@ -81,20 +82,77 @@
Validator validator = newValidator();
TypeCoercer coercer = newTypeCoercer();
FieldComponent field = newFieldComponent();
- Messages messages = newMock(Messages.class);
+ Messages messages = newMessages();
+ MessageFormatter formatter = newMessageFormatter();
Object inputValue = new Object();
ComponentResources resources = newComponentResources();
+ ComponentResources containerResources = newComponentResources();
+ Messages componentMessages = newMessages();
Map<String, Validator> map = singletonMap("required", validator);
train_getConstraintType(validator, null);
train_getComponentResources(field, resources);
+
+ train_getId(resources, "fred");
+ train_getContainerResources(resources, containerResources);
+ train_getMessages(containerResources, componentMessages);
+ train_contains(componentMessages, "fred-required", false);
+
train_getLocale(resources, Locale.FRENCH);
train_getValidationMessages(messagesSource, Locale.FRENCH, messages);
- validator.check(field, null, messages, inputValue);
+ train_getMessageKey(validator, "key");
+ train_getMessageFormatter(messages, "key", formatter);
+
+ validator.check(field, null, formatter, inputValue);
+
+ replay();
+
+ FieldValidatorSource source = new FieldValidatorSourceImpl(messagesSource, coercer, map);
+
+ FieldValidator fieldValidator = source.createValidator(field, "required", null);
+
+ fieldValidator.check(inputValue);
+
+ verify();
+ }
+
+ protected final void train_getContainerResources(ComponentResources resources,
+ ComponentResources containerResources)
+ {
+ expect(resources.getContainerResources()).andReturn(containerResources).atLeastOnce();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void component_messages_overrides_validator_messages() throws Exception
+ {
+ ValidationMessagesSource messagesSource = newValidationMessagesSource();
+ Validator validator = newValidator();
+ TypeCoercer coercer = newTypeCoercer();
+ FieldComponent field = newFieldComponent();
+ MessageFormatter formatter = newMessageFormatter();
+ Object inputValue = new Object();
+ ComponentResources resources = newComponentResources();
+ ComponentResources containerResources = newComponentResources();
+ Messages componentMessages = newMessages();
+
+ Map<String, Validator> map = singletonMap("required", validator);
+
+ train_getConstraintType(validator, null);
+
+ train_getComponentResources(field, resources);
+ train_getId(resources, "fred");
+ train_getContainerResources(resources, containerResources);
+ train_getMessages(containerResources, componentMessages);
+ train_contains(componentMessages, "fred-required", true);
+
+ train_getMessageFormatter(componentMessages, "fred-required", formatter);
+
+ validator.check(field, null, formatter, inputValue);
replay();
@@ -115,20 +173,31 @@
Validator validator = newValidator();
TypeCoercer coercer = newTypeCoercer();
FieldComponent field = newFieldComponent();
- Messages messages = newMock(Messages.class);
+ Messages messages = newMessages();
+ MessageFormatter formatter = newMessageFormatter();
Object inputValue = new Object();
ComponentResources resources = newComponentResources();
+ ComponentResources containerResources = newComponentResources();
+ Messages componentMessages = newMessages();
Map<String, Validator> map = singletonMap("required", validator);
train_getConstraintType(validator, null);
train_getComponentResources(field, resources);
+ train_getId(resources, "fred");
+ train_getContainerResources(resources, containerResources);
+ train_getMessages(containerResources, componentMessages);
+ train_contains(componentMessages, "fred-required", false);
+
train_getLocale(resources, Locale.FRENCH);
train_getValidationMessages(messagesSource, Locale.FRENCH, messages);
- validator.check(field, null, messages, inputValue);
+ train_getMessageKey(validator, "key");
+ train_getMessageFormatter(messages, "key", formatter);
+
+ validator.check(field, null, formatter, inputValue);
replay();
@@ -141,6 +210,21 @@
verify();
}
+ private void train_contains(Messages messages, String key, boolean result)
+ {
+ expect(messages.contains(key)).andReturn(result).atLeastOnce();
+ }
+
+ protected void train_getId(ComponentResources resources, String id)
+ {
+ expect(resources.getId()).andReturn(id).atLeastOnce();
+ }
+
+ protected final void train_getMessages(ComponentResources resources, Messages messages)
+ {
+ expect(resources.getMessages()).andReturn(messages).atLeastOnce();
+ }
+
@SuppressWarnings("unchecked")
@Test
public void multiple_validators_via_specification() throws Exception
@@ -150,9 +234,13 @@
Validator minLength = newValidator();
TypeCoercer coercer = newTypeCoercer();
FieldComponent field = newFieldComponent();
- Messages messages = newMock(Messages.class);
+ Messages messages = newMessages();
+ MessageFormatter requiredFormatter = newMessageFormatter();
+ MessageFormatter minLengthFormatter = newMessageFormatter();
Object inputValue = new Object();
ComponentResources resources = newComponentResources();
+ ComponentResources containerResources = newComponentResources();
+ Messages componentMessages = newMessages();
Integer fifteen = 15;
Map<String, Validator> map = newMap();
@@ -164,14 +252,27 @@
train_getConstraintType(minLength, Integer.class);
train_getComponentResources(field, resources);
+ train_getId(resources, "fred");
+ train_getContainerResources(resources, containerResources);
+ train_getMessages(containerResources, componentMessages);
+ train_contains(componentMessages, "fred-required", false);
+
train_getLocale(resources, Locale.FRENCH);
train_getValidationMessages(messagesSource, Locale.FRENCH, messages);
+ train_getMessageKey(required, "required");
+ train_getMessageFormatter(messages, "required", requiredFormatter);
+
+ train_contains(componentMessages, "fred-minLength", false);
+
+ train_getMessageKey(minLength, "min-length");
+ train_getMessageFormatter(messages, "min-length", minLengthFormatter);
+
train_coerce(coercer, "15", Integer.class, fifteen);
- required.check(field, null, messages, inputValue);
- minLength.check(field, fifteen, messages, inputValue);
+ required.check(field, null, requiredFormatter, inputValue);
+ minLength.check(field, fifteen, minLengthFormatter, inputValue);
replay();
@@ -192,9 +293,12 @@
Validator validator = newValidator();
TypeCoercer coercer = newTypeCoercer();
FieldComponent field = newFieldComponent();
- Messages messages = newMock(Messages.class);
+ Messages messages = newMessages();
+ MessageFormatter formatter = newMessageFormatter();
Object inputValue = new Object();
ComponentResources resources = newComponentResources();
+ ComponentResources containerResources = newComponentResources();
+ Messages componentMessages = newMessages();
Integer five = 5;
Map<String, Validator> map = singletonMap("minLength", validator);
@@ -204,11 +308,19 @@
train_coerce(coercer, "5", Integer.class, five);
train_getComponentResources(field, resources);
+ train_getId(resources, "fred");
+ train_getContainerResources(resources, containerResources);
+ train_getMessages(containerResources, componentMessages);
+ train_contains(componentMessages, "fred-minLength", false);
+
train_getLocale(resources, Locale.FRENCH);
train_getValidationMessages(messagesSource, Locale.FRENCH, messages);
- validator.check(field, five, messages, inputValue);
+ train_getMessageKey(validator, "key");
+ train_getMessageFormatter(messages, "key", formatter);
+
+ validator.check(field, five, formatter, inputValue);
replay();
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/validator/RequiredTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/validator/RequiredTest.java?view=diff&rev=497845&r1=497844&r2=497845
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/validator/RequiredTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/validator/RequiredTest.java Fri Jan 19 07:39:41 2007
@@ -16,7 +16,7 @@
import org.apache.tapestry.Field;
import org.apache.tapestry.ValidationException;
-import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.MessageFormatter;
import org.apache.tapestry.test.TapestryTestCase;
import org.testng.annotations.Test;
@@ -25,16 +25,16 @@
@Test
public void null_value()
{
- Messages messages = newMessages();
Field field = newField("My Field");
+ MessageFormatter formatter = newMessageFormatter();
- train_format(messages, "required", "{message}", "My Field");
+ train_format(formatter, "{message}", "My Field");
replay();
try
{
- new Required().check(field, null, messages, null);
+ new Required().check(field, null, formatter, null);
unreachable();
}
catch (ValidationException ex)
@@ -48,16 +48,16 @@
@Test
public void blank_value()
{
- Messages messages = newMessages();
+ MessageFormatter formatter = newMessageFormatter();
Field field = newField("My Field");
- train_format(messages, "required", "{message}", "My Field");
+ train_format(formatter, "{message}", "My Field");
replay();
try
{
- new Required().check(field, null, messages, "");
+ new Required().check(field, null, formatter, "");
unreachable();
}
catch (ValidationException ex)
@@ -71,19 +71,20 @@
@Test
public void non_blank_value() throws Exception
{
- Messages messages = newMessages();
+ MessageFormatter formatter = newMessageFormatter();
Field field = newField();
replay();
- new Required().check(field, null, messages, "not null");
+ new Required().check(field, null, formatter, "not null");
verify();
}
- protected void train_format(Messages messages, String key, String result, Object... arguments)
+ /** Have to put the result before the varargs. */
+ protected void train_format(MessageFormatter formatter, String result, Object... arguments)
{
- expect(messages.format(key, arguments)).andReturn(result);
+ expect(formatter.format(arguments)).andReturn(result);
}
protected final Field newField(String label)
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/ValidForm.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/ValidForm.properties?view=auto&rev=497845
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/ValidForm.properties (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/ValidForm.properties Fri Jan 19 07:39:41 2007
@@ -0,0 +1 @@
+message-required=Please provide a detailed description of the incident.
\ No newline at end of file