blob: aa320dbd2e374914476cb00ef67970b2d4331cdb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006 The Pampered Chef 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:
* The Pampered Chef - initial API and implementation
******************************************************************************/
package org.eclipse.jface.tests.databinding;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import junit.framework.TestCase;
import org.eclipse.jface.databinding.observable.list.WritableList;
import org.eclipse.jface.examples.databinding.ModelObject;
import org.eclipse.jface.examples.databinding.compositetable.day.NewEvent;
import org.eclipse.jface.examples.databinding.compositetable.day.binding.EventEditorBindingDescription;
import org.eclipse.jface.examples.databinding.compositetable.day.binding.EventEditorObservableLazyDataRequestorFactory;
import org.eclipse.jface.examples.databinding.compositetable.timeeditor.CalendarableItem;
import org.eclipse.jface.examples.databinding.compositetable.timeeditor.CalendarableModel;
import org.eclipse.jface.internal.databinding.provisional.BindSpec;
import org.eclipse.jface.internal.databinding.provisional.Binding;
import org.eclipse.jface.internal.databinding.provisional.DataBindingContext;
import org.eclipse.jface.internal.databinding.provisional.beans.BeanObservableFactory;
import org.eclipse.jface.internal.databinding.provisional.description.Property;
import org.eclipse.jface.internal.databinding.provisional.factories.DefaultBindSupportFactory;
import org.eclipse.jface.internal.databinding.provisional.factories.DefaultBindingFactory;
import org.eclipse.jface.internal.databinding.provisional.observable.LazyDeleteEvent;
import org.eclipse.jface.internal.databinding.provisional.observable.LazyInsertDeleteProvider;
import org.eclipse.jface.internal.databinding.provisional.observable.LazyInsertEvent;
import org.eclipse.jface.internal.databinding.provisional.observable.ILazyDataRequestor.NewObject;
/**
* This is basically two tests in one. It's an integration test that makes
* sure that we can successfully bind EventEditors to JavaBean-style List
* objects. However, since all of the other layers in this binding are also
* unit-tested, it is also a unit test of the
* EventEditorObservableLazyDataRequestor.
*
* @since 3.2
*/
public class EventEditorObservableLazyDataRequestorTest extends TestCase {
private EventEditorStub editor;
private DataBindingContext dbc;
private DataBindingContext getDBC() {
DataBindingContext dbc = new DataBindingContext();
dbc.addBindingFactory(new DefaultBindingFactory());
dbc.addObservableFactory(new EventEditorObservableLazyDataRequestorFactory());
dbc.addObservableFactory(new BeanObservableFactory(dbc, null, null));
dbc.addBindSupportFactory(new DefaultBindSupportFactory());
return dbc;
}
private static class EventEditorStub extends EventEditor {
public CalendarableModel model() {
return model;
}
}
protected static class Event extends ModelObject {
public boolean allDay = false;
public Date startTime;
public Date endTime;
public String description;
public Event(Date startTime, Date endTime, String description) {
this(startTime, endTime, description, false);
}
public Event(Date startTime, Date endTime, String description, boolean isAllDay) {
this.startTime = startTime;
this.endTime = endTime;
this.description = description;
this.allDay = isAllDay;
}
public void setDescription(String string) {
String oldValue = this.description;
description = string;
firePropertyChange("description", oldValue, string);
}
public boolean isAllDay() {
return allDay;
}
public void setAllDay(boolean allDay) {
this.allDay = allDay;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public String getDescription() {
return description;
}
}
protected Date time(int month, int day, int hour, int minutes) {
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(new Date());
gc.set(Calendar.MONTH, month);
gc.set(Calendar.DATE, day);
gc.set(Calendar.HOUR_OF_DAY, hour);
gc.set(Calendar.MINUTE, minutes);
gc.set(Calendar.SECOND, 0);
gc.set(Calendar.MILLISECOND, 0);
return gc.getTime();
}
protected Date time(int hour, int minutes) {
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(new Date());
gc.set(Calendar.HOUR_OF_DAY, hour);
gc.set(Calendar.MINUTE, minutes);
gc.set(Calendar.SECOND, 0);
gc.set(Calendar.MILLISECOND, 0);
return gc.getTime();
}
protected Date date(int month, int day) {
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(new Date());
gc.set(Calendar.MONTH, month);
gc.set(Calendar.DATE, day);
gc.set(Calendar.HOUR_OF_DAY, 0);
gc.set(Calendar.MINUTE, 0);
gc.set(Calendar.SECOND, 0);
gc.set(Calendar.MILLISECOND, 0);
return gc.getTime();
}
protected Date nextDay(Date date) {
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(date);
gc.add(Calendar.DATE, 1);
return gc.getTime();
}
private WritableList loadTestDataIntoList(Event[] testData) {
WritableList testDataList = new WritableList();
for (int event = 0; event < testData.length; event++) {
testDataList.add(testData[event]);
}
return testDataList;
}
/* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
editor = new EventEditorStub();
dbc = getDBC();
}
/* (non-Javadoc)
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
dbc.dispose();
}
private CalendarableItem ci(Date startDate, Date startTime, Date endTime, String description) {
return ci(startDate, startTime, endTime, description, false);
}
private CalendarableItem ci(Date startDate, String description) {
return ci(startDate, startDate, startDate, description, true);
}
private CalendarableItem ci(Date startDate, Date startTime, Date endTime, String description, boolean isAllDay) {
CalendarableItem result = new CalendarableItem(startDate);
result.setStartTime(startTime);
result.setEndTime(endTime);
result.setText(description);
result.setAllDayEvent(isAllDay);
return result;
}
protected Date setToStartOfDay(Date rawDate) {
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(rawDate);
gc.set(Calendar.HOUR_OF_DAY, 0);
gc.set(Calendar.MINUTE, 0);
gc.set(Calendar.SECOND, 0);
gc.set(Calendar.MILLISECOND, 0);
return gc.getTime();
}
protected Date setToEndOfDay(Date date) {
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(date);
gc.set(Calendar.HOUR_OF_DAY, 23);
gc.set(Calendar.MINUTE, 59);
gc.set(Calendar.SECOND, 59);
gc.set(Calendar.MILLISECOND, 999);
Date time = gc.getTime();
return time;
}
private WritableList makeModel(final Event[] testData) {
return loadTestDataIntoList(testData);
}
static class TestModel extends ModelObject {
List testDataList;
TestModel(List testData) {
this.testDataList = testData;
}
public List getTestDataList() {
return testDataList;
}
public void setTestDataList(List testDataList) {
Object oldValue = this.testDataList;
this.testDataList = testDataList;
firePropertyChange("testDataList", oldValue, testDataList);
}
};
private Property makeModel(List testData) {
Object model = new TestModel(testData);
return new Property(model, "testDataList");
}
private void assertEditorState(
EventEditorStub editor,
CalendarableItem[][] itemsInDay) {
CalendarableModel cm = editor.model();
for (int day=0; day < cm.getNumberOfDays(); ++day) {
List calendarables = cm.getCalendarableItems(day);
int itemInDay=0;
assertEquals("Day " + day + ": list sizes same", itemsInDay[day].length, calendarables.size());
for (Iterator calIter = calendarables.iterator(); calIter.hasNext();) {
CalendarableItem item = (CalendarableItem) calIter.next();
assertEquals("All-day", itemsInDay[day][itemInDay].isAllDayEvent(), item.isAllDayEvent());
assertEquals("Text", itemsInDay[day][itemInDay].getText(), item.getText());
if (item.isAllDayEvent()) {
assertTrue("same day", isSameDay(itemsInDay[day][itemInDay].getStartTime(), item.getStartTime()));
} else {
assertEquals("Start time", itemsInDay[day][itemInDay].getStartTime(), item.getStartTime());
assertEquals("End time", itemsInDay[day][itemInDay].getEndTime(), item.getEndTime());
}
++itemInDay;
}
}
}
private boolean isSameDay(Date time1, Date time2) {
GregorianCalendar gc1 = new GregorianCalendar();
GregorianCalendar gc2 = new GregorianCalendar();
gc1.setTime(time1);
gc2.setTime(time2);
if (gc1.get(Calendar.YEAR) != gc2.get(Calendar.YEAR)) {
return false;
}
if (gc1.get(Calendar.MONTH) != gc2.get(Calendar.MONTH)) {
return false;
}
if (gc1.get(Calendar.DATE) != gc2.get(Calendar.DATE)) {
return false;
}
return true;
}
private EventEditorBindingDescription makeBindingDescription() {
return new EventEditorBindingDescription(
editor, dbc, "startTime", "endTime", "allDay", "description", null, null);
}
// Tests here -------------------------------------------------------------
public void test_oneDayEvent_onEditorStartDate() throws Exception {
editor.setTimeBreakdown(7, 4);
editor.setStartDate(date(5, 15));
EventEditorBindingDescription editorBindDesc = makeBindingDescription();
Event[] testData = new Event[] {
new Event (time(5, 15, 5, 45), time(5, 15, 9, 45), "Stand-up mtg")};
dbc.bind(editorBindDesc, makeModel(testData), null);
assertEditorState(editor, new CalendarableItem[][] {
{ci(date(5, 15), time(5, 45), time(9, 45), "Stand-up mtg")},
{},
{},
{},
{},
{},
{}
});
}
public void test_addingAndRemovingFromModel() throws Exception {
editor.setTimeBreakdown(7, 4);
editor.setStartDate(date(5, 15));
EventEditorBindingDescription editorBindDesc = makeBindingDescription();
Event[] testData = new Event[] {
new Event (time(5, 15, 5, 45), time(5, 15, 9, 45), "Stand-up mtg")};
WritableList model = makeModel(testData);
dbc.bind(editorBindDesc, model, null);
Event event = new Event (time(5, 16, 5, 45), time(5, 16, 9, 45), "Stand-up mtg 2");
model.add(event);
assertEditorState(editor, new CalendarableItem[][] {
{ci(date(5, 15), time(5, 45), time(9, 45), "Stand-up mtg")},
{ci(date(5, 16), time(5, 45), time(9, 45), "Stand-up mtg 2")},
{},
{},
{},
{},
{}
});
model.remove(event);
assertEditorState(editor, new CalendarableItem[][] {
{ci(date(5, 15), time(5, 45), time(9, 45), "Stand-up mtg")},
{},
{},
{},
{},
{},
{}
});
}
public void test_oneDayOneEvent_notOnEditorStartDate() throws Exception {
editor.setTimeBreakdown(7, 4);
editor.setStartDate(date(5, 15));
EventEditorBindingDescription editorBindDesc = makeBindingDescription();
Event[] testData = new Event[] {
new Event (time(5, 16, 5, 45), time(5, 16, 9, 45), "Stand-up mtg")};
dbc.bind(editorBindDesc, makeModel(testData), null);
assertEditorState(editor, new CalendarableItem[][] {
{},
{ci(date(5, 16), time(5, 45), time(9, 45), "Stand-up mtg")},
{},
{},
{},
{},
{}
});
}
public void test_threeDayOneEvent() throws Exception {
editor.setTimeBreakdown(7, 4);
editor.setStartDate(date(5, 15));
EventEditorBindingDescription editorBindDesc = makeBindingDescription();
Event[] testData = new Event[] {
new Event (time(5, 15, 5, 45), time(5, 17, 9, 45), "Stand-up mtg")};
dbc.bind(editorBindDesc, makeModel(testData), null);
assertEditorState(editor, new CalendarableItem[][] {
{ci(date(5, 15), time(5, 45), setToEndOfDay(date(5, 15)), "Stand-up mtg")},
{ci(date(5, 16), setToStartOfDay(date(5, 16)), setToEndOfDay(date(5, 16)), "Stand-up mtg")},
{ci(date(5, 17), setToStartOfDay(date(5, 17)), time(9, 45), "Stand-up mtg")},
{},
{},
{},
{}
});
}
public void test_threeDayOneEvent_notOnEditorStartDate() throws Exception {
editor.setTimeBreakdown(7, 4);
editor.setStartDate(date(5, 14));
EventEditorBindingDescription editorBindDesc = makeBindingDescription();
Event[] testData = new Event[] {
new Event (time(5, 15, 5, 45), time(5, 17, 9, 45), "Stand-up mtg")};
dbc.bind(editorBindDesc, makeModel(testData), null);
assertEditorState(editor, new CalendarableItem[][] {
{},
{ci(date(5, 15), time(5, 45), setToEndOfDay(date(5, 15)), "Stand-up mtg")},
{ci(date(5, 16), setToStartOfDay(date(5, 16)), setToEndOfDay(date(5, 16)), "Stand-up mtg")},
{ci(date(5, 17), setToStartOfDay(date(5, 17)), time(9, 45), "Stand-up mtg")},
{},
{},
{}
});
}
public void test_oneDayOneAllDayEvent() throws Exception {
editor.setTimeBreakdown(7, 4);
editor.setStartDate(date(5, 15));
Event[] testData = new Event[] {
new Event (time(5, 15, 5, 45), time(5, 15, 9, 45), "Stand-up mtg", true)};
EventEditorBindingDescription editorBindDesc = makeBindingDescription();
dbc.bind(editorBindDesc, makeModel(testData), null);
assertEditorState(editor, new CalendarableItem[][] {
{ci(date(5, 15), "Stand-up mtg")},
{},
{},
{},
{},
{},
{}
});
}
public void test_multiDayAllDayEvent() throws Exception {
editor.setTimeBreakdown(7, 4);
editor.setStartDate(date(5, 15));
Event[] testData = new Event[] {
new Event (time(5, 15, 5, 45), time(5, 17, 9, 45), "three day mtg", true)};
EventEditorBindingDescription editorBindDesc = makeBindingDescription();
dbc.bind(editorBindDesc, makeModel(testData), null);
assertEditorState(editor, new CalendarableItem[][] {
{ci(date(5, 15), "three day mtg")},
{ci(date(5, 16), "three day mtg")},
{ci(date(5, 17), "three day mtg")},
{},
{},
{},
{}
});
}
public void test_bindCalendarableDescription() throws Exception {
editor.setTimeBreakdown(7, 4);
editor.setStartDate(date(5, 15));
Event[] testData = new Event[] {
new Event (time(5, 15, 5, 45), time(5, 15, 9, 45), "Stand-up mtg")};
List testDataList = loadTestDataIntoList(testData);
EventEditorBindingDescription editorBindDesc = makeBindingDescription();
dbc.bind(editorBindDesc, makeModel(testDataList), null);
assertEditorState(editor, new CalendarableItem[][] {
{ci(date(5, 15), time(5, 45), time(9, 45), "Stand-up mtg")},
{},
{},
{},
{},
{},
{}
});
Event event = (Event) testDataList.get(0);
event.setDescription("The quick brown fox jumped over the lazy dog.");
List calendarableEvents = editor.model.getCalendarableItems((0));
CalendarableItem item = (CalendarableItem) calendarableEvents.get(0);
assertEquals("item Text was changed", event.description, item.getText());
}
/**
* Test method for {@link org.eclipse.jface.examples.databinding.compositetable.day.binding.EventEditorObservableLazyDataRequestor#dispose()}.
*/
public void testDispose() {
editor.setTimeBreakdown(7, 4);
editor.setStartDate(date(5, 14));
EventEditorBindingDescription editorBindDesc = makeBindingDescription();
Event[] testData = new Event[] {
new Event (time(5, 15, 5, 45), time(5, 17, 9, 45), "Stand-up mtg")};
dbc.bind(editorBindDesc, makeModel(testData), null);
List daysToDispose = new LinkedList();
for (int day=0; day < 7; ++day) {
List calendarables = editor.model().getCalendarableItems(day);
if (calendarables != null) {
daysToDispose.addAll(calendarables);
}
}
editor.setStartDate(date(5, 1));
for (Iterator disposedDaysIter = daysToDispose.iterator(); disposedDaysIter.hasNext();) {
CalendarableItem item = (CalendarableItem) disposedDaysIter.next();
List bindingList = (List) item.getData("BindingBinding");
for (Iterator bindingListIter = bindingList.iterator(); bindingListIter.hasNext();) {
Binding binding = (Binding) bindingListIter.next();
assertTrue("should be disposed", binding.isDisposed());
}
}
}
/**
* Test method for {@link org.eclipse.jface.examples.databinding.compositetable.day.binding.EventEditorObservableLazyDataRequestor#add(int, java.lang.Object)}.
*/
public void testInsert() {
Event[] testData = new Event[] {
new Event (time(5, 15, 5, 45), time(5, 15, 9, 45), "Stand-up mtg")};
final WritableList model = makeModel(testData);
LazyInsertDeleteProvider insertDeleteProvider = new LazyInsertDeleteProvider() {
public NewObject insertElementAt(LazyInsertEvent e) {
Event event = new Event(time(5, 17, 5, 45), time(5, 17, 9, 45), "Stand-up mtg 3");
model.add(e.positionHint, event);
return new NewObject(e.positionHint, event);
}
public void deleteElementAt(LazyDeleteEvent e) {
}
};
editor.setTimeBreakdown(7, 4);
editor.setStartDate(date(5, 15));
EventEditorBindingDescription editorBindDesc = makeBindingDescription();
dbc.bind(editorBindDesc, model, new BindSpec().setLazyInsertDeleteProvider(insertDeleteProvider));
Event event = new Event (time(5, 16, 5, 45), time(5, 16, 9, 45), "Stand-up mtg 2");
model.add(event);
// Add the third event (to the target via the insertDeleteProvider)
NewEvent results = editorBindDesc.editor.fireInsert(date(5, 17), false);
assertEquals("start date", time(5, 17, 5, 45), results.startTimeEndTime[0]);
assertEquals("end date", time(5, 17, 9, 45), results.startTimeEndTime[1]);
assertEditorState(editor, new CalendarableItem[][] {
{ci(date(5, 15), time(5, 45), time(9, 45), "Stand-up mtg")},
{ci(date(5, 16), time(5, 45), time(9, 45), "Stand-up mtg 2")},
{ci(date(5, 17), time(5, 45), time(9, 45), "Stand-up mtg 3")},
{},
{},
{},
{}
});
}
/**
* Test method for {@link org.eclipse.jface.examples.databinding.compositetable.day.binding.EventEditorObservableLazyDataRequestor#remove(int)}.
*/
public void testRemove() {
Event[] testData = new Event[] {
new Event (time(5, 15, 5, 45), time(5, 15, 9, 45), "Stand-up mtg")};
final WritableList model = makeModel(testData);
LazyInsertDeleteProvider insertDeleteProvider = new LazyInsertDeleteProvider() {
public NewObject insertElementAt(LazyInsertEvent e) {
return null;
}
public boolean canDeleteElementAt(LazyDeleteEvent e) {
return true;
}
public void deleteElementAt(LazyDeleteEvent e) {
model.remove(e.position);
}
};
editor.setTimeBreakdown(7, 4);
editor.setStartDate(date(5, 15));
EventEditorBindingDescription editorBindDesc = makeBindingDescription();
dbc.bind(editorBindDesc, model, new BindSpec().setLazyInsertDeleteProvider(insertDeleteProvider));
Event event = new Event (time(5, 16, 5, 45), time(5, 16, 9, 45), "Stand-up mtg 2");
model.add(event);
boolean result = editorBindDesc.editor.fireDelete((CalendarableItem) editor.model.getCalendarableItems(0).get(0));
assertTrue("Could delete", result);
assertEditorState(editor, new CalendarableItem[][] {
{},
{ci(date(5, 16), time(5, 45), time(9, 45), "Stand-up mtg 2")},
{},
{},
{},
{},
{}
});
}
}