package grails.validation; import junit.framework.TestCase; import org.springframework.beans.BeanWrapper; import org.springframework.beans.BeanWrapperImpl; import org.springframework.validation.BindException; import org.springframework.validation.Errors; import org.springframework.validation.FieldError; /** * Abstract class for all constraint tests. * * @author Sergey Nebolsin (<a href="mailto:nebolsin@gmail.com"/>) */ public abstract class AbstractConstraintTests extends TestCase { protected Constraint getConstraint(String field, Object parameter) { Constraint constraint = null; try { constraint = (Constraint) getConstraintClass().newInstance(); } catch (Exception e) { fail("Cannot instantiate constraint class [" + getConstraintClass().getName() + "]"); } constraint.setOwningClass(TestClass.class); constraint.setPropertyName(field); constraint.setParameter(parameter); return constraint; } protected void testConstraintDefaultMessage(Constraint constraint, Object value, String message) { Errors errors = testConstraintFailed(constraint, value); assertEquals(message, errors.getFieldError(constraint.getPropertyName()).getDefaultMessage()); } protected void testConstraintMessageCode(Constraint constraint, Object value, String code) { Errors errors = testConstraintFailed(constraint, value); checkCode(errors.getFieldError(constraint.getPropertyName()), code); } protected void testConstraintMessageCode(Constraint constraint, Object value, String code, Object[] args) { Errors errors = testConstraintFailed(constraint, value); FieldError fieldError = errors.getFieldError(constraint.getPropertyName()); checkCode(fieldError, code); checkArguments(args, fieldError.getArguments()); } protected void testConstraintMessageCodes(Constraint constraint, Object value, String[] code, Object[] args) { Errors errors = testConstraintFailed(constraint, value); FieldError fieldError = errors.getFieldError(constraint.getPropertyName()); for (int j = 0; j < code.length; j++) { checkCode(fieldError, code[j]); } checkArguments(args, fieldError.getArguments()); } protected Errors testConstraintFailed(Constraint constraint, Object value) { Errors errors = validateConstraint(constraint, value); assertEquals(true, errors.hasErrors()); return errors; } protected Errors testConstraintFailedAndVetoed(Constraint constraint, Object value) { Errors errors = validateConstraint(constraint, value, Boolean.TRUE); assertEquals(true, errors.hasErrors()); return errors; } protected void testConstraintPassed(Constraint constraint, Object value) { Errors errors = validateConstraint(constraint, value); assertEquals(false, errors.hasErrors()); } protected void testConstraintPassedAndVetoed(Constraint constraint, Object value) { Errors errors = validateConstraint(constraint, value, Boolean.TRUE); assertEquals(false, errors.hasErrors()); } protected Errors validateConstraint(Constraint constraint, Object value) { return validateConstraint(constraint, value, null); } protected Errors validateConstraint(Constraint constraint, Object value, Boolean shouldVeto) { BeanWrapper constrainedBean = new BeanWrapperImpl(new TestClass()); constrainedBean.setPropertyValue(constraint.getPropertyName(), value); Errors errors = new BindException(constrainedBean.getWrappedInstance(), constrainedBean.getWrappedClass().getName()); if (!(constraint instanceof VetoingConstraint) || shouldVeto == null) { constraint.validate(constrainedBean.getWrappedInstance(), value, errors); } else { boolean vetoed = ((VetoingConstraint) constraint).validateWithVetoing(constrainedBean.getWrappedInstance(), value, errors); if (shouldVeto.booleanValue() && !vetoed) fail("Constraint should veto"); else if (!shouldVeto.booleanValue() && vetoed) fail("Constraint shouldn't veto"); } return errors; } private void checkCode(FieldError error, String code) { String[] codes = error.getCodes(); boolean result = false; for (int i = 0; i < codes.length; i++) { if (code.equals(codes[i])) { result = true; break; } } assertTrue("Code " + code + " is not found in error", result); } private void checkArguments(Object[] left, Object[] right) { assertEquals(left.length, right.length); for (int i = 0; i < left.length; i++) { assertEquals(left[i], right[i]); } } protected abstract Class<?> getConstraintClass(); }