/******************************************************************************* * Copyright (c) 2007, 2014 compeople AG and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * compeople AG - initial API and implementation *******************************************************************************/ package org.eclipse.riena.internal.ui.ridgets.swt; import static org.eclipse.riena.ui.ridgets.IDateTimeRidget.*; import java.beans.PropertyChangeEvent; import java.util.Calendar; import java.util.Date; import java.util.Locale; import org.eclipse.core.databinding.validation.IValidator; import org.eclipse.core.databinding.validation.ValidationStatus; import org.eclipse.core.runtime.IStatus; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.DateTime; import org.eclipse.riena.beans.common.TypedBean; import org.eclipse.riena.core.marker.AbstractMarker; import org.eclipse.riena.internal.ui.swt.test.UITestHelper; import org.eclipse.riena.internal.ui.swt.utils.TestUtils; import org.eclipse.riena.ui.core.marker.ValidationTime; import org.eclipse.riena.ui.ridgets.IDateTimeRidget; import org.eclipse.riena.ui.ridgets.IRidget; import org.eclipse.riena.ui.ridgets.swt.uibinding.SwtControlRidgetMapper; /** * Tests for the class {@link DateTextRidget}. */ public class DateTimeRidgetTest extends AbstractSWTRidgetTest { @Override protected IRidget createRidget() { return new DateTimeRidget(); } @Override protected IDateTimeRidget getRidget() { return (IDateTimeRidget) super.getRidget(); } @Override protected Control createWidget(final Composite parent) { return new DateTime(getShell(), SWT.DATE | SWT.MEDIUM); } @Override protected DateTime getWidget() { return (DateTime) super.getWidget(); } // test methods /////////////// public void testRidgetMapping() { final SwtControlRidgetMapper mapper = SwtControlRidgetMapper.getInstance(); assertSame(DateTimeRidget.class, mapper.getRidgetClass(getWidget())); } public void testSetDate() { final IDateTimeRidget ridget = getRidget(); final DateTime control = getWidget(); final TypedBean<Date> dateBean = new TypedBean<Date>(Date.class); expectNoPropertyChangeEvent(); ridget.bindToModel(dateBean, TypedBean.PROP_VALUE); verifyPropertyChangeEvents(); assertEquals(null, ridget.getDate()); assertEquals(null, dateBean.getValue()); final Date date2001 = createDate(2001, 12, 2); expectPropertyChangeEvents(new PropertyChangeEvent(ridget, "dateInternal", null, date2001), new PropertyChangeEvent(ridget, IDateTimeRidget.PROPERTY_DATE, null, date2001)); ridget.setDate(date2001); verifyPropertyChangeEvents(); assertEquals(date2001, ridget.getDate()); assertEquals(date2001, dateBean.getValue()); assertEquals("12/2/2001", getDate(control)); final Date date1800 = createDate(1800, 1, 1); expectPropertyChangeEvents(new PropertyChangeEvent(ridget, "dateInternal", date2001, date1800), new PropertyChangeEvent(ridget, IDateTimeRidget.PROPERTY_DATE, date2001, date1800)); ridget.setDate(date1800); verifyPropertyChangeEvents(); assertEquals(date1800, ridget.getDate()); assertEquals(date1800, dateBean.getValue()); assertEquals("1/1/1800", getDate(control)); } public void testSetDateNull() { final IDateTimeRidget ridget = getRidget(); final DateTime control = getWidget(); final TypedBean<Date> dateBean = new TypedBean<Date>(new Date()); ridget.bindToModel(dateBean, TypedBean.PROP_VALUE); ridget.updateFromModel(); ridget.setDate(null); assertEquals(null, ridget.getDate()); assertEquals(asStringEmptyDate(), getDate(control)); assertEquals(null, dateBean.getValue()); } public void testUpdateFromModel() { final IDateTimeRidget ridget = getRidget(); final DateTime control = getWidget(); final Date date2000 = createDate(2000, 1, 1); final Date date2001 = createDate(2001, 12, 2); final TypedBean<Date> dateBean = new TypedBean<Date>(date2000); ridget.bindToModel(dateBean, TypedBean.PROP_VALUE); assertEquals(null, ridget.getDate()); assertEquals(asStringEmptyDate(), getDate(control)); expectPropertyChangeEvents(new PropertyChangeEvent(ridget, "dateInternal", null, date2000), new PropertyChangeEvent(ridget, IDateTimeRidget.PROPERTY_DATE, null, date2000)); ridget.updateFromModel(); verifyPropertyChangeEvents(); assertEquals(date2000, ridget.getDate()); assertEquals("1/1/2000", getDate(control)); expectNoPropertyChangeEvent(); dateBean.setValue(date2001); verifyPropertyChangeEvents(); assertEquals(date2000, ridget.getDate()); assertEquals("1/1/2000", getDate(control)); expectPropertyChangeEvents(new PropertyChangeEvent(ridget, "dateInternal", date2000, date2001), new PropertyChangeEvent(ridget, IDateTimeRidget.PROPERTY_DATE, date2000, date2001)); ridget.updateFromModel(); verifyPropertyChangeEvents(); assertEquals(date2001, ridget.getDate()); assertEquals("12/2/2001", getDate(control)); expectPropertyChangeEvents(new PropertyChangeEvent(ridget, "dateInternal", date2001, null), new PropertyChangeEvent(ridget, IDateTimeRidget.PROPERTY_DATE, date2001, null)); dateBean.setValue(null); ridget.updateFromModel(); verifyPropertyChangeEvents(); assertEquals(null, ridget.getDate()); assertEquals(asStringEmptyDate(), getDate(control)); } public void testWidgetModification() { final PropertyChangeEvent[] events = new PropertyChangeEvent[6]; String input; final String country = Locale.getDefault().getCountry(); if ("DE".equals(country)) { events[0] = createPropertyChangeEvent("dateInternal", 2001, 12, 1, 2001, 12, 10); events[1] = createPropertyChangeEvent(PROPERTY_DATE, 2001, 12, 1, 2001, 12, 10); events[2] = createPropertyChangeEvent("dateInternal", 2001, 12, 10, 2001, 04, 10); events[3] = createPropertyChangeEvent(PROPERTY_DATE, 2001, 12, 10, 2001, 04, 10); events[4] = createPropertyChangeEvent("dateInternal", 2001, 04, 10, 2009, 04, 10); events[5] = createPropertyChangeEvent(PROPERTY_DATE, 2001, 04, 10, 2009, 04, 10); input = "10.04.2009"; } else if ("US".equals(country)) { events[0] = createPropertyChangeEvent("dateInternal", 2001, 12, 1, 2001, 4, 1); events[1] = createPropertyChangeEvent(PROPERTY_DATE, 2001, 12, 1, 2001, 4, 1); events[2] = createPropertyChangeEvent("dateInternal", 2001, 4, 1, 2001, 4, 10); events[3] = createPropertyChangeEvent(PROPERTY_DATE, 2001, 4, 1, 2001, 4, 10); events[4] = createPropertyChangeEvent("dateInternal", 2001, 4, 10, 2009, 4, 10); events[5] = createPropertyChangeEvent(PROPERTY_DATE, 2001, 4, 10, 2009, 4, 10); input = "04/10/2009"; } else { System.out.println("Skipping DateTimeRidgetTest#testWidgetModification()"); return; } final IDateTimeRidget ridget = getRidget(); final DateTime control = getWidget(); final Date date2001 = createDate(2001, 12, 1); final TypedBean<Date> dateBean = new TypedBean<Date>(date2001); ridget.bindToModel(dateBean, TypedBean.PROP_VALUE); ridget.updateFromModel(); // ridget.addPropertyChangeListener(new PropertyChangeListener() { // public void propertyChange(PropertyChangeEvent evt) { // System.out.println(String.format("%s: %s -> %s", evt.getPropertyName(), evt.getOldValue(), evt // .getNewValue())); // } // }); assertEquals(date2001, ridget.getDate()); assertEquals(date2001, dateBean.getValue()); expectPropertyChangeEvents(events); control.setFocus(); UITestHelper.sendString(control.getDisplay(), input); verifyPropertyChangeEvents(); assertEquals("4/10/2009", asString(ridget.getDate())); assertEquals("4/10/2009", asString(dateBean.getValue())); } public void testMandatoryMarker() { final IDateTimeRidget ridget = getRidget(); ridget.setMandatory(true); assertTrue(ridget.isDisableMandatoryMarker()); TestUtils.assertMandatoryMarker(ridget, 1, true); } public void testControlEnablement() { final IDateTimeRidget ridget = getRidget(); final DateTime control = getWidget(); assertTrue(control.isEnabled()); ridget.setEnabled(false); assertFalse(control.isEnabled()); ridget.setEnabled(true); assertTrue(control.isEnabled()); ridget.setOutputOnly(true); ridget.setEnabled(false); ridget.setEnabled(true); assertFalse(control.isEnabled()); ridget.setEnabled(false); ridget.setOutputOnly(false); assertFalse(control.isEnabled()); ridget.setEnabled(true); assertTrue(control.isEnabled()); } public void testValidationUpdateFromModelOnUpdateRules() { handleValidationUpdateFromModel(ValidationTime.ON_UPDATE_TO_MODEL); } public void testValidationUpdateFromModelOnEditRules() { handleValidationUpdateFromModel(ValidationTime.ON_UI_CONTROL_EDIT); } public void testValidationSetDateOnUpdateRules() { handleValidationSetDate(ValidationTime.ON_UPDATE_TO_MODEL); } public void testValidationSetDateOnEditRules() { handleValidationSetDate(ValidationTime.ON_UI_CONTROL_EDIT); } public void testValidationWidgetModificationOnUpdateRules() { final String country = Locale.getDefault().getCountry(); if ("DE".equals(country)) { handleValidationWidgetModification(ValidationTime.ON_UPDATE_TO_MODEL, "10.04.2009"); } else if ("US".equals(country)) { handleValidationWidgetModification(ValidationTime.ON_UPDATE_TO_MODEL, "04/10/2009"); } else { System.out.println("Skipping DateTimeRidgetTest#testValidation_WidgetModification_onUpdateRules"); } } public void testValidationWidgetModificationOnEditRules() { final String country = Locale.getDefault().getCountry(); if ("DE".equals(country)) { handleValidationWidgetModification(ValidationTime.ON_UI_CONTROL_EDIT, "10.04.2009"); } else if ("US".equals(country)) { handleValidationWidgetModification(ValidationTime.ON_UI_CONTROL_EDIT, "04/10/2009"); } else { System.out.println("Skipping DateTimeRidgetTest#testValidation_WidgetModification_OnEditRules"); } } public void testRevalidate() { final IDateTimeRidget ridget = getRidget(); final FTValidator validator = new FTValidator(new Date(99)); ridget.addValidationRule(validator, ValidationTime.ON_UPDATE_TO_MODEL); ridget.setDate(new Date(99)); assertTrue(ridget.isErrorMarked()); ridget.removeValidationRule(validator); assertFalse(ridget.isErrorMarked()); // since 1.2: remove updates immediately ridget.revalidate(); assertFalse(ridget.isErrorMarked()); } // helping methods ////////////////// private String asString(final Date date) { String result = "null"; if (date != null) { final Calendar cal = Calendar.getInstance(); cal.clear(); cal.setTime(date); final int year = cal.get(Calendar.YEAR); final int month = cal.get(Calendar.MONTH) + 1; final int day = cal.get(Calendar.DAY_OF_MONTH); result = String.format("%s/%s/%s", month, day, year); } return result; } private String asStringEmptyDate() { return asString(new Date(0)); } private Date createDate(final int year, final int month, final int day) { final Calendar cal = Calendar.getInstance(); cal.clear(); cal.set(year, month - 1, day, 0, 0); cal.set(Calendar.MILLISECOND, 0); return cal.getTime(); } private PropertyChangeEvent createPropertyChangeEvent(final String propertyName, final int oldYear, final int oldMonth, final int oldDay, final int newYear, final int newMonth, final int newDay) { final Date oldDate = createDate(oldYear, oldMonth, oldDay); final Date newDate = createDate(newYear, newMonth, newDay); return new PropertyChangeEvent(getRidget(), propertyName, oldDate, newDate); } private String getDate(final DateTime control) { final int year = control.getYear(); final int month = control.getMonth() + 1; final int day = control.getDay(); return String.format("%s/%s/%s", month, day, year); } private void handleValidationUpdateFromModel(final ValidationTime time) { final IDateTimeRidget ridget = getRidget(); final FTValidator validator = new FTValidator(new Date(99)); ridget.addValidationRule(validator, time); final TypedBean<Date> dateBean = new TypedBean<Date>(new Date(0)); ridget.bindToModel(dateBean, TypedBean.PROP_VALUE); int count = validator.count; ridget.updateFromModel(); assertTrue(count < validator.count); assertFalse(ridget.isErrorMarked()); count = validator.count; dateBean.setValue(new Date(99)); ridget.updateFromModel(); assertTrue(count < validator.count); assertTrue(ridget.isErrorMarked()); assertEquals(new Date(99), ridget.getDate()); count = validator.count; dateBean.setValue(new Date(0)); ridget.updateFromModel(); assertTrue(count < validator.count); assertFalse(ridget.isErrorMarked()); } private void handleValidationSetDate(final ValidationTime time) { final IDateTimeRidget ridget = getRidget(); final FTValidator validator = new FTValidator(new Date(99)); ridget.addValidationRule(validator, time); assertEquals(0, validator.count); ridget.setDate(new Date(0)); assertEquals(1, validator.count); assertFalse(ridget.isErrorMarked()); ridget.setDate(new Date(99)); assertEquals(2, validator.count); assertTrue(ridget.isErrorMarked()); assertEquals(new Date(99), ridget.getDate()); ridget.setDate(new Date(0)); assertEquals(3, validator.count); assertFalse(ridget.isErrorMarked()); } private void handleValidationWidgetModification(final ValidationTime time, final String input) { final IDateTimeRidget ridget = getRidget(); final FTValidator validator = new FTValidator("4/10/2009"); final DateTime control = getWidget(); ridget.addValidationRule(validator, time); final TypedBean<Date> dateBean = new TypedBean<Date>(new Date(0)); ridget.bindToModel(dateBean, TypedBean.PROP_VALUE); final int count = validator.count; assertFalse(ridget.isErrorMarked()); control.setFocus(); UITestHelper.sendString(control.getDisplay(), input); assertTrue(count < validator.count); assertTrue(ridget.isErrorMarked()); } /** * As per Bug 323899 */ public void testSetOutputOnly() { final IDateTimeRidget ridget = (IDateTimeRidget) createRidget(); final DateTime control = (DateTime) createWidget(getShell()); ridget.setOutputOnly(true); assertTrue(ridget.isOutputOnly()); assertTrue(control.isEnabled()); ridget.setUIControl(control); ridget.addMarker(new AbstractMarker() { }); assertTrue(ridget.isOutputOnly()); assertFalse(control.isEnabled()); } // helping classes ////////////////// /** * IValidator with counter. Used for testing. */ private final class FTValidator implements IValidator { private int count = 0; private Date errorDate; private String errorString; FTValidator(final Date errorValue) { this.errorDate = errorValue; } FTValidator(final String errorValue) { this.errorString = errorValue; } public IStatus validate(final Object value) { count++; IStatus result = ValidationStatus.ok(); if (errorDate != null && errorDate.equals(value)) { result = ValidationStatus.error("error"); } if (errorString != null && errorString.equals(asString((Date) value))) { result = ValidationStatus.error("error"); } // System.out.println("validate: " + count + " " + value + " " + result); return result; } } }