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/31 21:18:52 UTC

svn commit: r501975 [2/2] - in /tapestry/tapestry5/tapestry-core/trunk/src: main/java/org/apache/tapestry/ main/java/org/apache/tapestry/beaneditor/ main/java/org/apache/tapestry/corelib/components/ main/java/org/apache/tapestry/internal/beaneditor/ ma...

Modified: 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=diff&rev=501975&r1=501974&r2=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/MinLength.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/validator/MinLength.java Wed Jan 31 12:18:49 2007
@@ -41,9 +41,9 @@
         return Integer.class;
     }
 
-    public boolean skipIfBlank()
+    public boolean invokeIfBlank()
     {
-        return true;
+        return false;
     }
 
     public Class<String> getValueType()

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=501975&r1=501974&r2=501975
==============================================================================
--- 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 Wed Jan 31 12:18:49 2007
@@ -42,9 +42,9 @@
         return null;
     }
 
-    public boolean skipIfBlank()
+    public boolean invokeIfBlank()
     {
-        return false;
+        return true;
     }
 
     public Class<Object> getValueType()

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/corelib/components/BeanEditor.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/corelib/components/BeanEditor.html?view=auto&rev=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/corelib/components/BeanEditor.html (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/corelib/components/BeanEditor.html Wed Jan 31 12:18:49 2007
@@ -0,0 +1,15 @@
+<form t:type="Form" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" class="t-beaneditor">
+    <t:comp type="Errors"/>
+
+    <div class="t-beaneditor-row" t:type="Loop" t:source="model.propertyNames" t:value="propertyName">
+        <t:comp type="Delegate" to="blockForProperty"/>
+    </div>
+    <div class="t-beaneditor-row">
+        <input type="submit" value="Create/Update"/>
+    </div>
+
+    <t:block id="text">
+        <label t:type="Label" for="textField"/>                
+        <input t:id="textField"/>
+    </t:block>
+</form>

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/InternalStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/InternalStrings.properties?view=diff&rev=501975&r1=501974&r2=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/InternalStrings.properties (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/InternalStrings.properties Wed Jan 31 12:18:49 2007
@@ -1,2 +1,16 @@
+# Copyright 2007 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.
+
 bad-key-value=Key/value pair '%s' is not properly formatted (it does not contain a equals sign).
  

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/beaneditor/BeanEditorStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/beaneditor/BeanEditorStrings.properties?view=auto&rev=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/beaneditor/BeanEditorStrings.properties (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/beaneditor/BeanEditorStrings.properties Wed Jan 31 12:18:49 2007
@@ -0,0 +1,16 @@
+# Copyright 2007 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.
+
+duplicate-property-name=Bean editor model for %s already contains a property model for property '%s'.
+unknown-property=Bean editor model for %s does not contain a property named '%s'.  Available properties: %s.
\ No newline at end of file

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/BeanEditorDemo.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/BeanEditorDemo.html?view=auto&rev=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/BeanEditorDemo.html (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/BeanEditorDemo.html Wed Jan 31 12:18:49 2007
@@ -0,0 +1,10 @@
+<t:comp type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <h1>BeanEditor Component Demo</h1>
+    
+    <t:comp type="BeanEditor" object="registrationData"/>
+       
+       
+    <p>
+        [<a t:type="ActionLink" t:id="clear">Clear Data</a>]
+    </p>        
+</t:comp>
\ No newline at end of file

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/ViewRegistration.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/ViewRegistration.html?view=auto&rev=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/ViewRegistration.html (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/ViewRegistration.html Wed Jan 31 12:18:49 2007
@@ -0,0 +1,10 @@
+<t:comp type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <h1>BeanEdit Component Demo</h1>
+    
+First Name: [${registrationData.firstName}]
+<br/>
+Last Name: [${registrationData.lastName}]
+<br/>
+Birth year: [${registrationData.birthYear}]
+    
+</t:comp>
\ No newline at end of file

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html?view=diff&rev=501975&r1=501974&r2=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html Wed Jan 31 12:18:49 2007
@@ -93,6 +93,9 @@
                         <li>
                             <a href="FlashDemo">FlashDemo</a> -- demonstrate "flash" persistence
                         </li>
+                        <li>
+                            <a href="beaneditordemo">BeanEditor Demo</a> -- demonstrate the BeanEditor mega-component
+                        </li>
                     </ul>
                 </td>
             </tr>

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml?view=diff&rev=501975&r1=501974&r2=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml Wed Jan 31 12:18:49 2007
@@ -26,7 +26,7 @@
       <package name="org.apache.tapestry.dom"/>
       <package name="org.apache.internal"/>
       <package name="org.apache.tapestry.internal"/>
-      <package name="org.apache.tapestry.internal.aspects"/>
+      <package name="org.apache.tapestry.internal.beaneditor"/>
       <package name="org.apache.tapestry.internal.services"/>
       <package name="org.apache.tapestry.internal.structure"/>
       <package name="org.apache.tapestry.internal.util"/>

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=501975&r1=501974&r2=501975
==============================================================================
--- 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 Wed Jan 31 12:18:49 2007
@@ -614,15 +614,18 @@
         throw new AssertionError(String.format("%s was '%s' not '%s'", locator, actual, expected));
     }
 
-    private void assertTextPresent(String text)
+    private void assertTextPresent(String... text)
     {
-        if (_selenium.isTextPresent(text))
-            return;
+        for (String item : text)
+        {
+            if (_selenium.isTextPresent(item))
+                return;
 
-        System.err.printf("Text pattern '%s' not found in:\n%s\n\n", text, _selenium
-                .getHtmlSource());
+            System.err.printf("Text pattern '%s' not found in:\n%s\n\n", item, _selenium
+                    .getHtmlSource());
 
-        throw new AssertionError("Page did not contain '" + text + "'.");
+            throw new AssertionError("Page did not contain '" + item + "'.");
+        }
     }
 
     private void assertValue(String locator, String expected)
@@ -691,5 +694,42 @@
         assertValue("title_0", "Eliminate JSF - immediately");
         assertValue("title_1", "Conquer Rife - post haste");
         assertValue("title_2", "Conquer World");
+    }
+
+    /**
+     * Tests the bean editor. Along the way, tests a bunch about validation, loops, blocks, and
+     * application state objects.
+     */
+    @Test
+    public void bean_editor()
+    {
+        String submitButton = "//input[@value='Create/Update']";
+
+        _selenium.open(BASE_URL);
+        clickAndWait("link=BeanEditor Demo");
+        clickAndWait(submitButton);
+        assertTextPresent(
+                "You must provide a value for First Name.",
+                "Everyone has to have last name!",
+                "Year of Birth requires a value of at least 1900.");
+
+        _selenium.type("textField", "a");
+        _selenium.type("textField_0", "b");
+        _selenium.type("textField_1", "");
+
+        clickAndWait(submitButton);
+
+        assertTextPresent(
+                "You must provide at least 3 characters for First Name.",
+                "You must provide at least 5 characters for Last Name.",
+                "You must provide a value for Year of Birth.");
+
+        _selenium.type("textField", "Howard");
+        _selenium.type("textField_0", "Lewis Ship");
+        _selenium.type("textField_1", "1966");
+
+        clickAndWait(submitButton);
+
+        assertTextPresent("[Howard]", "[Lewis Ship]", "[1966]");
     }
 }

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/data/RegistrationData.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/data/RegistrationData.java?view=auto&rev=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/data/RegistrationData.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/data/RegistrationData.java Wed Jan 31 12:18:49 2007
@@ -0,0 +1,63 @@
+// Copyright 2007 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.integration.app1.data;
+
+import org.apache.tapestry.beaneditor.Order;
+import org.apache.tapestry.beaneditor.Validate;
+
+public class RegistrationData
+{
+    private String _lastName;
+
+    private String _firstName;
+
+    private int _birthYear;
+
+    @Order(300)
+    @Validate("min=1900,max=2007")
+    public int getBirthYear()
+    {
+        return _birthYear;
+    }
+
+    public void setBirthYear(int birthYear)
+    {
+        _birthYear = birthYear;
+    }
+
+    public String getFirstName()
+    {
+        return _firstName;
+    }
+
+    @Order(100)
+    @Validate("required,minlength=3")
+    public void setFirstName(String firstName)
+    {
+        _firstName = firstName;
+    }
+
+    @Validate("required,minlength=5")
+    public String getLastName()
+    {
+        return _lastName;
+    }
+
+    @Order(200)
+    public void setLastName(String lastName)
+    {
+        _lastName = lastName;
+    }
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditorDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditorDemo.java?view=auto&rev=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditorDemo.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditorDemo.java Wed Jan 31 12:18:49 2007
@@ -0,0 +1,41 @@
+// Copyright 2007 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.integration.app1.pages;
+
+import org.apache.tapestry.annotations.ApplicationState;
+import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.integration.app1.data.RegistrationData;
+
+@ComponentClass
+public class BeanEditorDemo
+{
+    @ApplicationState
+    private RegistrationData _data;
+
+    public RegistrationData getRegistrationData()
+    {
+        return _data;
+    }
+
+    String onSuccess()
+    {
+        return "ViewRegistration";
+    }
+    
+    void onActionFromClear()
+    {
+        _data = null;
+    }
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/ViewRegistration.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/ViewRegistration.java?view=auto&rev=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/ViewRegistration.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/ViewRegistration.java Wed Jan 31 12:18:49 2007
@@ -0,0 +1,31 @@
+// Copyright 2007 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.integration.app1.pages;
+
+import org.apache.tapestry.annotations.ApplicationState;
+import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.integration.app1.data.RegistrationData;
+
+@ComponentClass
+public class ViewRegistration
+{
+    @ApplicationState
+    private RegistrationData _data;
+
+    public RegistrationData getRegistrationData()
+    {
+        return _data;
+    }
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/beaneditor/ValidateAnnotationConstraintGeneratorTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/beaneditor/ValidateAnnotationConstraintGeneratorTest.java?view=auto&rev=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/beaneditor/ValidateAnnotationConstraintGeneratorTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/beaneditor/ValidateAnnotationConstraintGeneratorTest.java Wed Jan 31 12:18:49 2007
@@ -0,0 +1,92 @@
+// Copyright 2007 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.internal.beaneditor;
+
+import java.util.Arrays;
+
+import org.apache.tapestry.beaneditor.PropertyConduit;
+import org.apache.tapestry.beaneditor.PropertyEditModel;
+import org.apache.tapestry.beaneditor.Validate;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.ValidationConstraintGenerator;
+import org.testng.annotations.Test;
+
+public class ValidateAnnotationConstraintGeneratorTest extends InternalBaseTestCase
+{
+    @Test
+    public void no_annotation()
+    {
+        PropertyEditModel model = newPropertyEditModel();
+        PropertyConduit conduit = newPropertyConduit();
+
+        train_getConduit(model, conduit);
+        train_getAnnotation(conduit, Validate.class, null);
+
+        replay();
+
+        ValidationConstraintGenerator gen = new ValidateAnnotationConstraintGenerator();
+
+        assertNull(gen.buildConstraints(model));
+
+        verify();
+    }
+
+    @Test
+    public void single_constraint()
+    {
+        PropertyEditModel model = newPropertyEditModel();
+        PropertyConduit conduit = newPropertyConduit();
+        Validate validate = newValidate("required");
+
+        train_getConduit(model, conduit);
+        train_getAnnotation(conduit, Validate.class, validate);
+
+        replay();
+
+        ValidationConstraintGenerator gen = new ValidateAnnotationConstraintGenerator();
+
+        assertEquals(gen.buildConstraints(model), Arrays.asList("required"));
+
+        verify();
+    }
+
+    @Test
+    public void multiple_constraints()
+    {
+        PropertyEditModel model = newPropertyEditModel();
+        PropertyConduit conduit = newPropertyConduit();
+        Validate validate = newValidate("required,minlength=3");
+
+        train_getConduit(model, conduit);
+        train_getAnnotation(conduit, Validate.class, validate);
+
+        replay();
+
+        ValidationConstraintGenerator gen = new ValidateAnnotationConstraintGenerator();
+
+        assertEquals(gen.buildConstraints(model), Arrays.asList("required", "minlength=3"));
+
+        verify();
+    }
+
+    private Validate newValidate(String value)
+    {
+        Validate annotation = newMock(Validate.class);
+
+        expect(annotation.value()).andReturn(value).atLeastOnce();
+
+        return annotation;
+    }
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/BeanEditorModelSourceImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/BeanEditorModelSourceImplTest.java?view=auto&rev=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/BeanEditorModelSourceImplTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/BeanEditorModelSourceImplTest.java Wed Jan 31 12:18:49 2007
@@ -0,0 +1,253 @@
+// Copyright 2007 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.internal.services;
+
+import java.util.Arrays;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.beaneditor.BeanEditorModel;
+import org.apache.tapestry.beaneditor.PropertyConduit;
+import org.apache.tapestry.beaneditor.PropertyEditModel;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.services.BeanEditorModelSource;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/** Tests for the bean editor model source itself, as well as the model classes. */
+public class BeanEditorModelSourceImplTest extends InternalBaseTestCase
+{
+    private BeanEditorModelSource _source;
+
+    @BeforeClass
+    public void setup()
+    {
+        _source = getObject("infrastructure:BeanEditorModelSource", BeanEditorModelSource.class);
+    }
+
+    @AfterClass
+    public void cleanup()
+    {
+        _source = null;
+    }
+
+    /** Tests defaults for property names, labels and conduits. */
+    @Test
+    public void default_model_for_bean()
+    {
+        ComponentResources resources = newComponentResources();
+        Messages messages = newMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanEditorModel model = _source.create(SimpleBean.class, resources);
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("age", "firstName", "lastName"));
+
+        assertEquals(model.get("age").getLabel(), "Age");
+        assertSame(model.get("age").getPropertyType(), int.class);
+
+        assertEquals(model.get("firstName").getLabel(), "First Name");
+        assertEquals(model.get("firstName").getPropertyType(), String.class);
+
+        assertEquals(model.get("lastName").getLabel(), "Last Name");
+
+        PropertyConduit conduit = model.get("lastName").getConduit();
+
+        SimpleBean instance = new SimpleBean();
+
+        instance.setLastName("Lewis Ship");
+
+        assertEquals(conduit.read(instance), "Lewis Ship");
+
+        conduit.write(instance, "TapestryDude");
+
+        assertEquals(instance.getLastName(), "TapestryDude");
+
+        // Now, one with some type coercion.
+
+        model.get("age").getConduit().write(instance, "40");
+
+        assertEquals(instance.getAge(), 40);
+
+        verify();
+    }
+
+    @Test
+    public void add_duplicate_property_name_is_failure()
+    {
+        ComponentResources resources = newComponentResources();
+        Messages messages = newMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanEditorModel model = _source.create(SimpleBean.class, resources);
+
+        try
+        {
+            model.add("age");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Bean editor model for org.apache.tapestry.internal.services.SimpleBean already contains a property model for property \'age\'.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void unknown_property_name()
+    {
+        ComponentResources resources = newComponentResources();
+        Messages messages = newMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanEditorModel model = _source.create(SimpleBean.class, resources);
+
+        try
+        {
+            model.get("frobozz");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Bean editor model for org.apache.tapestry.internal.services.SimpleBean does not contain a property named \'frobozz\'.  "
+                            + "Available properties: age, firstName, lastName.");
+        }
+
+        verify();
+    }
+
+    /**
+     * You can add anything you like as a property, but you'll have to fill in details such as type
+     * and conduit.
+     */
+    @Test
+    public void default_values_for_missing_property()
+    {
+        ComponentResources resources = newComponentResources();
+        Messages messages = newMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanEditorModel model = _source.create(SimpleBean.class, resources);
+
+        PropertyEditModel pm = model.add("frobozz");
+
+        assertEquals(pm.getLabel(), "Frobozz");
+        assertEquals(pm.getOrder(), 0);
+        assertNull(pm.getConduit());
+        assertSame(pm.getPropertyType(), Object.class);
+
+        verify();
+    }
+
+    @Test
+    public void order_via_annotation()
+    {
+        ComponentResources resources = newComponentResources();
+        Messages messages = newMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanEditorModel model = _source.create(StoogeBean.class, resources);
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("larry", "moe", "shemp", "curly"));
+
+        verify();
+    }
+
+    @Test
+    public void edit_property_label()
+    {
+        ComponentResources resources = newComponentResources();
+        Messages messages = newMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanEditorModel model = _source.create(SimpleBean.class, resources).get("age").label(
+                "Decrepitude").model();
+
+        assertEquals(model.get("age").getLabel(), "Decrepitude");
+
+        verify();
+    }
+
+    @Test
+    public void label_from_component_messages()
+    {
+        ComponentResources resources = newComponentResources();
+        Messages messages = newMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        train_contains(messages, "age-label", true);
+        train_get(messages, "age-label", "Decrepitude");
+
+        replay();
+
+        BeanEditorModel model = _source.create(SimpleBean.class, resources);
+
+        assertEquals(model.get("age").getLabel(), "Decrepitude");
+
+        verify();
+    }
+
+    @Test
+    public void override_conduit()
+    {
+        ComponentResources resources = newComponentResources();
+        Messages messages = newMessages();
+        PropertyConduit conduit = newMock(PropertyConduit.class);
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanEditorModel model = _source.create(SimpleBean.class, resources).get("age").conduit(
+                conduit).model();
+
+        assertSame(model.get("age").getConduit(), conduit);
+
+        verify();
+    }
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/FieldValidatorImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/FieldValidatorImplTest.java?view=diff&rev=501975&r1=501974&r2=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/FieldValidatorImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/FieldValidatorImplTest.java Wed Jan 31 12:18:49 2007
@@ -34,7 +34,7 @@
         MessageFormatter formatter = newMessageFormatter();
         Validator validator = newValidator();
 
-        train_skipIfBlank(validator, true);
+        train_invokeIfBlank(validator, false);
 
         replay();
 
@@ -53,7 +53,7 @@
         MessageFormatter formatter = newMessageFormatter();
         Validator validator = newValidator();
 
-        train_skipIfBlank(validator, true);
+        train_invokeIfBlank(validator, false);
 
         replay();
 
@@ -73,7 +73,7 @@
         Validator validator = newValidator();
         Integer value = 15;
 
-        train_skipIfBlank(validator, true);
+        train_invokeIfBlank(validator, true);
         train_getValueType(validator, String.class);
 
         replay();
@@ -93,7 +93,7 @@
         MessageFormatter formatter = newMessageFormatter();
         Validator validator = newValidator();
 
-        train_skipIfBlank(validator, false);
+        train_invokeIfBlank(validator, true);
 
         validator.validate(field, null, formatter, null);
 

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=501975&r1=501974&r2=501975
==============================================================================
--- 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 Wed Jan 31 12:18:49 2007
@@ -49,9 +49,17 @@
         Validator validator = newValidator();
         TypeCoercer coercer = newTypeCoercer();
         FieldComponent field = newFieldComponent();
-
+        ComponentResources resources = newComponentResources();
+        ComponentResources containerResources = newComponentResources();
+        Messages containerMessages = newMessages();
         Map<String, Validator> map = newMap();
 
+        train_getComponentResources(field, resources);
+        train_getId(resources, "fred");
+        train_getLocale(resources, Locale.ENGLISH);
+        train_getContainerResources(resources, containerResources);
+        train_getMessages(containerResources, containerMessages);
+
         map.put("alpha", validator);
         map.put("beta", validator);
 
@@ -107,7 +115,7 @@
         train_getMessageKey(validator, "key");
         train_getMessageFormatter(messages, "key", formatter);
 
-        train_skipIfBlank(validator, true);
+        train_invokeIfBlank(validator, false);
         train_getValueType(validator, Object.class);
         validator.validate(field, null, formatter, inputValue);
 
@@ -142,13 +150,14 @@
 
         train_getComponentResources(field, resources);
         train_getId(resources, "fred");
+        train_getLocale(resources, Locale.ENGLISH);
         train_getContainerResources(resources, containerResources);
         train_getMessages(containerResources, componentMessages);
         train_contains(componentMessages, "fred-required", true);
 
         train_getMessageFormatter(componentMessages, "fred-required", formatter);
 
-        train_skipIfBlank(validator, true);
+        train_invokeIfBlank(validator, false);
         train_getValueType(validator, Object.class);
         validator.validate(field, null, formatter, inputValue);
 
@@ -195,7 +204,7 @@
         train_getMessageKey(validator, "key");
         train_getMessageFormatter(messages, "key", formatter);
 
-        train_skipIfBlank(validator, true);
+        train_invokeIfBlank(validator,false);
         train_getValueType(validator, Object.class);
         validator.validate(field, null, formatter, inputValue);
 
@@ -256,11 +265,11 @@
 
         train_coerce(coercer, "15", Integer.class, fifteen);
 
-        train_skipIfBlank(required, false);
+        train_invokeIfBlank(required, true);
         train_getValueType(required, Object.class);
         required.validate(field, null, requiredFormatter, inputValue);
 
-        train_skipIfBlank(minLength, true);
+        train_invokeIfBlank(minLength, false);
         train_getValueType(minLength, String.class);
         minLength.validate(field, fifteen, minLengthFormatter, inputValue);
 
@@ -310,7 +319,7 @@
         train_getMessageKey(validator, "key");
         train_getMessageFormatter(messages, "key", formatter);
 
-        train_skipIfBlank(validator, true);
+        train_invokeIfBlank(validator, false);
         train_getValueType(validator, Object.class);
         validator.validate(field, five, formatter, inputValue);
 

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/SimpleBean.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/SimpleBean.java?view=auto&rev=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/SimpleBean.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/SimpleBean.java Wed Jan 31 12:18:49 2007
@@ -0,0 +1,55 @@
+// Copyright 2007 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.internal.services;
+
+public class SimpleBean
+{
+    private String _firstName;
+
+    private String _lastName;
+
+    private int _age;
+
+    public int getAge()
+    {
+        return _age;
+    }
+
+    public void setAge(int age)
+    {
+        _age = age;
+    }
+
+    public String getFirstName()
+    {
+        return _firstName;
+    }
+
+    public void setFirstName(String firstName)
+    {
+        _firstName = firstName;
+    }
+
+    public String getLastName()
+    {
+        return _lastName;
+    }
+
+    public void setLastName(String lastName)
+    {
+        _lastName = lastName;
+    }
+
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/StoogeBean.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/StoogeBean.java?view=auto&rev=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/StoogeBean.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/StoogeBean.java Wed Jan 31 12:18:49 2007
@@ -0,0 +1,65 @@
+// Copyright 2007 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.internal.services;
+
+import org.apache.tapestry.beaneditor.Order;
+
+public class StoogeBean
+{
+    private int _moe, _larry, _curly, _shemp;
+
+    @Order(100)
+    public int getCurly()
+    {
+        return _curly;
+    }
+
+    public void setCurly(int curly)
+    {
+        _curly = curly;
+    }
+
+    public int getLarry()
+    {
+        return _larry;
+    }
+
+    @Order(-1)
+    public void setLarry(int larry)
+    {
+        _larry = larry;
+    }
+
+    public int getMoe()
+    {
+        return _moe;
+    }
+
+    public void setMoe(int moe)
+    {
+        _moe = moe;
+    }
+
+    public int getShemp()
+    {
+        return _shemp;
+    }
+
+    public void setShemp(int shemp)
+    {
+        _shemp = shemp;
+    }
+
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/util/NotificationEventHandlerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/util/NotificationEventHandlerTest.java?view=auto&rev=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/util/NotificationEventHandlerTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/util/NotificationEventHandlerTest.java Wed Jan 31 12:18:49 2007
@@ -0,0 +1,83 @@
+// Copyright 2007 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.internal.util;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.runtime.Component;
+import org.testng.annotations.Test;
+
+public class NotificationEventHandlerTest extends InternalBaseTestCase
+{
+    private static final String EVENT_TYPE = "myEventType";
+
+    private static final String COMPLETE_ID = "foo.bar.baz";
+
+    private static final String METHOD = "foo.components.Baz.bar()";
+
+    @Test
+    public void true_is_allowed()
+    {
+        Component component = newComponent();
+
+        replay();
+
+        NotificationEventHandler handler = new NotificationEventHandler(EVENT_TYPE, COMPLETE_ID);
+
+        assertTrue(handler.handleResult(Boolean.TRUE, component, METHOD));
+
+        verify();
+    }
+
+    @Test
+    public void false_is_allowed()
+    {
+        Component component = newComponent();
+
+        replay();
+
+        NotificationEventHandler handler = new NotificationEventHandler(EVENT_TYPE, COMPLETE_ID);
+
+        assertFalse(handler.handleResult(Boolean.FALSE, component, METHOD));
+
+        verify();
+    }
+
+    @Test
+    public void other_values_force_exception()
+    {
+        Component component = newComponent();
+        String result = "*RESULT*";
+
+        replay();
+
+        NotificationEventHandler handler = new NotificationEventHandler(EVENT_TYPE, COMPLETE_ID);
+
+        try
+        {
+            handler.handleResult(result, component, METHOD);
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Event 'myEventType' from foo.bar.baz received an event handler method return value of *RESULT* from foo.components.Baz.bar(). "
+                            + "This type of event does not support return values from event handler methods.");
+        }
+
+        verify();
+    }
+
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/log4j.properties?view=diff&rev=501975&r1=501974&r2=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/log4j.properties (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/log4j.properties Wed Jan 31 12:18:49 2007
@@ -28,7 +28,4 @@
 
 log4j.category.app=info
 log4j.category.org.apache.tapestry.integration.app1=error
-log4j.category.org.apache.tapestry.corelib=error
-
-log4j.category.org.apache.tapestry.integration.app1.pages.ToDoList=debug
-
+log4j.category.org.apache.tapestry.corelib=error

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/BeanEditorDemo.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/BeanEditorDemo.properties?view=auto&rev=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/BeanEditorDemo.properties (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/BeanEditorDemo.properties Wed Jan 31 12:18:49 2007
@@ -0,0 +1,16 @@
+# Copyright 2007 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.
+
+birthYear-label=Year of Birth
+lastName-required=Everyone has to have last name!
\ No newline at end of file

Modified: 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=diff&rev=501975&r1=501974&r2=501975
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/ValidForm.properties (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/ValidForm.properties Wed Jan 31 12:18:49 2007
@@ -1 +1,15 @@
+# Copyright 2007 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.
+
 message-required=Please provide a detailed description of the incident.