package org.grails.validation; import grails.validation.AbstractConstraintTests; import grails.validation.ConstrainedProperty; import grails.validation.Constraint; import grails.validation.TestClass; import groovy.lang.GroovyShell; /** * Test cases for custom 'validator' constraint. * * @author Sergey Nebolsin (<a href="mailto:nebolsin@gmail.com"/>) */ public class ValidatorConstraintTests extends AbstractConstraintTests { private static final String PROP_NAME = "firstName"; private GroovyShell shell = new GroovyShell(); @Override protected Class<?> getConstraintClass() { return ValidatorConstraint.class; } protected Constraint getConstraint(String closure) { return super.getConstraint("testString", shell.evaluate(closure)); } public void testBooleanReturn() { testConstraintMessageCodes( getConstraint("{val,obj -> return false}"), "test", new String[] { "testClass.testString.validator.error","testClass.testString.validator.invalid"}, new Object[] { "testString", TestClass.class, "test" }); testConstraintPassed( getConstraint("{val,obj -> return true}"), "test"); testConstraintDefaultMessage( getConstraint("{val,obj -> return false}"), "test", "Property [{0}] of class [{1}] with value [{2}] does not pass custom validation"); // Test null and blank values. testConstraintFailed( getConstraint("{val,obj -> return val == null}"), "test"); testConstraintPassed( getConstraint("{val,obj -> return val == null}"), null); testConstraintFailed( getConstraint("{val,obj -> return val?.trim() == ''}"), "test"); testConstraintPassed( getConstraint("{val,obj -> return val?.trim() == ''}"), " "); } public void testStringReturn() { testConstraintMessageCode( getConstraint("{val,obj -> return 'test.message'}"), "test", "testClass.testString.test.message", new Object[] { "testString", TestClass.class, "test" }); try { testConstraintFailed( getConstraint("{val,obj -> return 123L}"), "test"); fail("Validator constraint must throw an exception about wrong closure return"); } catch (IllegalArgumentException iae) { // Greate } } public void testListReturn() { testConstraintMessageCode( getConstraint("{val,obj -> return ['test.message', 'arg', 123L]}"), "test", "testClass.testString.test.message", new Object[] { "testString", TestClass.class, "test", "arg", 123L }); try { testConstraintFailed( getConstraint("{val,obj -> return [123L,'arg1','arg2']}"), "test"); fail("Validator constraint must throw an exception about wrong closure return"); } catch (IllegalArgumentException iae) { // Greate } } /** * Tests that the delegate that provides access to the name of the * constrained property is available to custom validators. */ public void testDelegate() { testConstraintPassed( getConstraint("{val, obj -> return propertyName == 'testString'}"), "test"); } public void testConstraintCreation() { Constraint validatorConstraint = new ValidatorConstraint(); assertEquals(ConstrainedProperty.VALIDATOR_CONSTRAINT, validatorConstraint.getName()); assertTrue(validatorConstraint.supports(TestClass.class)); assertFalse(validatorConstraint.supports(null)); validatorConstraint.setOwningClass(TestClass.class); validatorConstraint.setPropertyName(PROP_NAME); try { getConstraint("testString", "Test"); fail("ValidatorConstraint must throw an exception for non-closure parameter."); } catch (IllegalArgumentException iae) { // Great since validator constraint only applicable for Closure parameter } try { getConstraint("{ param1, param2, param3, param4 -> return true}"); fail("ValidatorConstraint must throw exception about closure with more that 3 params"); } catch (IllegalArgumentException iae) { // Great since validator constraint only applicable for Closure's with 1, 2 or 3 params } } }