/*******************************************************************************
* 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 java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import com.ibm.icu.util.GregorianCalendar;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;
import org.eclipse.riena.beans.common.DateBean;
import org.eclipse.riena.beans.common.StringBean;
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.ErrorMarker;
import org.eclipse.riena.ui.core.marker.MandatoryMarker;
import org.eclipse.riena.ui.ridgets.IDateTextRidget;
import org.eclipse.riena.ui.ridgets.IMarkableRidget;
import org.eclipse.riena.ui.ridgets.IRidget;
import org.eclipse.riena.ui.ridgets.swt.uibinding.SwtControlRidgetMapper;
import org.eclipse.riena.ui.swt.DatePickerComposite;
import org.eclipse.riena.ui.swt.DatePickerComposite.IDateConverterStrategy;
import org.eclipse.riena.ui.swt.utils.UIControlsFactory;
/**
* Tests for the class {@link DateTextRidget}.
*/
public class DateTextRidgetTest extends AbstractSWTRidgetTest {
@Override
protected IRidget createRidget() {
final DateTextRidget result = new DateTextRidget();
result.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
return result;
}
@Override
protected IDateTextRidget getRidget() {
return (IDateTextRidget) super.getRidget();
}
@Override
protected Control createWidget(final Composite parent) {
final Control result = new Text(getShell(), SWT.RIGHT | SWT.BORDER | SWT.SINGLE);
result.setData(UIControlsFactory.KEY_TYPE, UIControlsFactory.TYPE_DATE);
result.setLayoutData(new RowData(100, SWT.DEFAULT));
return result;
}
@Override
protected Text getWidget() {
return (Text) super.getWidget();
}
// test methods
///////////////
/**
* ensure that pressing ENTER triggers an autofill
*/
public void testAutofillOnEnter() throws Exception {
final IDateTextRidget ridget = getRidget();
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
ridget.setDirectWriting(false);
final DateBean bean = new DateBean(new Date());
ridget.bindToModel(bean, DateBean.DATE_PROPERTY);
UITestHelper.sendKeyAction(getWidget().getDisplay(), UITestHelper.KC_DEL);
UITestHelper.sendString(getWidget().getDisplay(), "010298"); //$NON-NLS-1$
// not press ENTER
UITestHelper.sendString(getWidget().getDisplay(), "\r"); //$NON-NLS-1$
assertEquals(new GregorianCalendar(1998, 1, 1).getTime(), bean.getValue());
assertEquals("01.02.1998", getWidget().getText()); //$NON-NLS-1$
}
public void testEmptyText() {
final IDateTextRidget ridget = getRidget();
ridget.setFormat(IDateTextRidget.FORMAT_DDMM);
ridget.updateFromModel();
assertTrue(ridget.getMarkersOfType(ErrorMarker.class).isEmpty());
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYY);
ridget.updateFromModel();
assertTrue(ridget.getMarkersOfType(ErrorMarker.class).isEmpty());
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
ridget.updateFromModel();
assertTrue(ridget.getMarkersOfType(ErrorMarker.class).isEmpty());
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYYHHMM);
ridget.updateFromModel();
assertTrue(ridget.getMarkersOfType(ErrorMarker.class).isEmpty());
}
public void testRidgetMapping() {
final SwtControlRidgetMapper mapper = SwtControlRidgetMapper.getInstance();
assertSame(DateTextRidget.class, mapper.getRidgetClass(getWidget()));
}
public void testDelete() {
final IDateTextRidget ridget = getRidget();
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
assertText("^01.10.2008", UITestHelper.KC_DEL, " ^1.10.2008");
assertText("0^1.10.2008", UITestHelper.KC_DEL, " 0^.10.2008");
assertText("01.10.200^8", UITestHelper.KC_DEL, "01.10. 200^");
assertText("01.10.2008^", UITestHelper.KC_DEL, "01.10.2008^");
assertText("01.10^.2008", UITestHelper.KC_DEL, "01.10. ^008");
assertText("01.10^. 008", UITestHelper.KC_DEL, "01.10. ^08");
assertText("01.10^.^2008", UITestHelper.KC_DEL, "01.10^.2008");
assertText("01.10^.2^008", UITestHelper.KC_DEL, "01.10^. 008");
assertText("01.1^0.2^008", UITestHelper.KC_DEL, "01. 1^. 008");
assertText("^01.10.2008^", UITestHelper.KC_DEL, " ^. . ");
assertText("^01.10.2008", "\b", "^01.10.2008");
assertText("0^1.10.2008", "\b", " ^1.10.2008");
assertText("01.10.200^8", "\b", "01.10. 20^8");
assertText("01.10.2008^", "\b", "01.10. 200^");
assertText("01.10.^2008", "\b", "01. 1^.2008");
assertText("01. 1.^2008", "\b", "01. ^.2008");
assertText("01.10^.^2008", "\b", "01.10^.2008");
assertText("01.10^.2^008", "\b", "01.10^. 008");
assertText("01.1^0.2^008", "\b", "01. 1^. 008");
assertText("^01.10.2008^", "\b", " ^. . ");
assertText("^ . . ", UITestHelper.KC_DEL, " ^. . ");
assertText(" ^. . ", UITestHelper.KC_DEL, " . ^. ");
assertText(" . ^ . ", UITestHelper.KC_DEL, " . ^. ");
assertText(" . ^. ", UITestHelper.KC_DEL, " . . ^");
assertText(" . . ^", "\b", " . ^. ");
assertText(" . ^ . ", "\b", " ^. . ");
assertText(" ^. . ", "\b", " ^. . ");
assertText(" ^ . . ", "\b", " ^ . . ");
}
public void testReplace() {
final IDateTextRidget ridget = getRidget();
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
assertText("01.10^.^2008", "1", "01.10^.2008");
assertText("01.10^.^2008", ".", "01.10.^2008");
assertText("01.10^.2^008", "1", "01.10.1^008");
assertText("01.1^0.^2008", "3", "01.13^.2008");
assertText("01.1^0.2^008", "3", "01.13^. 008");
assertText("^01^.10.2008", "3", " 3^.10.2008");
assertText("^01.^10.2008", "3", " 3^.10.2008");
assertText("^01.1^0.2008", "3", " 3^. 0.2008");
assertText("^01.10.2^008", "3", " 3^. . 008");
assertText("^01.10.2008^", "3", " 3^. . ");
}
public void testInsert() {
final IDateTextRidget ridget = getRidget();
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
assertText(" ^. . ", "01102008", "01.10.2008^");
assertText(" ^ . . ", "01.10.2008", "01.10.2008^");
assertText("^ . . ", "01.10.20081234", "01.10.2008^");
assertText(" ^.10.2008", "0123", "01^.10.2008");
assertText(" ^. .2008", "1208", "12.08^.2008");
assertText(" . ^.2008", "1208", " .12^.2008");
assertText("01. .^2008", "10", "01. .^2008");
assertText(" . . ^", "2008", " . .2008^");
assertText(" . ^. ", "102008", " .10.2008^");
}
public void testSetText() {
final IDateTextRidget ridget = getRidget();
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
ridget.setText("01.10.2008");
assertEquals("01.10.2008", ridget.getText());
ridget.setText("01.10");
assertEquals("01.10. ", ridget.getText());
ridget.setText("22.22.2222");
assertEquals("22.22.2222", ridget.getText());
ridget.setText("");
assertEquals(" . . ", ridget.getText());
ridget.setText(" .10.");
assertEquals(" .10. ", ridget.getText());
ridget.setText(" . .");
assertEquals(" . . ", ridget.getText());
try {
ridget.setText("abc");
fail();
} catch (final RuntimeException rex) {
ok();
}
try {
ridget.setText("12102008");
fail();
} catch (final RuntimeException rex) {
ok();
}
try {
ridget.setText("12/10/2008");
fail();
} catch (final RuntimeException rex) {
ok();
}
try {
ridget.setText("12.ab");
fail();
} catch (final RuntimeException rex) {
ok();
}
}
/**
* Tests that setText(null) clears the ridget (i.e. results in an empty pattern with just the separators)
*/
public void testSetTextNull() {
final IDateTextRidget ridget = getRidget();
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
ridget.setText("01.10.2008");
assertEquals("01.10.2008", ridget.getText());
ridget.setText(null);
assertEquals(" . . ", ridget.getText());
}
public void testSetFormatAfterSetText() {
final IDateTextRidget ridget = getRidget();
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
final Text control = getWidget();
final StringBean bean = new StringBean();
ridget.bindToModel(bean, StringBean.PROP_VALUE);
ridget.setText("01.10.2008");
assertEquals("01.10.2008", control.getText());
assertEquals("01.10.2008", ridget.getText());
assertEquals("01.10.2008", bean.getValue());
// As per Bug 289535. See also #testSetFormatWithStringBean
ridget.setFormat(IDateTextRidget.FORMAT_HHMM);
assertEquals(" : ", control.getText());
assertEquals(" : ", ridget.getText());
assertEquals(" : ", bean.getValue());
}
public void testUpdateFromModel() {
final IDateTextRidget ridget = getRidget();
final Text control = getWidget();
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
final StringBean bean = new StringBean("12.10.2008");
ridget.bindToModel(bean, StringBean.PROP_VALUE);
// value fully matches pattern
ridget.updateFromModel();
assertEquals("12.10.2008", control.getText());
assertEquals("12.10.2008", ridget.getText());
assertEquals("12.10.2008", bean.getValue());
// value matches sub-pattern
bean.setValue(" .12");
ridget.updateFromModel();
assertEquals(" .12. ", control.getText());
assertEquals(" .12. ", ridget.getText());
assertEquals(" .12", bean.getValue());
// value does not match patter; control and ridget unchanged
bean.setValue("abc");
ridget.updateFromModel();
assertEquals(" .12. ", control.getText());
assertEquals(" .12. ", control.getText());
assertEquals("abc", bean.getValue());
}
public void testBindToDate() {
final IDateTextRidget ridget = getRidget();
final Text control = getWidget();
final DateBean bean = new DateBean(localize(0L));
ridget.bindToModel(bean, DateBean.DATE_PROPERTY);
ridget.updateFromModel();
assertEquals("01.01.1970", control.getText());
assertEquals("01.01.1970", ridget.getText());
assertEquals(localize(0L), bean.getValue());
}
/**
* As per Bug 289535
* <p>
* When the ridget / control value on setFormat(...) it will be overwritten with the freshly formatted data from the model. If there is no model it will be
* cleared.
*/
public void testSetFormatWithDateBean() {
final IDateTextRidget ridget = getRidget();
final Text control = getWidget();
final DateBean bean = new DateBean(localize(0L));
ridget.bindToModel(bean, DateBean.DATE_PROPERTY);
ridget.updateFromModel();
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYY);
assertEquals("01.01.70", ridget.getText());
assertEquals("01.01.70", control.getText());
assertEquals(localize(0L), bean.getValue());
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
assertEquals("01.01.1970", ridget.getText());
assertEquals("01.01.1970", control.getText());
assertEquals(localize(0L), bean.getValue());
}
/**
* As per Bug 289535
* <p>
* When the format is incompatible with the model (this can never happen when the model is backed by a Date. It can only happen when the model is backed by
* a String), the format will be changed and the value of the model will be applied as is to the ridget / widget. If the value is longer than the format
* pattern, it will be truncated. In any case the resulting value will most likely be incorrect (since it is based on the old format) and may cause an error
* marker to appear.
*/
public void testSetFormatWithStringBean() {
final IDateTextRidget ridget = getRidget();
final Text control = getWidget();
final StringBean bean = new StringBean("01.01.1970");
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
ridget.bindToModel(bean, StringBean.PROP_VALUE);
ridget.updateFromModel();
assertEquals("01.01.1970", ridget.getText());
assertEquals("01.01.1970", control.getText());
assertEquals("01.01.1970", bean.getValue());
ridget.setFormat("dd/MM/yy");
assertEquals(" / / ", ridget.getText());
assertEquals(" / / ", control.getText());
assertEquals(" / / ", bean.getValue());
assertFalse(ridget.isErrorMarked());
control.setFocus();
UITestHelper.sendString(control.getDisplay(), "01/01/70\t");
assertEquals("01/01/70", ridget.getText());
assertEquals("01/01/70", control.getText());
assertEquals("01/01/70", bean.getValue());
assertFalse(ridget.isErrorMarked());
}
/**
* As per Bug 289535
* <p>
* When the ridget / control value on setFormat(...) it will be overwritten with the freshly formatted data from the model. If there is no model it will be
* cleared.
*/
public void testSetFormatWithNoBean() {
final IDateTextRidget ridget = getRidget();
final Text control = getWidget();
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
ridget.setText("01.01.1970");
assertEquals("01.01.1970", ridget.getText());
assertEquals("01.01.1970", control.getText());
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYY);
assertEquals(" . . ", ridget.getText());
assertEquals(" . . ", control.getText());
}
public void testAutoFillYYYY() {
final IDateTextRidget ridget = getRidget();
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
assertText(" . . ^", "00\t", " . .2000");
assertText(" . .^ ", "01\t", " . .2001");
assertText(" . . ^ ", "29\t", " . .2029");
assertText(" . . ^", "30\t", " . .1930");
assertText(" . . ^", "99\t", " . .1999");
}
public void testAutoFillYYYYWithError() {
final IDateTextRidget ridget = getRidget();
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
ridget.setText("31.10.2008");
assertFalse(ridget.isErrorMarked());
assertText("31.10. ^", "8\t", "31.10. 8");
assertTrue(ridget.isErrorMarked());
ridget.setText("31.10.2008");
assertFalse(ridget.isErrorMarked());
assertText("31.10. ^", "008\t", "31.10. 008");
assertTrue(ridget.isErrorMarked());
}
public void testDoNotFillYY() {
final IDateTextRidget ridget = getRidget();
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYY);
assertText(" . . ^", "00\t", " . .00");
ridget.setFormat("ddMMyy");
assertText(" ^", "00\t", " 00");
}
public void testMandatoryMarker() {
final IDateTextRidget ridget = getRidget();
ridget.setMandatory(true);
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
ridget.setText("31.10.2008");
TestUtils.assertMandatoryMarker(ridget, 1, true);
ridget.setText(null);
TestUtils.assertMandatoryMarker(ridget, 1, false);
ridget.setMandatory(false);
TestUtils.assertMandatoryMarker(ridget, 0, false);
}
public void testDateConverterStrategyGetter() {
final DateTextRidget ridget = (DateTextRidget) getRidget();
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
final IDateConverterStrategy strategy = ridget.new RidgetAwareDateConverterStrategy();
assertNull(strategy.getDateFromTextField(null));
assertNull(strategy.getDateFromTextField(""));
assertNull(strategy.getDateFromTextField("abcd"));
assertNull(strategy.getDateFromTextField("12.12"));
final Calendar calendar = Calendar.getInstance();
calendar.set(2009, 11, 24, 0, 0, 0);
final Date expected = calendar.getTime();
final Date result = strategy.getDateFromTextField("24.12.2009");
assertEquals(expected.toString(), result.toString());
}
public void testDateConverterStrategySetter() {
final DateTextRidget ridget = (DateTextRidget) getRidget();
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYYHHMM);
final IDateConverterStrategy strategy = ridget.new RidgetAwareDateConverterStrategy();
final Calendar calendar = Calendar.getInstance();
calendar.set(2009, 11, 24, 0, 0, 0);
final Date date = calendar.getTime();
strategy.setDateToTextField(date);
assertEquals("24.12.2009 00:00", ridget.getText());
}
/**
* As per Bug 305056.
*/
public void testMandatoryWithDatePickerWidget() {
final IDateTextRidget ridget = getRidget();
ridget.setMandatory(true);
final DatePickerComposite control = new DatePickerComposite(getShell(), SWT.BORDER);
ridget.setUIControl(control);
final Display display = control.getDisplay();
final Color colorWhite = display.getSystemColor(SWT.COLOR_WHITE);
final Color colorMandatory = Activator.getSharedColor(display, SharedColors.COLOR_MANDATORY);
assertFalse(colorWhite.equals(colorMandatory)); // sanity check
ridget.setText("01.10.2008");
assertEquals("01.10.2008", ridget.getText());
assertEquals("01.10.2008", control.getTextfield().getText());
assertMandatoryMarker(ridget, 1, true);
assertEquals(colorWhite, control.getTextfield().getBackground());
ridget.setText(" . . ");
assertEquals(" . . ", ridget.getText());
assertEquals(" . . ", control.getTextfield().getText());
assertMandatoryMarker(ridget, 1, false);
assertEquals(colorMandatory, control.getTextfield().getBackground());
ridget.setMandatory(false);
assertEquals(" . . ", ridget.getText());
assertEquals(" . . ", control.getTextfield().getText());
assertMandatoryMarker(ridget, 0, false);
assertEquals(colorWhite, control.getTextfield().getBackground());
}
/**
* As per Bug 313254
*/
public void testHideEmptyValueWhenOutputOnly() {
final IDateTextRidget ridget = getRidget();
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
final Text control = getWidget();
assertEquals(false, ridget.isOutputOnly());
assertEquals(" . . ", ridget.getText());
assertEquals(" . . ", control.getText());
ridget.setOutputOnly(true);
assertEquals(true, ridget.isOutputOnly());
assertEquals(" . . ", ridget.getText());
assertEquals("", control.getText());
ridget.setOutputOnly(false);
assertEquals(false, ridget.isOutputOnly());
assertEquals(" . . ", ridget.getText());
assertEquals(" . . ", control.getText());
}
/**
* As per Bug 317028.
*/
public void testTogglingEnabledWithDirectWritingPreservesContent() {
final IDateTextRidget ridget = getRidget();
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
final Text control = getWidget();
ridget.setDirectWriting(true);
assertTrue(ridget.isDirectWriting());
final StringBean bean = new StringBean(" . . ");
ridget.bindToModel(bean, StringBean.PROP_VALUE);
ridget.updateFromModel();
assertEquals(" . . ", control.getText());
assertEquals(" . . ", ridget.getText());
assertEquals(" . . ", bean.getValue());
ridget.setEnabled(false);
assertEquals("", control.getText());
assertEquals(" . . ", ridget.getText());
assertEquals(" . . ", bean.getValue());
ridget.setEnabled(true);
assertEquals(" . . ", control.getText());
assertEquals(" . . ", ridget.getText());
assertEquals(" . . ", bean.getValue());
}
/**
* As per Bug 317028.
*/
public void testTogglingOutputOnlyWithDirectWritingPreservesContent() {
final IDateTextRidget ridget = getRidget();
ridget.setFormat(IDateTextRidget.FORMAT_DDMMYYYY);
final Text control = getWidget();
ridget.setDirectWriting(true);
assertTrue(ridget.isDirectWriting());
final StringBean bean = new StringBean(" . . ");
ridget.bindToModel(bean, StringBean.PROP_VALUE);
ridget.updateFromModel();
assertEquals(" . . ", control.getText());
assertEquals(" . . ", ridget.getText());
assertEquals(" . . ", bean.getValue());
ridget.setOutputOnly(true);
assertEquals("", control.getText());
assertEquals(" . . ", ridget.getText());
assertEquals(" . . ", bean.getValue());
ridget.setOutputOnly(false);
assertEquals(" . . ", control.getText());
assertEquals(" . . ", ridget.getText());
assertEquals(" . . ", bean.getValue());
}
// helping methods
//////////////////
private void assertText(final String before, final String keySeq, final String after) {
TestUtils.assertText(getWidget(), before, keySeq, after);
}
private void assertText(final String before, final int keyCode, final String after) {
TestUtils.assertText(getWidget(), before, keyCode, after);
}
private void assertMandatoryMarker(final IMarkableRidget ridget, final int count, final boolean isDisabled) {
final Collection<MandatoryMarker> markers = ridget.getMarkersOfType(MandatoryMarker.class);
assertEquals(count, markers.size());
for (final MandatoryMarker marker : markers) {
assertEquals(isDisabled, marker.isDisabled());
}
}
@SuppressWarnings("deprecation")
private Date localize(final long msSinceEpochUtc) {
final Date localDate = new Date(msSinceEpochUtc);
return new Date(localDate.getTime() + (60 * 1000 * localDate.getTimezoneOffset()));
}
}