Skip to content

Package: MultiReferenceRenderer_PTest$1

MultiReferenceRenderer_PTest$1

nameinstructionbranchcomplexitylinemethod
answer(InvocationOnMock)
M: 2 C: 16
89%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 1 C: 4
80%
M: 0 C: 1
100%
{...}
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2011-2019 EclipseSource Muenchen GmbH and others.
3: *
4: * All rights reserved. This program and the accompanying materials
5: * are made available under the terms of the Eclipse Public License 2.0
6: * which accompanies this distribution, and is available at
7: * https://www.eclipse.org/legal/epl-2.0/
8: *
9: * SPDX-License-Identifier: EPL-2.0
10: *
11: * Contributors:
12: * Lucas Koehler - initial API and implementation
13: * Christian W. Damus - bugs 527736, 552385
14: ******************************************************************************/
15: package org.eclipse.emf.ecp.view.internal.control.multireference;
16:
17: import static org.hamcrest.CoreMatchers.is;
18: import static org.hamcrest.MatcherAssert.assertThat;
19: import static org.hamcrest.Matchers.equalTo;
20: import static org.hamcrest.Matchers.notNullValue;
21: import static org.hamcrest.Matchers.nullValue;
22: import static org.junit.Assert.assertEquals;
23: import static org.junit.Assert.assertFalse;
24: import static org.junit.Assert.assertSame;
25: import static org.junit.Assert.assertTrue;
26: import static org.junit.Assert.fail;
27: import static org.mockito.Matchers.any;
28: import static org.mockito.Matchers.matches;
29: import static org.mockito.Mockito.mock;
30: import static org.mockito.Mockito.when;
31:
32: import java.util.Collections;
33: import java.util.LinkedList;
34: import java.util.List;
35: import java.util.NoSuchElementException;
36: import java.util.regex.Pattern;
37:
38: import org.eclipse.core.databinding.observable.IObserving;
39: import org.eclipse.core.databinding.observable.Observables;
40: import org.eclipse.core.databinding.observable.Realm;
41: import org.eclipse.core.databinding.observable.list.IObservableList;
42: import org.eclipse.core.databinding.observable.list.WritableList;
43: import org.eclipse.core.databinding.observable.value.IObservableValue;
44: import org.eclipse.core.databinding.property.value.IValueProperty;
45: import org.eclipse.emf.common.command.BasicCommandStack;
46: import org.eclipse.emf.common.util.URI;
47: import org.eclipse.emf.databinding.EMFProperties;
48: import org.eclipse.emf.databinding.edit.EMFEditProperties;
49: import org.eclipse.emf.ecore.EClass;
50: import org.eclipse.emf.ecore.EObject;
51: import org.eclipse.emf.ecore.EPackage;
52: import org.eclipse.emf.ecore.EReference;
53: import org.eclipse.emf.ecore.EStructuralFeature;
54: import org.eclipse.emf.ecore.EStructuralFeature.Setting;
55: import org.eclipse.emf.ecore.ETypedElement;
56: import org.eclipse.emf.ecore.EcoreFactory;
57: import org.eclipse.emf.ecore.resource.Resource;
58: import org.eclipse.emf.ecore.util.EcoreUtil;
59: import org.eclipse.emf.ecp.edit.spi.DeleteService;
60: import org.eclipse.emf.ecp.edit.spi.EMFDeleteServiceImpl;
61: import org.eclipse.emf.ecp.view.model.common.AbstractGridCell.Alignment;
62: import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
63: import org.eclipse.emf.ecp.view.spi.model.VControl;
64: import org.eclipse.emf.ecp.view.spi.model.VDomainModelReference;
65: import org.eclipse.emf.ecp.view.spi.model.VElement;
66: import org.eclipse.emf.ecp.view.spi.model.VView;
67: import org.eclipse.emf.ecp.view.spi.renderer.NoPropertyDescriptorFoundExeption;
68: import org.eclipse.emf.ecp.view.spi.renderer.NoRendererFoundException;
69: import org.eclipse.emf.ecp.view.spi.util.swt.ImageRegistryService;
70: import org.eclipse.emf.ecp.view.template.model.VTStyleProperty;
71: import org.eclipse.emf.ecp.view.template.model.VTViewTemplateProvider;
72: import org.eclipse.emf.ecp.view.template.style.reference.model.VTReferenceFactory;
73: import org.eclipse.emf.ecp.view.template.style.reference.model.VTReferenceStyleProperty;
74: import org.eclipse.emf.ecp.view.template.style.tableStyleProperty.model.RenderMode;
75: import org.eclipse.emf.ecp.view.template.style.tableStyleProperty.model.VTTableStyleProperty;
76: import org.eclipse.emf.ecp.view.test.common.swt.spi.DatabindingClassRunner;
77: import org.eclipse.emf.ecp.view.test.common.swt.spi.SWTTestUtil;
78: import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
79: import org.eclipse.emf.edit.domain.EditingDomain;
80: import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
81: import org.eclipse.emf.emfstore.bowling.BowlingFactory;
82: import org.eclipse.emf.emfstore.bowling.BowlingPackage;
83: import org.eclipse.emf.emfstore.bowling.Fan;
84: import org.eclipse.emf.emfstore.bowling.League;
85: import org.eclipse.emf.emfstore.bowling.Player;
86: import org.eclipse.emfforms.core.services.databinding.testmodel.test.model.B;
87: import org.eclipse.emfforms.core.services.databinding.testmodel.test.model.TestFactory;
88: import org.eclipse.emfforms.core.services.databinding.testmodel.test.model.TestPackage;
89: import org.eclipse.emfforms.spi.common.report.ReportService;
90: import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException;
91: import org.eclipse.emfforms.spi.core.services.databinding.EMFFormsDatabinding;
92: import org.eclipse.emfforms.spi.core.services.label.EMFFormsLabelProvider;
93: import org.eclipse.emfforms.spi.core.services.label.NoLabelFoundException;
94: import org.eclipse.emfforms.spi.localization.EMFFormsLocalizationService;
95: import org.eclipse.emfforms.spi.swt.core.SWTDataElementIdHelper;
96: import org.eclipse.emfforms.spi.swt.core.layout.SWTGridCell;
97: import org.eclipse.emfforms.spi.swt.core.layout.SWTGridDescription;
98: import org.eclipse.jface.viewers.StructuredSelection;
99: import org.eclipse.swt.SWT;
100: import org.eclipse.swt.widgets.Button;
101: import org.eclipse.swt.widgets.Composite;
102: import org.eclipse.swt.widgets.Control;
103: import org.eclipse.swt.widgets.Label;
104: import org.eclipse.swt.widgets.Shell;
105: import org.eclipse.swt.widgets.Table;
106: import org.eclipse.swt.widgets.TableColumn;
107: import org.eclipse.swt.widgets.TableItem;
108: import org.junit.After;
109: import org.junit.Before;
110: import org.junit.BeforeClass;
111: import org.junit.Test;
112: import org.junit.runner.RunWith;
113: import org.mockito.Mockito;
114: import org.mockito.invocation.InvocationOnMock;
115: import org.mockito.stubbing.Answer;
116: import org.osgi.framework.Bundle;
117:
118: /**
119: * JUnit plugin tests for {@link MultiReferenceSWTRenderer}.
120: *
121: * @author Lucas Koehler
122: *
123: */
124: @RunWith(DatabindingClassRunner.class)
125: public class MultiReferenceRenderer_PTest {
126:         private static final String UUID_LINK = "UUID#link"; //$NON-NLS-1$
127:         private static final String UUID_ADD = "UUID#add"; //$NON-NLS-1$
128:         private static final String UUID_DELETE = "UUID#delete"; //$NON-NLS-1$
129:         private static final String UUID_DOWN = "UUID#down"; //$NON-NLS-1$
130:         private static final String UUID_UP = "UUID#up"; //$NON-NLS-1$
131:         private static final String TEST_DESCRIPTION = "test-description"; //$NON-NLS-1$
132:         private static final String TEST_DISPLAYNAME = "test-displayName"; //$NON-NLS-1$
133:         private static Realm realm;
134:         private EMFFormsDatabinding databindingService;
135:         private MultiReferenceSWTRenderer renderer;
136:         private MultiReferenceSWTRenderer compactVerticallyRenderer;
137:         private Shell shell;
138:         private EMFFormsLabelProvider labelProvider;
139:         private boolean showMoveButtons;
140:         private VTViewTemplateProvider templateProvider;
141:
142:         /**
143:          * Get {@link Realm} for the tests.
144:          */
145:         @BeforeClass
146:         public static void setUpBeforeClass() {
147:                 realm = Realm.getDefault();
148:
149:         }
150:
151:         /**
152:          * Set up executed before every test.
153:          * Mocks and registers the databinding and label services.
154:          * Creates a new {@link MultiReferenceSWTRenderer} to be tested. Mocks needed parameters and contents (e.g.
155:          * VControl, ViewModelContext).
156:          *
157:          * @throws DatabindingFailedException if the databinding failed
158:          * @throws NoLabelFoundException
159:          */
160:         @Before
161:         public void setUp() throws DatabindingFailedException, NoLabelFoundException {
162:                 databindingService = mock(EMFFormsDatabinding.class);
163:                 labelProvider = mock(EMFFormsLabelProvider.class);
164:                 when(labelProvider.getDescription(any(VDomainModelReference.class), any(EObject.class))).thenReturn(
165:                         Observables.constantObservableValue(TEST_DESCRIPTION));
166:                 when(labelProvider.getDisplayName(any(VDomainModelReference.class), any(EObject.class))).thenReturn(
167:                         Observables.constantObservableValue(TEST_DISPLAYNAME));
168:
169:                 shell = new Shell();
170:
171:                 final B eObject = TestFactory.eINSTANCE.createB();
172:                 final EStructuralFeature eStructuralFeature = TestPackage.Literals.B__CLIST;
173:
174:                 final ReportService reportService = mock(ReportService.class);
175:                 final ViewModelContext viewContext = mock(ViewModelContext.class);
176:                 final VControl vControl = Mockito.mock(VControl.class);
177:                 final Setting setting = mock(Setting.class);
178:                 final VDomainModelReference domainModelReference = mock(VDomainModelReference.class);
179:
180:                 when(viewContext.getDomainModel()).thenReturn(eObject);
181:                 when(viewContext.getViewModel()).thenReturn(vControl);
182:                 // Required for delete button enablement
183:                 when(viewContext.getService(DeleteService.class)).thenReturn(new EMFDeleteServiceImpl());
184:
185:                 when(vControl.getDomainModelReference()).thenReturn(domainModelReference);
186:
187:                 when(setting.getEObject()).thenReturn(eObject);
188:                 when(setting.getEStructuralFeature()).thenReturn(eStructuralFeature);
189:
190:                 Mockito.doReturn("UUID").when(vControl).getUuid(); //$NON-NLS-1$
191:
192:                 final ImageRegistryService imageRegistryService = mock(ImageRegistryService.class);
193:                 templateProvider = mock(VTViewTemplateProvider.class);
194:                 final EMFFormsLocalizationService l10n = mock(EMFFormsLocalizationService.class);
195:                 when(l10n.getString(any(Bundle.class), matches("_UI_\\w+_type"))).then(new Answer<String>() { //$NON-NLS-1$
196:                         @Override
197:                         public String answer(InvocationOnMock invocation) throws Throwable {
198:                                 final java.util.regex.Matcher m = Pattern.compile("_UI_(\\w+)_type") //$NON-NLS-1$
199:                                         .matcher((String) invocation.getArguments()[1]);
200:•                                if (m.matches()) { // It should, else we wouldn't be here
201:                                         return m.group(1);
202:                                 }
203:                                 return null;
204:                         }
205:                 });
206:                 when(viewContext.getService(EMFFormsLocalizationService.class)).thenReturn(l10n);
207:
208:                 // mock databinding to return a value property with changeable structural feature.
209:                 // Necessary due to the implementation of Bug 536250
210:                 final EStructuralFeature changeableFeature = mock(EStructuralFeature.class);
211:                 when(changeableFeature.isChangeable()).thenReturn(true);
212:                 final IValueProperty<?, ?> valueProperty = mock(IValueProperty.class);
213:                 when(valueProperty.getValueType()).thenReturn(changeableFeature);
214:                 when(databindingService.getValueProperty(any(VDomainModelReference.class), any(EObject.class)))
215:                         .thenReturn(valueProperty);
216:                 final TestObservableValue observableValue = mock(TestObservableValue.class);
217:                 when(observableValue.getObserved()).thenReturn(eObject);
218:                 when(observableValue.getValueType()).thenReturn(eStructuralFeature);
219:                 when(databindingService.getObservableValue(domainModelReference, eObject)).thenReturn(observableValue);
220:
221:                 renderer = new MultiReferenceSWTRenderer(vControl, viewContext, reportService, databindingService,
222:                         labelProvider, templateProvider, imageRegistryService, l10n) {
223:                         @Override
224:                         protected boolean showMoveDownButton() {
225:                                 return showMoveButtons;
226:                         }
227:
228:                         @Override
229:                         protected boolean showMoveUpButton() {
230:                                 return showMoveButtons;
231:                         }
232:                 };
233:                 renderer.getGridDescription(new SWTGridDescription());
234:
235:                 final VTViewTemplateProvider compactTemplateProvider = mock(VTViewTemplateProvider.class);
236:                 final VTTableStyleProperty tableStyleProperty = mock(VTTableStyleProperty.class);
237:                 when(compactTemplateProvider.getStyleProperties(vControl, viewContext))
238:                         .thenReturn(Collections.singleton((VTStyleProperty) tableStyleProperty));
239:                 when(tableStyleProperty.getRenderMode()).thenReturn(RenderMode.COMPACT_VERTICALLY);
240:                 compactVerticallyRenderer = new MultiReferenceSWTRenderer(vControl, viewContext, reportService,
241:                         databindingService, labelProvider, compactTemplateProvider, imageRegistryService);
242:                 compactVerticallyRenderer.init();
243:                 compactVerticallyRenderer.getGridDescription(new SWTGridDescription());
244:         }
245:
246:         /**
247:          *
248:          * Unregister databinding and label service after every test.
249:          */
250:         @After
251:         public void tearDown() {
252:         }
253:
254:         /**
255:          * Test if the initial data binding is working.
256:          *
257:          * @throws NoRendererFoundException Renderer could not be found
258:          * @throws NoPropertyDescriptorFoundExeption Property descriptor could not be found
259:          * @throws DatabindingFailedException if the databinding failed
260:          */
261:         @Test
262:         public void testDatabindingServiceUsageInitialBinding() throws NoRendererFoundException,
263:                 NoPropertyDescriptorFoundExeption, DatabindingFailedException {
264:                 final List<Integer> initialList = new LinkedList<Integer>();
265:                 initialList.add(2);
266:                 initialList.add(4);
267:                 final WritableList mockedObservableList = new WritableList(realm, initialList, Integer.class);
268:
269:                 final Table table = setUpDatabindingTests(mockedObservableList);
270:
271:                 assertEquals(mockedObservableList.size(), table.getItemCount());
272:                 for (int i = 0; i < mockedObservableList.size(); i++) {
273:                         assertEquals(mockedObservableList.get(i).toString(), table.getItems()[i].getText(0));
274:                 }
275:         }
276:
277:         /**
278:          * Tests whether adding values to the model is reflected in the control.
279:          *
280:          * @throws NoRendererFoundException Renderer could not be found
281:          * @throws NoPropertyDescriptorFoundExeption Property descriptor could not be found
282:          * @throws DatabindingFailedException if the databinding failed
283:          */
284:         @Test
285:         public void testDatabindingServiceUsageAddToModel() throws NoRendererFoundException,
286:                 NoPropertyDescriptorFoundExeption, DatabindingFailedException {
287:                 final List<EObject> initialList = new LinkedList<>();
288:                 initialList.add(TestFactory.eINSTANCE.createC());
289:                 initialList.add(TestFactory.eINSTANCE.createC());
290:                 final WritableList<EObject> mockedObservableList = new WritableList<EObject>(realm, initialList, EObject.class);
291:
292:                 final Table table = setUpDatabindingTests(mockedObservableList);
293:
294:                 mockedObservableList.add(TestFactory.eINSTANCE.createC());
295:
296:                 assertEquals(mockedObservableList.size(), table.getItemCount());
297:                 for (int i = 0; i < mockedObservableList.size(); i++) {
298:                         assertSame(mockedObservableList.get(i), table.getItems()[i].getData());
299:                 }
300:         }
301:
302:         /**
303:          * Tests whether removing values to the model is reflected in the control.
304:          *
305:          * @throws NoRendererFoundException Renderer could not be found
306:          * @throws NoPropertyDescriptorFoundExeption Property descriptor could not be found
307:          * @throws DatabindingFailedException if the databinding failed
308:          */
309:         @Test
310:         public void testDatabindingServiceUsageRemoveFromModel() throws NoRendererFoundException,
311:                 NoPropertyDescriptorFoundExeption, DatabindingFailedException {
312:                 final List<EObject> initialList = new LinkedList<>();
313:                 initialList.add(TestFactory.eINSTANCE.createC());
314:                 initialList.add(TestFactory.eINSTANCE.createC());
315:                 final WritableList<EObject> mockedObservableList = new WritableList<EObject>(realm, initialList, EObject.class);
316:
317:                 final Table table = setUpDatabindingTests(mockedObservableList);
318:
319:                 mockedObservableList.remove(0);
320:
321:                 assertEquals(mockedObservableList.size(), table.getItemCount());
322:                 for (int i = 0; i < mockedObservableList.size(); i++) {
323:                         assertSame(mockedObservableList.get(i), table.getItems()[i].getData());
324:                 }
325:         }
326:
327:         /**
328:          * Tests whether changing values of the model is reflected in the control.
329:          *
330:          * @throws NoRendererFoundException Renderer could not be found
331:          * @throws NoPropertyDescriptorFoundExeption Property descriptor could not be found
332:          * @throws DatabindingFailedException if the databinding failed
333:          */
334:         @Test
335:         public void testDatabindingServiceUsageChangeModel() throws NoRendererFoundException,
336:                 NoPropertyDescriptorFoundExeption, DatabindingFailedException {
337:                 final List<EObject> initialList = new LinkedList<>();
338:                 initialList.add(TestFactory.eINSTANCE.createC());
339:                 initialList.add(TestFactory.eINSTANCE.createC());
340:                 final WritableList<EObject> mockedObservableList = new WritableList<EObject>(realm, initialList, EObject.class);
341:
342:                 final Table table = setUpDatabindingTests(mockedObservableList);
343:
344:                 mockedObservableList.set(1, TestFactory.eINSTANCE.createC());
345:
346:                 assertEquals(mockedObservableList.size(), table.getItemCount());
347:                 for (int i = 0; i < mockedObservableList.size(); i++) {
348:                         assertSame(mockedObservableList.get(i), table.getItems()[i].getData());
349:                 }
350:         }
351:
352:         private Table setUpDatabindingTests(IObservableList<?> mockedObservableList) throws NoRendererFoundException,
353:                 NoPropertyDescriptorFoundExeption, DatabindingFailedException {
354:                 when(databindingService.getObservableList(any(VDomainModelReference.class), any(EObject.class))).thenReturn(
355:                         mockedObservableList);
356:                 final TestObservableValue observableValue = mock(TestObservableValue.class);
357:                 when(databindingService.getObservableValue(any(VDomainModelReference.class), any(EObject.class))).thenReturn(
358:                         observableValue);
359:                 when(observableValue.getObserved()).thenReturn(mock(EObject.class));
360:                 renderer.init();
361:                 final Composite composite = (Composite) renderer.render(new SWTGridCell(0, 0, renderer), shell);
362:                 final Composite controlComposite = (Composite) composite.getChildren()[1];
363:                 final Table table = (Table) controlComposite.getChildren()[0];
364:
365:                 return table;
366:         }
367:
368:         /**
369:          * Tests whether a {@link EMFFormsLabelProvider} is used to get labels.
370:          *
371:          * @throws NoRendererFoundException Renderer could not be found
372:          * @throws NoPropertyDescriptorFoundExeption Property descriptor could not be found
373:          * @throws DatabindingFailedException if the databinding failed
374:          */
375:         @Test
376:         public void testLabelServiceUsage() throws NoRendererFoundException, NoPropertyDescriptorFoundExeption,
377:                 DatabindingFailedException {
378:
379:                 final TestObservableValue observableValue = mock(TestObservableValue.class);
380:                 when(databindingService.getObservableValue(any(VDomainModelReference.class), any(EObject.class))).thenReturn(
381:                         observableValue);
382:                 when(observableValue.getObserved()).thenReturn(mock(EObject.class));
383:
384:                 renderer.init();
385:                 final Composite composite = (Composite) renderer.render(new SWTGridCell(0, 0, renderer), shell);
386:                 final Composite controlComposite = (Composite) composite.getChildren()[1];
387:                 final Table table = (Table) controlComposite.getChildren()[0];
388:
389:                 final TableColumn column = table.getColumn(0);
390:                 assertEquals(TEST_DISPLAYNAME, column.getText());
391:                 assertEquals(TEST_DESCRIPTION, column.getToolTipText());
392:         }
393:
394:         @Test
395:         public void testRenderModeDefaultGridDescription() {
396:                 final SWTGridDescription description = renderer.getGridDescription(new SWTGridDescription());
397:                 assertEquals(1, description.getColumns());
398:         }
399:
400:         @Test
401:         public void testRenderModeCompactVerticallyGridDescription() {
402:                 final SWTGridDescription description = compactVerticallyRenderer.getGridDescription(new SWTGridDescription());
403:                 assertEquals(2, description.getColumns());
404:         }
405:
406:         @Test
407:         public void testRenderModeCompactVerticallyRenderValidation()
408:                 throws NoPropertyDescriptorFoundExeption, NoRendererFoundException {
409:                 final Control renderedControl = compactVerticallyRenderer
410:                         .render(new SWTGridCell(0, 0, compactVerticallyRenderer), shell);
411:                 assertTrue(Label.class.isInstance(renderedControl));
412:                 assertTrue(String.class.isInstance(renderedControl.getData(SWTDataElementIdHelper.ELEMENT_ID_KEY)));
413:                 assertTrue(
414:                         String.class.cast(renderedControl.getData(SWTDataElementIdHelper.ELEMENT_ID_KEY)).contains("validation")); //$NON-NLS-1$
415:         }
416:
417:         @Test
418:         public void testRenderModeCompactVerticallyRenderTable()
419:                 throws NoPropertyDescriptorFoundExeption, NoRendererFoundException, DatabindingFailedException {
420:
421:                 final TestObservableValue observableValue = mock(TestObservableValue.class);
422:                 when(databindingService.getObservableValue(any(VDomainModelReference.class), any(EObject.class))).thenReturn(
423:                         observableValue);
424:                 when(observableValue.getObserved()).thenReturn(mock(EObject.class));
425:
426:                 final Control renderedControl = compactVerticallyRenderer
427:                         .render(new SWTGridCell(0, 1, compactVerticallyRenderer), shell);
428:                 assertTrue(Composite.class.isInstance(renderedControl));
429:
430:                 final Composite tableAndButtonsComposite = Composite.class.cast(renderedControl);
431:                 assertTrue(Composite.class.isInstance(tableAndButtonsComposite.getChildren()[0]));
432:
433:                 final Composite tableComposite = Composite.class.cast(tableAndButtonsComposite.getChildren()[0]);
434:                 assertTrue(Composite.class.isInstance(tableComposite.getChildren()[0]));
435:
436:                 final Composite tableControlComposite = Composite.class.cast(tableComposite.getChildren()[0]);
437:                 assertTrue(Table.class.isInstance(tableControlComposite.getChildren()[0]));
438:         }
439:
440:         @Test
441:         public void testRenderModeCompactVerticallyRenderButtons()
442:                 throws NoPropertyDescriptorFoundExeption, NoRendererFoundException, DatabindingFailedException {
443:
444:                 final TestObservableValue observableValue = mock(TestObservableValue.class);
445:                 when(databindingService.getObservableValue(any(VDomainModelReference.class), any(EObject.class))).thenReturn(
446:                         observableValue);
447:                 when(observableValue.getObserved()).thenReturn(mock(EObject.class));
448:
449:                 final Control renderedControl = compactVerticallyRenderer
450:                         .render(new SWTGridCell(0, 1, compactVerticallyRenderer), shell);
451:                 assertTrue(Composite.class.isInstance(renderedControl));
452:
453:                 final Composite tableAndButtonsComposite = Composite.class.cast(renderedControl);
454:                 assertTrue(Composite.class.isInstance(tableAndButtonsComposite.getChildren()[1]));
455:
456:                 final Composite buttonsComposite = Composite.class.cast(tableAndButtonsComposite.getChildren()[1]);
457:                 assertTrue(Button.class.isInstance(buttonsComposite.getChildren()[0]));
458:         }
459:
460:         @Test
461:         public void testRenderModeCompactGridDescription() {
462:                 final SWTGridDescription gridDescription = compactVerticallyRenderer.getGridDescription(null);
463:
464:                 assertThat(gridDescription.getColumns(), is(equalTo(2)));
465:
466:                 final SWTGridCell validationCell = gridDescription.getGrid().get(0);
467:                 assertThat(validationCell.getPreferredSize(), notNullValue());
468:                 assertThat(validationCell.isHorizontalGrab(), is(false));
469:                 assertThat(validationCell.getVerticalAlignment(), is(Alignment.BEGINNING));
470:
471:                 final SWTGridCell mainCell = gridDescription.getGrid().get(1);
472:                 assertThat(mainCell.getPreferredSize(), nullValue());
473:                 assertThat(mainCell.isHorizontalGrab(), is(true));
474:                 assertThat(mainCell.isVerticalGrab(), is(true));
475:         }
476:
477:         /**
478:          * Tests the tool-tip on the "Link" button.
479:          *
480:          * @see <a href="http://eclip.se/527736">bug 527736</a>
481:          */
482:         @Test
483:         public void testLinkButtonTooltip() {
484:                 final Table table = createLeaguePlayersTable();
485:                 final Button linkButton = SWTTestUtil.findControl(table.getParent().getParent(), 0, Button.class);
486:                 assertThat(linkButton.getToolTipText(), is("Link Player")); //$NON-NLS-1$
487:         }
488:
489:         /**
490:          * Tests the tool-tip on the "Link" button.
491:          *
492:          * @see <a href="http://eclip.se/527736">bug 527736</a>
493:          */
494:         @SuppressWarnings("unchecked")
495:         @Test
496:         public void testLinkButtonTooltipReflective() {
497:                 final EPackage leaguePackage = EcoreFactory.eINSTANCE.createEPackage();
498:                 leaguePackage.setName("Example"); //$NON-NLS-1$
499:                 leaguePackage.setNsPrefix("example"); //$NON-NLS-1$
500:                 leaguePackage.setNsURI("http:///example.ecore"); //$NON-NLS-1$
501:
502:                 final EClass leagueClass = EcoreFactory.eINSTANCE.createEClass();
503:                 leagueClass.setName("League"); //$NON-NLS-1$
504:                 final EClass playerClass = EcoreFactory.eINSTANCE.createEClass();
505:                 playerClass.setName("Player"); //$NON-NLS-1$
506:                 final EReference playersReference = EcoreFactory.eINSTANCE.createEReference();
507:                 playersReference.setEType(playerClass);
508:                 playersReference.setUpperBound(ETypedElement.UNBOUNDED_MULTIPLICITY);
509:                 leagueClass.getEStructuralFeatures().add(playersReference);
510:
511:                 leaguePackage.getEClassifiers().add(leagueClass);
512:                 leaguePackage.getEClassifiers().add(playerClass);
513:
514:                 final EObject league = EcoreUtil.create(leagueClass);
515:
516:                 final IObservableList<?> observableList = EMFProperties.list(playersReference).observe(league);
517:
518:                 Table table = null;
519:
520:                 try {
521:                         // Re-stub the domain model as our league
522:                         when(renderer.getViewModelContext().getDomainModel()).thenReturn(league);
523:                         when(databindingService.getObservableList(any(VDomainModelReference.class), any(EObject.class))).thenReturn(
524:                                 observableList);
525:                         final TestObservableValue observableValue = mock(TestObservableValue.class);
526:                         when(databindingService.getObservableValue(any(VDomainModelReference.class), any(EObject.class)))
527:                                 .thenReturn(observableValue);
528:                         when(observableValue.getObserved()).thenReturn(league);
529:                         when(observableValue.getValueType()).thenReturn(BowlingPackage.Literals.LEAGUE__PLAYERS);
530:                         renderer.init();
531:                         final Composite composite = (Composite) renderer.render(new SWTGridCell(0, 0, renderer), shell);
532:                         final Composite controlComposite = (Composite) composite.getChildren()[1];
533:                         table = (Table) controlComposite.getChildren()[0];
534:                         // BEGIN COMPLEX CODE
535:                 } catch (final Exception e) {
536:                         // END COMPLEX CODE
537:                         e.printStackTrace();
538:                         fail("Failed to render multi-reference table: " + e.getMessage()); //$NON-NLS-1$
539:                 }
540:
541:                 final Button linkButton = SWTTestUtil.findControl(table.getParent().getParent(), 0, Button.class);
542:                 assertThat(linkButton.getToolTipText(), is("Link Player")); //$NON-NLS-1$
543:         }
544:
545:         /**
546:          * Tests the tool-tip on the "Create and link new" button.
547:          *
548:          * @see <a href="http://eclip.se/527736">bug 527736</a>
549:          */
550:         @Test
551:         public void testCreateAndLinkNewButtonTooltip() {
552:                 final Table table = createLeaguePlayersTable();
553:                 final Button linkButton = SWTTestUtil.findControl(table.getParent().getParent(), 1, Button.class);
554:                 assertThat(linkButton.getToolTipText(), is("Create and link new Player")); //$NON-NLS-1$
555:         }
556:
557:         @Test
558:         public void testButtonData() {
559:                 showMoveButtons = true;
560:                 final Table table = createLeaguePlayersTable();
561:                 assertEquals(UUID_UP, SWTTestUtil.findControl(table.getParent().getParent(), 0, Button.class)
562:                         .getData(SWTDataElementIdHelper.ELEMENT_ID_KEY));
563:                 assertEquals(UUID_DOWN, SWTTestUtil.findControl(table.getParent().getParent(), 1, Button.class)
564:                         .getData(SWTDataElementIdHelper.ELEMENT_ID_KEY));
565:                 assertEquals(UUID_LINK, SWTTestUtil.findControl(table.getParent().getParent(), 2, Button.class)
566:                         .getData(SWTDataElementIdHelper.ELEMENT_ID_KEY));
567:                 assertEquals(UUID_ADD, SWTTestUtil.findControl(table.getParent().getParent(), 3, Button.class)
568:                         .getData(SWTDataElementIdHelper.ELEMENT_ID_KEY));
569:                 assertEquals(UUID_DELETE, SWTTestUtil.findControl(table.getParent().getParent(), 4, Button.class)
570:                         .getData(SWTDataElementIdHelper.ELEMENT_ID_KEY));
571:         }
572:
573:         /**
574:          * Tests the tool-tip on the "Link" button.
575:          *
576:          * @see <a href="http://eclip.se/527736">bug 527736</a>
577:          */
578:         @SuppressWarnings("unchecked")
579:         @Test
580:         public void testCreateAndLinkNewButtonTooltipReflective() {
581:                 final EPackage leaguePackage = EcoreFactory.eINSTANCE.createEPackage();
582:                 leaguePackage.setName("Example"); //$NON-NLS-1$
583:                 leaguePackage.setNsPrefix("example"); //$NON-NLS-1$
584:                 leaguePackage.setNsURI("http:///example.ecore"); //$NON-NLS-1$
585:
586:                 final EClass leagueClass = EcoreFactory.eINSTANCE.createEClass();
587:                 leagueClass.setName("League"); //$NON-NLS-1$
588:                 final EClass playerClass = EcoreFactory.eINSTANCE.createEClass();
589:                 playerClass.setName("Player"); //$NON-NLS-1$
590:                 final EReference playersReference = EcoreFactory.eINSTANCE.createEReference();
591:                 playersReference.setEType(playerClass);
592:                 playersReference.setUpperBound(ETypedElement.UNBOUNDED_MULTIPLICITY);
593:                 leagueClass.getEStructuralFeatures().add(playersReference);
594:
595:                 leaguePackage.getEClassifiers().add(leagueClass);
596:                 leaguePackage.getEClassifiers().add(playerClass);
597:
598:                 final EObject league = EcoreUtil.create(leagueClass);
599:
600:                 final IObservableList<?> observableList = EMFProperties.list(playersReference).observe(league);
601:
602:                 Table table = null;
603:
604:                 try {
605:                         // Re-stub the domain model as our league
606:                         when(renderer.getViewModelContext().getDomainModel()).thenReturn(league);
607:                         when(databindingService.getObservableList(any(VDomainModelReference.class), any(EObject.class))).thenReturn(
608:                                 observableList);
609:                         final TestObservableValue observableValue = mock(TestObservableValue.class);
610:                         when(databindingService.getObservableValue(any(VDomainModelReference.class), any(EObject.class)))
611:                                 .thenReturn(observableValue);
612:                         when(observableValue.getObserved()).thenReturn(league);
613:                         when(observableValue.getValueType()).thenReturn(BowlingPackage.Literals.LEAGUE__PLAYERS);
614:                         renderer.init();
615:                         final Composite composite = (Composite) renderer.render(new SWTGridCell(0, 0, renderer), shell);
616:                         final Composite controlComposite = (Composite) composite.getChildren()[1];
617:                         table = (Table) controlComposite.getChildren()[0];
618:                         // BEGIN COMPLEX CODE
619:                 } catch (final Exception e) {
620:                         // END COMPLEX CODE
621:                         e.printStackTrace();
622:                         fail("Failed to render multi-reference table: " + e.getMessage()); //$NON-NLS-1$
623:                 }
624:
625:                 final Button linkButton = SWTTestUtil.findControl(table.getParent().getParent(), 1, Button.class);
626:                 assertThat(linkButton.getToolTipText(), is("Create and link new Player")); //$NON-NLS-1$
627:         }
628:
629:         protected Table createLeaguePlayersTable() {
630:                 final League league = BowlingFactory.eINSTANCE.createLeague();
631:                 return createLeaguePlayersTable(league);
632:         }
633:
634:         protected Table createLeaguePlayersTable(final League league) {
635:                 final EditingDomain domain = new AdapterFactoryEditingDomain(
636:                         new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE), new BasicCommandStack());
637:                 final Resource bowling = domain.getResourceSet().createResource(URI.createURI("foo.ecore")); //$NON-NLS-1$
638:                 bowling.getContents().add(league);
639:
640:                 final IObservableList<?> observableList = EMFEditProperties
641:                         .list(domain, BowlingPackage.Literals.LEAGUE__PLAYERS).observe(league);
642:
643:                 Table result = null;
644:
645:                 try {
646:                         // Re-stub the domain model as our league
647:                         when(renderer.getViewModelContext().getDomainModel()).thenReturn(league);
648:                         // reset(databindingService);
649:                         when(databindingService.getObservableList(any(VDomainModelReference.class), any(EObject.class))).thenReturn(
650:                                 observableList);
651:                         final TestObservableValue observableValue = mock(TestObservableValue.class);
652:                         when(databindingService.getObservableValue(any(VDomainModelReference.class), any(EObject.class)))
653:                                 .thenReturn(observableValue);
654:                         when(observableValue.getObserved()).thenReturn(league);
655:                         when(observableValue.getValueType()).thenReturn(BowlingPackage.Literals.LEAGUE__PLAYERS);
656:                         renderer.init();
657:                         final Composite composite = (Composite) renderer.render(new SWTGridCell(0, 0, renderer), shell);
658:                         final Composite controlComposite = (Composite) composite.getChildren()[1];
659:                         result = (Table) controlComposite.getChildren()[0];
660:                         // BEGIN COMPLEX CODE
661:                 } catch (final Exception e) {
662:                         // END COMPLEX CODE
663:                         e.printStackTrace();
664:                         fail("Failed to render multi-reference table: " + e.getMessage()); //$NON-NLS-1$
665:                 }
666:
667:                 return result;
668:         }
669:
670:         protected Composite createFanVisitedTournaments() {
671:                 final EditingDomain domain = new AdapterFactoryEditingDomain(
672:                         new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE), new BasicCommandStack());
673:                 final Resource bowling = domain.getResourceSet().createResource(URI.createURI("foo.ecore")); //$NON-NLS-1$
674:                 final Fan fan = BowlingFactory.eINSTANCE.createFan();
675:                 bowling.getContents().add(fan);
676:
677:                 @SuppressWarnings("unchecked")
678:                 final IObservableList<?> observableList = EMFEditProperties
679:                         .list(domain, BowlingPackage.Literals.FAN__VISITED_TOURNAMENTS).observe(fan);
680:
681:                 try {
682:                         // Re-stub the domain model as our league
683:                         when(renderer.getViewModelContext().getDomainModel()).thenReturn(fan);
684:                         when(databindingService.getObservableList(any(VDomainModelReference.class), any(EObject.class))).thenReturn(
685:                                 observableList);
686:                         final TestObservableValue observableValue = mock(TestObservableValue.class);
687:                         when(databindingService.getObservableValue(any(VDomainModelReference.class), any(EObject.class)))
688:                                 .thenReturn(observableValue);
689:                         when(observableValue.getObserved()).thenReturn(fan);
690:                         when(observableValue.getValueType()).thenReturn(BowlingPackage.Literals.FAN__VISITED_TOURNAMENTS);
691:                         renderer.init();
692:                         return (Composite) renderer.render(new SWTGridCell(0, 0, renderer), shell);
693:                         // BEGIN COMPLEX CODE
694:                 } catch (final Exception e) {
695:                         // END COMPLEX CODE
696:                         e.printStackTrace();
697:                         fail("Failed to render multi-reference table: " + e.getMessage()); //$NON-NLS-1$
698:                         return null; // Cannot happen but is necessary for Java to be happy
699:                 }
700:         }
701:
702:         /**
703:          * Test that the control is disabled when it's set to read only.
704:          *
705:          * @throws DatabindingFailedException
706:          * @throws NoRendererFoundException
707:          * @throws NoPropertyDescriptorFoundExeption
708:          */
709:         @Test
710:         public void testReadOnlyNotDisablesControl()
711:                 throws DatabindingFailedException, NoRendererFoundException, NoPropertyDescriptorFoundExeption {
712:                 showMoveButtons = true;
713:                 when(renderer.getVElement().isEffectivelyReadonly()).thenReturn(true);
714:                 when(renderer.getVElement().isEffectivelyEnabled()).thenReturn(true);
715:                 final TestObservableValue observableValue = mock(TestObservableValue.class);
716:                 when(databindingService.getObservableValue(any(VDomainModelReference.class), any(EObject.class))).thenReturn(
717:                         observableValue);
718:                 when(observableValue.getObserved()).thenReturn(mock(EObject.class));
719:                 renderer.init();
720:                 final Composite composite = (Composite) renderer.render(new SWTGridCell(0, 0, renderer), shell);
721:                 renderer.finalizeRendering(shell);
722:                 // only buttons shall be not visible
723:                 // main composite shall still be enabled
724:                 assertTrue(composite.isEnabled());
725:         }
726:
727:         /**
728:          * Test that the control and buttons are visible when it's not read only.
729:          *
730:          * @throws DatabindingFailedException
731:          * @throws NoRendererFoundException
732:          * @throws NoPropertyDescriptorFoundExeption
733:          */
734:         @Test
735:         public void testNotReadOnlyButtonsVisibility()
736:                 throws DatabindingFailedException, NoRendererFoundException, NoPropertyDescriptorFoundExeption {
737:                 showMoveButtons = true;
738:                 when(renderer.getVElement().isReadonly()).thenReturn(false);
739:                 when(renderer.getVElement().isEffectivelyReadonly()).thenReturn(false);
740:                 final TestObservableValue observableValue = mock(TestObservableValue.class);
741:                 when(databindingService.getObservableValue(any(VDomainModelReference.class), any(EObject.class))).thenReturn(
742:                         observableValue);
743:                 when(observableValue.getObserved()).thenReturn(mock(EObject.class));
744:                 renderer.init();
745:                 final Composite composite = (Composite) renderer.render(new SWTGridCell(0, 0, renderer), shell);
746:                 renderer.finalizeRendering(shell);
747:
748:                 checkButton(composite, UUID_UP, true, false);
749:                 checkButton(composite, UUID_DOWN, true, false);
750:                 checkButton(composite, UUID_DELETE, true, false);
751:                 checkNoButton(composite, UUID_LINK);
752:                 checkNoButton(composite, UUID_ADD);
753:         }
754:
755:         /**
756:          * Test that the control is disabled when it's effectively set to read only because a parent is read only.
757:          * Test also buttons visibility
758:          *
759:          * @throws DatabindingFailedException
760:          * @throws NoRendererFoundException
761:          * @throws NoPropertyDescriptorFoundExeption
762:          */
763:         @Test
764:         public void testEffectivelyReadOnlyDisablesControl()
765:                 throws DatabindingFailedException, NoRendererFoundException, NoPropertyDescriptorFoundExeption {
766:                 showMoveButtons = true;
767:                 when(renderer.getVElement().isReadonly()).thenReturn(false);
768:                 when(renderer.getVElement().isEffectivelyReadonly()).thenReturn(true);
769:                 when(renderer.getVElement().isEffectivelyEnabled()).thenReturn(true);
770:                 // Simulate control's parent that is set to readOnly
771:                 final VView parent = mock(VView.class);
772:                 when(parent.isReadonly()).thenReturn(true);
773:                 when(renderer.getVElement().eContainer()).thenReturn(parent);
774:
775:                 final TestObservableValue observableValue = mock(TestObservableValue.class);
776:                 when(databindingService.getObservableValue(any(VDomainModelReference.class), any(EObject.class))).thenReturn(
777:                         observableValue);
778:                 when(observableValue.getObserved()).thenReturn(mock(EObject.class));
779:                 renderer.init();
780:                 final Composite composite = (Composite) renderer.render(new SWTGridCell(0, 0, renderer), shell);
781:                 renderer.finalizeRendering(shell);
782:                 // read only does not disable control, but hides button
783:                 assertTrue(composite.isEnabled());
784:                 checkButton(composite, UUID_UP, false, false);
785:                 checkButton(composite, UUID_DOWN, false, false);
786:                 checkButton(composite, UUID_DELETE, false, false);
787:                 checkNoButton(composite, UUID_LINK);
788:                 checkNoButton(composite, UUID_ADD);
789:         }
790:
791:         /**
792:          * Test that the control is disabled when VElement enablement is set to false
793:          *
794:          * @throws DatabindingFailedException
795:          * @throws NoRendererFoundException
796:          * @throws NoPropertyDescriptorFoundExeption
797:          */
798:         @Test
799:         public void testControlDisabled()
800:                 throws DatabindingFailedException, NoRendererFoundException, NoPropertyDescriptorFoundExeption {
801:                 showMoveButtons = true;
802:                 when(renderer.getVElement().isEffectivelyReadonly()).thenReturn(false);
803:                 when(renderer.getVElement().isEnabled()).thenReturn(false);
804:
805:                 // Simulate control's parent that is set to readOnly
806:                 final VView parent = mock(VView.class);
807:                 when(parent.isReadonly()).thenReturn(true);
808:                 when(renderer.getVElement().eContainer()).thenReturn(parent);
809:
810:                 final TestObservableValue observableValue = mock(TestObservableValue.class);
811:                 when(databindingService.getObservableValue(any(VDomainModelReference.class), any(EObject.class))).thenReturn(
812:                         observableValue);
813:                 when(observableValue.getObserved()).thenReturn(mock(EObject.class));
814:                 renderer.init();
815:                 final Composite composite = (Composite) renderer.render(new SWTGridCell(0, 0, renderer), shell);
816:                 renderer.finalizeRendering(shell);
817:                 assertFalse(composite.isEnabled());
818:
819:                 checkButton(composite, UUID_UP, true, false);
820:                 checkButton(composite, UUID_DOWN, true, false);
821:                 checkNoButton(composite, UUID_LINK);
822:                 checkButton(composite, UUID_DELETE, true, false);
823:         }
824:
825:         /**
826:          * Test that the control is enabled when VElement enablement is set to true
827:          *
828:          * @throws DatabindingFailedException
829:          * @throws NoRendererFoundException
830:          * @throws NoPropertyDescriptorFoundExeption
831:          */
832:         @Test
833:         public void testControlEnabled()
834:                 throws DatabindingFailedException, NoRendererFoundException, NoPropertyDescriptorFoundExeption {
835:                 showMoveButtons = true;
836:                 when(renderer.getVElement().isEffectivelyReadonly()).thenReturn(false);
837:                 when(renderer.getVElement().isEffectivelyEnabled()).thenReturn(true);
838:                 when(renderer.getVElement().isEnabled()).thenReturn(true);
839:                 when(renderer.getVElement().isVisible()).thenReturn(true);
840:
841:                 final VTReferenceStyleProperty property = VTReferenceFactory.eINSTANCE.createReferenceStyleProperty();
842:                 property.setShowLinkButtonForContainmentReferences(true);
843:                 when(templateProvider.getStyleProperties(any(VElement.class), any(ViewModelContext.class)))
844:                         .thenReturn(Collections.<VTStyleProperty> singleton(property));
845:
846:                 final League league = BowlingFactory.eINSTANCE.createLeague();
847:                 createPlayers(league, "player1", "player2", "player3"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
848:                 final Table table = createLeaguePlayersTable(league);
849:                 when(renderer.getVElement().isEffectivelyReadonly()).thenReturn(false);
850:                 when(renderer.getVElement().isEffectivelyEnabled()).thenReturn(true);
851:
852:                 /* setup rendering */
853:                 final SWTGridDescription gridDescription = renderer.getGridDescription(null);
854:                 final SWTGridCell lastGridCell = gridDescription.getGrid().get(gridDescription.getGrid().size() - 1);
855:
856:                 /* render */
857:                 final Control control = renderer.render(lastGridCell, shell);
858:                 renderer.finalizeRendering(shell);
859:                 SWTTestUtil.findControl(control, 0, Table.class);
860:
861:                 // check table itself
862:                 assertTrue(table.getVisible());
863:                 assertTrue(table.isEnabled());
864:
865:                 final Button upButton = SWTTestUtil.findControlById(control, UUID_UP, Button.class);
866:                 checkControl(upButton, true, false);
867:
868:                 final Button deleteButton = SWTTestUtil.findControlById(control, UUID_DELETE, Button.class);
869:                 checkControl(deleteButton, true, false);
870:
871:                 final IObservableList<?> list = databindingService.getObservableList(null, league);
872:                 renderer.getTableViewer().setSelection(new StructuredSelection(list.get(0)), true);
873:                 SWTTestUtil.waitForUIThread();
874:
875:                 // up may be false, as first element is selected (not yet implemented)
876:                 checkControl(upButton, true, false);
877:                 checkControl(deleteButton, true, true);
878:
879:                 renderer.getTableViewer().setSelection(new StructuredSelection(list.get(1)), true);
880:                 SWTTestUtil.waitForUIThread();
881:
882:                 // up may be false, as first element is selected (not yet implemented)
883:                 checkControl(upButton, true, true);
884:                 checkControl(deleteButton, true, true);
885:         }
886:
887:         private void createPlayers(League league, String... names) {
888:                 for (final String name : names) {
889:                         final Player p = BowlingFactory.eINSTANCE.createPlayer();
890:                         p.setName(name);
891:                         league.getPlayers().add(p);
892:                 }
893:         }
894:
895:         /**
896:          * By default, the 'create and link new' button should be shown for cross references (legacy behavior).
897:          */
898:         @Test
899:         public void createAndLinkButton_crossRefNoReferenceStyle() {
900:                 final Composite rendered = createFanVisitedTournaments();
901:                 final Button linkButton = SWTTestUtil.findControl(rendered, 0, Button.class);
902:                 assertThat(linkButton.getToolTipText(), is("Link Tournament")); //$NON-NLS-1$
903:                 final Button createButton = SWTTestUtil.findControl(rendered, 1, Button.class);
904:                 assertThat(createButton.getToolTipText(), is("Create and link new Tournament")); //$NON-NLS-1$
905:                 final Button deleteButton = SWTTestUtil.findControl(rendered, 2, Button.class);
906:                 assertThat(deleteButton.getToolTipText(), is("Delete")); //$NON-NLS-1$
907:         }
908:
909:         @Test
910:         public void createAndLinkButton_crossRefReferenceStyleTrue() {
911:                 final VTReferenceStyleProperty property = VTReferenceFactory.eINSTANCE.createReferenceStyleProperty();
912:                 property.setShowCreateAndLinkButtonForCrossReferences(true);
913:                 when(templateProvider.getStyleProperties(any(VElement.class), any(ViewModelContext.class)))
914:                         .thenReturn(Collections.<VTStyleProperty> singleton(property));
915:
916:                 final Composite rendered = createFanVisitedTournaments();
917:                 final Button linkButton = SWTTestUtil.findControl(rendered, 0, Button.class);
918:                 assertThat(linkButton.getToolTipText(), is("Link Tournament")); //$NON-NLS-1$
919:                 final Button createButton = SWTTestUtil.findControl(rendered, 1, Button.class);
920:                 assertThat(createButton.getToolTipText(), is("Create and link new Tournament")); //$NON-NLS-1$
921:                 final Button deleteButton = SWTTestUtil.findControl(rendered, 2, Button.class);
922:                 assertThat(deleteButton.getToolTipText(), is("Delete")); //$NON-NLS-1$
923:         }
924:
925:         @Test
926:         public void createAndLinkButton_crossRefReferenceStyleFalse() {
927:                 final VTReferenceStyleProperty property = VTReferenceFactory.eINSTANCE.createReferenceStyleProperty();
928:                 property.setShowCreateAndLinkButtonForCrossReferences(false);
929:                 when(templateProvider.getStyleProperties(any(VElement.class), any(ViewModelContext.class)))
930:                         .thenReturn(Collections.<VTStyleProperty> singleton(property));
931:
932:                 final Composite rendered = createFanVisitedTournaments();
933:                 final Button linkButton = SWTTestUtil.findControl(rendered, 0, Button.class);
934:                 assertThat(linkButton.getToolTipText(), is("Link Tournament")); //$NON-NLS-1$
935:                 final Button deleteButton = SWTTestUtil.findControl(rendered, 1, Button.class);
936:                 assertThat(deleteButton.getToolTipText(), is("Delete")); //$NON-NLS-1$
937:
938:                 try {
939:                         SWTTestUtil.findControl(rendered, 2, Button.class);
940:                         fail(
941:                                 "There must not be a third button for a non-containment reference with disabled 'create and link' button."); //$NON-NLS-1$
942:                 } catch (final NoSuchElementException ex) {
943:                         // This is what we expect => Test is successful
944:                         // Cannot use expected in @Test annotation because the test must not succeed if the link or the delete
945:                         // button are not found.
946:                 }
947:         }
948:
949:         /**
950:          * For a containment ref the 'create and link' must still be shown even if the reference style property is set to
951:          * false.
952:          */
953:         @Test
954:         public void createAndLinkButton_containmentRefReferenceStyleFalse() {
955:                 final VTReferenceStyleProperty property = VTReferenceFactory.eINSTANCE.createReferenceStyleProperty();
956:                 property.setShowCreateAndLinkButtonForCrossReferences(false);
957:                 when(templateProvider.getStyleProperties(any(VElement.class), any(ViewModelContext.class)))
958:                         .thenReturn(Collections.<VTStyleProperty> singleton(property));
959:
960:                 final Composite rendered = createLeaguePlayersTable().getParent().getParent();
961:                 final Button linkButton = SWTTestUtil.findControl(rendered, 0, Button.class);
962:                 assertThat(linkButton.getToolTipText(), is("Link Player")); //$NON-NLS-1$
963:                 final Button createButton = SWTTestUtil.findControl(rendered, 1, Button.class);
964:                 assertThat(createButton.getToolTipText(), is("Create and link new Player")); //$NON-NLS-1$
965:                 final Button deleteButton = SWTTestUtil.findControl(rendered, 2, Button.class);
966:                 assertThat(deleteButton.getToolTipText(), is("Delete")); //$NON-NLS-1$
967:         }
968:
969:         /**
970:          * For a cross ref the 'link' button must still be shown even if the reference style property is set to false.
971:          */
972:         @Test
973:         public void linkButton_crossRefReferenceStyleFalse() {
974:                 final VTReferenceStyleProperty property = VTReferenceFactory.eINSTANCE.createReferenceStyleProperty();
975:                 property.setShowLinkButtonForContainmentReferences(false);
976:                 when(templateProvider.getStyleProperties(any(VElement.class), any(ViewModelContext.class)))
977:                         .thenReturn(Collections.<VTStyleProperty> singleton(property));
978:
979:                 final Composite rendered = createFanVisitedTournaments();
980:                 final Button linkButton = SWTTestUtil.findControl(rendered, 0, Button.class);
981:                 assertThat(linkButton.getToolTipText(), is("Link Tournament")); //$NON-NLS-1$
982:                 final Button createButton = SWTTestUtil.findControl(rendered, 1, Button.class);
983:                 assertThat(createButton.getToolTipText(), is("Create and link new Tournament")); //$NON-NLS-1$
984:                 final Button deleteButton = SWTTestUtil.findControl(rendered, 2, Button.class);
985:                 assertThat(deleteButton.getToolTipText(), is("Delete")); //$NON-NLS-1$
986:         }
987:
988:         /**
989:          * By default, the 'link new' button must be shown for containment references (legacy behavior).
990:          */
991:         @Test
992:         public void linkButton_containmentRefNoReferenceStyle() {
993:                 final Composite rendered = createLeaguePlayersTable().getParent().getParent();
994:                 final Button linkButton = SWTTestUtil.findControl(rendered, 0, Button.class);
995:                 assertThat(linkButton.getToolTipText(), is("Link Player")); //$NON-NLS-1$
996:                 final Button createButton = SWTTestUtil.findControl(rendered, 1, Button.class);
997:                 assertThat(createButton.getToolTipText(), is("Create and link new Player")); //$NON-NLS-1$
998:                 final Button deleteButton = SWTTestUtil.findControl(rendered, 2, Button.class);
999:                 assertThat(deleteButton.getToolTipText(), is("Delete")); //$NON-NLS-1$
1000:         }
1001:
1002:         @Test
1003:         public void linkButton_containmentRefReferenceStyleTrue() {
1004:                 final VTReferenceStyleProperty property = VTReferenceFactory.eINSTANCE.createReferenceStyleProperty();
1005:                 property.setShowLinkButtonForContainmentReferences(true);
1006:                 when(templateProvider.getStyleProperties(any(VElement.class), any(ViewModelContext.class)))
1007:                         .thenReturn(Collections.<VTStyleProperty> singleton(property));
1008:
1009:                 final Composite rendered = createLeaguePlayersTable().getParent().getParent();
1010:                 final Button linkButton = SWTTestUtil.findControl(rendered, 0, Button.class);
1011:                 assertThat(linkButton.getToolTipText(), is("Link Player")); //$NON-NLS-1$
1012:                 final Button createButton = SWTTestUtil.findControl(rendered, 1, Button.class);
1013:                 assertThat(createButton.getToolTipText(), is("Create and link new Player")); //$NON-NLS-1$
1014:                 final Button deleteButton = SWTTestUtil.findControl(rendered, 2, Button.class);
1015:                 assertThat(deleteButton.getToolTipText(), is("Delete")); //$NON-NLS-1$
1016:         }
1017:
1018:         @Test
1019:         public void linkButton_containmentRefReferenceStyleFalse() {
1020:                 final VTReferenceStyleProperty property = VTReferenceFactory.eINSTANCE.createReferenceStyleProperty();
1021:                 property.setShowLinkButtonForContainmentReferences(false);
1022:                 when(templateProvider.getStyleProperties(any(VElement.class), any(ViewModelContext.class)))
1023:                         .thenReturn(Collections.<VTStyleProperty> singleton(property));
1024:
1025:                 final Composite rendered = createLeaguePlayersTable().getParent().getParent();
1026:                 final Button createButton = SWTTestUtil.findControl(rendered, 0, Button.class);
1027:                 assertThat(createButton.getToolTipText(), is("Create and link new Player")); //$NON-NLS-1$
1028:                 final Button deleteButton = SWTTestUtil.findControl(rendered, 1, Button.class);
1029:                 assertThat(deleteButton.getToolTipText(), is("Delete")); //$NON-NLS-1$ NON-NLS-1$
1030:
1031:                 try {
1032:                         SWTTestUtil.findControl(rendered, 2, Button.class);
1033:                         fail(
1034:                                 "There must not be a third button for a containment reference with disabled 'link' button."); //$NON-NLS-1$
1035:                 } catch (final NoSuchElementException ex) {
1036:                         // This is what we expect => Test is successful
1037:                         // Cannot use expected in @Test annotation because the test must not succeed if the 'create and link' or the
1038:                         // delete button are not found.
1039:                 }
1040:         }
1041:
1042:         @Test
1043:         public void compare()
1044:                 throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, DatabindingFailedException {
1045:                 showMoveButtons = false;
1046:
1047:                 // Label: Player a2
1048:                 final Player p1 = BowlingFactory.eINSTANCE.createPlayer();
1049:                 p1.setName("a2"); //$NON-NLS-1$
1050:
1051:                 // Label: Player a10
1052:                 final Player p2 = BowlingFactory.eINSTANCE.createPlayer();
1053:                 p2.setName("a10a"); //$NON-NLS-1$
1054:
1055:                 // Label: Player a10a
1056:                 final Player p3 = BowlingFactory.eINSTANCE.createPlayer();
1057:                 p3.setName("a10"); //$NON-NLS-1$
1058:
1059:                 final League league = BowlingFactory.eINSTANCE.createLeague();
1060:                 league.getPlayers().add(p1);
1061:                 league.getPlayers().add(p2);
1062:                 league.getPlayers().add(p3);
1063:
1064:                 final Table playersTable = createLeaguePlayersTable(league);
1065:
1066:                 // Initially, items should be sorted by insertion order
1067:                 assertEquals(SWT.NONE, playersTable.getSortDirection());
1068:                 assertItemOrder(playersTable, p1, p2, p3);
1069:
1070:                 SWTTestUtil.selectWidget(playersTable.getColumn(0));
1071:                 SWTTestUtil.waitForUIThread();
1072:
1073:                 // ascending
1074:                 assertEquals(SWT.UP, playersTable.getSortDirection());
1075:                 assertItemOrder(playersTable, p1, p3, p2);
1076:
1077:                 SWTTestUtil.selectWidget(playersTable.getColumn(0));
1078:                 SWTTestUtil.waitForUIThread();
1079:
1080:                 // descending
1081:                 assertEquals(SWT.DOWN, playersTable.getSortDirection());
1082:                 assertItemOrder(playersTable, p2, p3, p1);
1083:
1084:                 SWTTestUtil.selectWidget(playersTable.getColumn(0));
1085:                 SWTTestUtil.waitForUIThread();
1086:
1087:                 // insertion order again
1088:                 assertEquals(SWT.NONE, playersTable.getSortDirection());
1089:                 assertItemOrder(playersTable, p1, p2, p3);
1090:         }
1091:
1092:         private static void assertItemOrder(Table table, Object... objects) {
1093:                 assertEquals(objects.length, table.getItemCount());
1094:                 final TableItem[] items = table.getItems();
1095:                 for (int i = 0; i < items.length; i++) {
1096:                         assertSame(objects[i], items[i].getData());
1097:                 }
1098:         }
1099:
1100:         @Test
1101:         public void testVisibleOnWritable()
1102:                 throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, DatabindingFailedException {
1103:
1104:                 final VTReferenceStyleProperty property = VTReferenceFactory.eINSTANCE.createReferenceStyleProperty();
1105:                 property.setShowLinkButtonForContainmentReferences(true);
1106:                 when(templateProvider.getStyleProperties(any(VElement.class), any(ViewModelContext.class)))
1107:                         .thenReturn(Collections.<VTStyleProperty> singleton(property));
1108:
1109:                 createLeaguePlayersTable();
1110:                 when(renderer.getVElement().isEffectivelyReadonly()).thenReturn(false);
1111:                 when(renderer.getVElement().isEffectivelyEnabled()).thenReturn(true);
1112:
1113:                 /* setup rendering */
1114:                 final SWTGridDescription gridDescription = renderer.getGridDescription(null);
1115:                 final SWTGridCell lastGridCell = gridDescription.getGrid().get(gridDescription.getGrid().size() - 1);
1116:
1117:                 /* render */
1118:                 final Control control = renderer.render(lastGridCell, shell);
1119:                 renderer.finalizeRendering(shell);
1120:                 final Button upButton = SWTTestUtil.findControl(control, 0, Button.class);
1121:                 final Table table = SWTTestUtil.findControl(control, 0, Table.class);
1122:
1123:                 // check table itself
1124:                 assertTrue(table.getVisible());
1125:                 assertTrue(table.isEnabled());
1126:                 assertTrue(upButton.getEnabled());
1127:         }
1128:
1129:         @Test
1130:         public void testActivateOnEnable()
1131:                 throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, DatabindingFailedException {
1132:                 final VTReferenceStyleProperty property = VTReferenceFactory.eINSTANCE.createReferenceStyleProperty();
1133:                 property.setShowLinkButtonForContainmentReferences(true);
1134:                 when(templateProvider.getStyleProperties(any(VElement.class), any(ViewModelContext.class)))
1135:                         .thenReturn(Collections.<VTStyleProperty> singleton(property));
1136:
1137:                 createLeaguePlayersTable();
1138:                 when(renderer.getVElement().isEffectivelyReadonly()).thenReturn(false);
1139:                 when(renderer.getVElement().isEffectivelyEnabled()).thenReturn(true);
1140:
1141:                 /* setup rendering */
1142:                 final SWTGridDescription gridDescription = renderer.getGridDescription(null);
1143:                 final SWTGridCell lastGridCell = gridDescription.getGrid().get(gridDescription.getGrid().size() - 1);
1144:
1145:                 /* render */
1146:                 final Control control = renderer.render(lastGridCell, shell);
1147:                 renderer.finalizeRendering(shell);
1148:                 final Button upButton = SWTTestUtil.findControl(control, 0, Button.class);
1149:                 final Table table = SWTTestUtil.findControl(control, 0, Table.class);
1150:
1151:                 // check table itself
1152:                 assertTrue(table.isEnabled());
1153:
1154:                 checkControl(upButton, true, true);
1155:                 assertTrue(upButton.getParent().getVisible());
1156:
1157:         }
1158:
1159:         @Test
1160:         public void testButtonsNotVisibleOnReadOnly()
1161:                 throws NoRendererFoundException, NoPropertyDescriptorFoundExeption, DatabindingFailedException {
1162:                 final VTReferenceStyleProperty property = VTReferenceFactory.eINSTANCE.createReferenceStyleProperty();
1163:                 property.setShowLinkButtonForContainmentReferences(true);
1164:                 when(templateProvider.getStyleProperties(any(VElement.class), any(ViewModelContext.class)))
1165:                         .thenReturn(Collections.<VTStyleProperty> singleton(property));
1166:
1167:                 createLeaguePlayersTable();
1168:                 when(renderer.getVElement().isEffectivelyReadonly()).thenReturn(true);
1169:                 when(renderer.getVElement().isEffectivelyEnabled()).thenReturn(true);
1170:
1171:                 /* setup rendering */
1172:                 final SWTGridDescription gridDescription = renderer.getGridDescription(null);
1173:                 final SWTGridCell lastGridCell = gridDescription.getGrid().get(gridDescription.getGrid().size() - 1);
1174:
1175:                 /* render */
1176:                 final Control control = renderer.render(lastGridCell, shell);
1177:                 renderer.finalizeRendering(shell);
1178:                 final Button upButton = SWTTestUtil.findControl(control, 0, Button.class);
1179:
1180:                 /* by default, up is disabled (no selection) */
1181:                 assertFalse(upButton.getVisible());
1182:         }
1183:
1184:         /**
1185:          * Helper Interface for mocking.
1186:          *
1187:          * @author Eugen Neufeld
1188:          *
1189:          */
1190:         public interface TestObservableValue extends IObservableValue, IObserving {
1191:         }
1192:
1193:         private void checkButton(Composite root, String elementId, boolean visible, boolean enabled) {
1194:                 final Button button = SWTTestUtil.findControlById(root, elementId, Button.class);
1195:                 checkControl(button, visible, enabled);
1196:         }
1197:
1198:         private void checkNoButton(Composite root, String elementId) {
1199:                 final Button button = SWTTestUtil.findControlById(root, elementId, Button.class);
1200:                 assertThat(button, nullValue());
1201:         }
1202:
1203:         private void checkControl(Control control, boolean visible, boolean enabled) {
1204:                 assertThat(control, notNullValue());
1205:                 assertThat(control.getVisible(), is(visible));
1206:                 // no selection
1207:                 assertThat(control.getEnabled(), is(enabled));
1208:         }
1209: }