/** * Copyright (c) 2014 - 2017 Frank Appel * 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: * Frank Appel - initial API and implementation */ package com.codeaffine.eclipse.swt.widget.scrollable; import static com.codeaffine.eclipse.swt.test.util.ShellHelper.createShell; import static com.codeaffine.eclipse.swt.widget.scrollable.StyledTextAdapter.UNSUPPORTED_CREATION; import static com.codeaffine.eclipse.swt.widget.scrollable.StyledTextHelper.createStyledText; import static com.codeaffine.test.util.lang.ThrowableCaptor.thrownBy; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import java.util.Optional; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DragSource; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.RowData; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import com.codeaffine.eclipse.swt.test.util.DisplayHelper; import com.codeaffine.eclipse.swt.test.util.SWTEventHelper; import com.codeaffine.eclipse.swt.test.util.SWTIgnoreConditions.NonWindowsPlatform; import com.codeaffine.eclipse.swt.util.ReadAndDispatch; import com.codeaffine.test.util.junit.ConditionalIgnoreRule; import com.codeaffine.test.util.junit.ConditionalIgnoreRule.ConditionalIgnore; import com.codeaffine.test.util.lang.ThrowableCaptor; public class StyledTextAdapterTest { @Rule public final ConditionalIgnoreRule ignoreRule = new ConditionalIgnoreRule(); @Rule public final DisplayHelper displayHelper = new DisplayHelper(); private ScrollableAdapterFactory adapterFactory; private StyledTextAdapter adapter; private StyledText styledText; private Object layoutData; private Shell shell; @Before public void setUp() { adapterFactory = new ScrollableAdapterFactory(); shell = createShell( displayHelper ); styledText = createStyledText( shell ); layoutData = new Object(); styledText.setLayoutData( layoutData ); adapter = adapterFactory.create( styledText, StyledTextAdapter.class ).get(); } @Test @ConditionalIgnore( condition = NonWindowsPlatform.class ) public void adapt() { assertThat( adapter.getChildren() ).contains( styledText ); assertThat( adapter.getLayout() ).isInstanceOf( ScrollableLayout.class ); assertThat( adapter.getBounds() ).isEqualTo( shell.getClientArea() ); assertThat( adapter.getLayoutData() ).isSameAs( layoutData ); assertThat( adapter.getScrollable() ).isSameAs( styledText ); } @Test public void setLayout() { Throwable actual = ThrowableCaptor.thrownBy( () -> adapter.setLayout( new FillLayout() ) ); assertThat( actual ).isInstanceOf( UnsupportedOperationException.class ); } @Test @ConditionalIgnore( condition = NonWindowsPlatform.class ) public void disposalOfAdapter() { adapter.dispose(); assertThat( styledText.isDisposed() ).isTrue(); } @Test @ConditionalIgnore( condition = NonWindowsPlatform.class ) public void disposalOfStyledText() { styledText.dispose(); assertThat( adapter.isDisposed() ).isTrue(); assertThat( shell.getChildren() ).isEmpty(); } @Test public void disposalWithDragSourceOnStyledText() { StyledText styledText = new TestStyledTextFactory().create( shell ); ScrollableAdapterFactoryHelper.adapt( styledText, StyledTextAdapter.class ); DragSource dragSource = new DragSource( styledText, DND.DROP_MOVE | DND.DROP_COPY ); shell.dispose(); assertThat( dragSource.isDisposed() ).isTrue(); } @Test public void constructor() { Throwable actual = thrownBy( () -> new StyledTextAdapter() ); assertThat( actual ) .hasMessageContaining( UNSUPPORTED_CREATION ) .isInstanceOf( UnsupportedOperationException.class ); } @Test @ConditionalIgnore( condition = NonWindowsPlatform.class ) public void changeStyledTextBoundsWithVisibleScrollBars() { openShellWithoutLayout(); waitForReconciliation(); styledText.setBounds( expectedBounds() ); waitForReconciliation(); assertThat( adapter.getBounds() ).isEqualTo( expectedBounds() ); assertThat( styledText.getBounds() ).isNotEqualTo( expectedBounds() ); } @Test @ConditionalIgnore( condition = NonWindowsPlatform.class ) public void changeStyledTextVisibility() { waitForReconciliation(); styledText.setVisible( false ); waitForReconciliation(); assertThat( adapter.getVisible() ).isFalse(); } @Test @ConditionalIgnore( condition = NonWindowsPlatform.class ) public void changeStyledTextEnablement() { waitForReconciliation(); styledText.setEnabled( false ); waitForReconciliation(); assertThat( adapter.getEnabled() ).isFalse(); } @Test public void adaptWithoutScrollBarStyle() { openShellWithoutLayout(); styledText = new StyledText( shell, SWT.NONE ); Optional<StyledTextAdapter> adapter = adapterFactory.create( styledText, StyledTextAdapter.class ); assertThat( adapter.isPresent() ).isFalse(); } @Test public void getLayoutData() { RowData expected = new RowData(); styledText.setLayoutData( expected ); Object actual = adapter.getLayoutData(); assertThat( actual ).isSameAs( expected ); } @Test public void setLayoutData() { Object expected = new Object(); adapter.setLayoutData( expected ); Object actual = styledText.getLayoutData(); assertThat( actual ).isSameAs( expected ); } @Test public void computeSize() { Point expected = styledText.computeSize( SWT.DEFAULT, SWT.DEFAULT, true ); Point actual = adapter.computeSize( SWT.DEFAULT, SWT.DEFAULT, true ); assertThat( actual ).isEqualTo( expected ); } @Test @ConditionalIgnore( condition = NonWindowsPlatform.class ) // Workaround for https://github.com/fappel/xiliary/issues/63 public void avoidMouseWheelEventPropagationToFlatScrollBars() { Listener listener = mock( Listener.class ); adapter.addListener( SWT.MouseWheel, listener ); SWTEventHelper.trigger( SWT.MouseWheel ).on( adapter ); verify( listener, never() ).handleEvent( any( Event.class ) ); } private void openShellWithoutLayout() { shell.setLayout( null ); shell.open(); } private void waitForReconciliation() { new ReadAndDispatch().spinLoop( shell, WatchDog.DELAY * 6 ); } private Rectangle expectedBounds() { Rectangle clientArea = shell.getClientArea(); return new Rectangle( 5, 10, clientArea.width - 10, clientArea.height - 20 ); } }