/** * 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.scrollbar; import static com.codeaffine.eclipse.swt.test.util.DisplayHelper.flushPendingEvents; import static com.codeaffine.eclipse.swt.widget.scrollbar.FlatScrollBar.DEFAULT_INCREMENT; import static com.codeaffine.eclipse.swt.widget.scrollbar.FlatScrollBar.DEFAULT_MAXIMUM; import static com.codeaffine.eclipse.swt.widget.scrollbar.FlatScrollBar.DEFAULT_MINIMUM; import static com.codeaffine.eclipse.swt.widget.scrollbar.FlatScrollBar.DEFAULT_PAGE_INCREMENT; import static com.codeaffine.eclipse.swt.widget.scrollbar.FlatScrollBar.DEFAULT_SELECTION; import static com.codeaffine.eclipse.swt.widget.scrollbar.FlatScrollBar.DEFAULT_THUMB; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentCaptor.forClass; import static org.mockito.Matchers.any; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Layout; 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 org.mockito.ArgumentCaptor; import com.codeaffine.eclipse.swt.test.util.DisplayHelper; import com.codeaffine.eclipse.swt.test.util.SWTIgnoreConditions.GtkPlatform; import com.codeaffine.eclipse.swt.test.util.SWTIgnoreConditions.NonWindowsPlatform; import com.codeaffine.test.util.junit.ConditionalIgnoreRule; import com.codeaffine.test.util.junit.ConditionalIgnoreRule.ConditionalIgnore; public class FlatScrollBarTest { @Rule public final ConditionalIgnoreRule ignoreRule = new ConditionalIgnoreRule(); @Rule public final DisplayHelper displayHelper = new DisplayHelper(); private FlatScrollBar scrollBar; private Shell shell; @Before public void setUp() { shell = displayHelper.createShell( SWT.SHELL_TRIM ); shell.setBackgroundMode( SWT.INHERIT_DEFAULT ); shell.setLayout( new FillLayout( SWT.HORIZONTAL ) ); shell.setBounds( 250, 200, 500, 400 ); shell.setBackground( Display.getCurrent().getSystemColor( SWT.COLOR_LIST_BACKGROUND ) ); shell.open(); scrollBar = new FlatScrollBar( shell, SWT.HORIZONTAL ); } @Test( expected = UnsupportedOperationException.class ) public void setLayout() { scrollBar.setLayout( null ); } @Test public void defaultDirection() { FlatScrollBar flatScrollBar = new FlatScrollBar( shell, SWT.NONE ); Direction actual = flatScrollBar.getDirection(); assertThat( actual ).isSameAs( Direction.VERTICAL ); } @Test public void getDirection() { Direction actual = scrollBar.getDirection(); assertThat( actual ).isSameAs( Direction.HORIZONTAL ); } @Test public void getStyle() { int actual = scrollBar.getStyle(); assertThat( actual & SWT.HORIZONTAL ).isEqualTo( SWT.HORIZONTAL ); } @Test public void getMinimum() { int actual = scrollBar.getMinimum(); assertThat( actual ).isEqualTo( DEFAULT_MINIMUM ); } @Test public void setMinimum() { int expected = DEFAULT_MAXIMUM - 1; scrollBar.setMinimum( expected ); int actual = scrollBar.getMinimum(); assertThat( actual ).isEqualTo( expected ); } @Test public void setMinimumTwice() { scrollBar.setMinimum( DEFAULT_MAXIMUM - 1 ); PaintListener listener = registerPaintListener( scrollBar ); scrollBar.setMinimum( DEFAULT_MAXIMUM - 1 ); assertThatNoLayoutUpdateHasBeenTriggered( listener ); } @Test public void setMinimumWithTooLargeValue() { scrollBar.setMinimum( DEFAULT_MAXIMUM ); int actual = scrollBar.getMinimum(); assertThat( actual ).isEqualTo( DEFAULT_MINIMUM ); } @Test public void setMinimumWithTooSmallValue() { scrollBar.setMinimum( -1 ); int actual = scrollBar.getMinimum(); assertThat( actual ).isEqualTo( DEFAULT_MINIMUM ); } @Test public void setMinimumTriggersLayout() { shell.layout(); Rectangle before = scrollBar.drag.getControl().getBounds(); scrollBar.setMinimum( 20 ); Rectangle after = scrollBar.drag.getControl().getBounds(); assertThat( after ).isNotEqualTo( before ); } @Test public void getMaximum() { int actual = scrollBar.getMaximum(); assertThat( actual ).isEqualTo( DEFAULT_MAXIMUM ); } @Test public void setMaximum() { int expected = 110; scrollBar.setMaximum( expected ); int actual = scrollBar.getMaximum(); assertThat( actual ).isEqualTo( expected ); } @Test public void setMaximumTwice() { int maximum = 110; scrollBar.setMaximum( maximum ); PaintListener listener = registerPaintListener( scrollBar ); scrollBar.setMaximum( maximum ); assertThatNoLayoutUpdateHasBeenTriggered( listener ); } @Test public void setMaximumWithValueEqualsMinimum() { scrollBar.setMinimum( 10 ); scrollBar.setMaximum( 10 ); int actual = scrollBar.getMaximum(); assertThat( actual ).isEqualTo( DEFAULT_MAXIMUM ); } @Test public void setMaximumWithNegativeValue() { scrollBar.setMaximum( -1 ); int actual = scrollBar.getMaximum(); assertThat( actual ).isEqualTo( DEFAULT_MAXIMUM ); } @Test public void setMaximumTriggersLayout() { shell.layout(); Rectangle before = scrollBar.drag.getControl().getBounds(); scrollBar.setMaximum( 80 ); Rectangle after = scrollBar.drag.getControl().getBounds(); assertThat( after ).isNotEqualTo( before ); } @Test public void getThumb() { int actual = scrollBar.getThumb(); assertThat( actual ).isEqualTo( DEFAULT_THUMB ); } @Test public void getThumbOnMaximumAdjustment() { scrollBar.setMaximum( 1 ); int actual = scrollBar.getThumb(); assertThat( actual ).isEqualTo( 1 ); } @Test public void getThumbOnMinimumAdjustment() { scrollBar.setMinimum( DEFAULT_MAXIMUM - 1 ); int actual = scrollBar.getThumb(); assertThat( actual ).isEqualTo( 1 ); } @Test public void setThumb() { int expected = 20; scrollBar.setThumb( expected ); int actual = scrollBar.getThumb(); assertThat( actual ).isEqualTo( expected ); } @Test public void setThumbTwice() { int thumb = 20; scrollBar.setThumb( thumb ); PaintListener listener = registerPaintListener( scrollBar ); scrollBar.setThumb( thumb ); assertThatNoLayoutUpdateHasBeenTriggered( listener ); } @Test public void setThumbWithTooSmallValue() { scrollBar.setThumb( 0 ); int actual = scrollBar.getThumb(); assertThat( actual ).isEqualTo( DEFAULT_THUMB ); } @Test public void setThumbWithTooLargeValue() { scrollBar.setThumb( DEFAULT_MAXIMUM + 10 ); int actual = scrollBar.getThumb(); assertThat( actual ).isEqualTo( DEFAULT_MAXIMUM ); } @Test public void setThumbTriggersLayout() { shell.layout(); Rectangle before = scrollBar.drag.getControl().getBounds(); scrollBar.setThumb( 20 ); Rectangle after = scrollBar.drag.getControl().getBounds(); assertThat( after ).isNotEqualTo( before ); } @Test public void getIncrement() { int actual = scrollBar.getIncrement(); assertThat( actual ).isEqualTo( DEFAULT_INCREMENT ); } @Test public void setIncrement() { int expected = 10; scrollBar.setIncrement( expected ); int actual = scrollBar.getIncrement(); assertThat( actual ).isEqualTo( expected ); } @Test public void setIncrementTwice() { int increment = 10; scrollBar.setIncrement( increment ); PaintListener listener = registerPaintListener( scrollBar ); scrollBar.setIncrement( increment ); assertThatNoLayoutUpdateHasBeenTriggered( listener ); } @Test public void getPageIncrement() { int actual = scrollBar.getPageIncrement(); assertThat( actual ).isEqualTo( DEFAULT_PAGE_INCREMENT ); } @Test public void setPageIncrement() { int expected = 25; scrollBar.setPageIncrement( expected ); int actual = scrollBar.getPageIncrement(); assertThat( actual ).isEqualTo( expected ); } @Test public void getSelection() { int actual = scrollBar.getSelection(); assertThat( actual ).isEqualTo( DEFAULT_SELECTION ); } @Test public void getSelectionOnMinimumAdjustment() { scrollBar.setMinimum( DEFAULT_MAXIMUM - 1 ); int actual = scrollBar.getSelection(); assertThat( actual ).isEqualTo( 99 ); } @Test public void getSelectionOnMaximumAdjustment() { scrollBar.setThumb( 1 ); scrollBar.setSelectionInternal( 10, SWT.NONE ); scrollBar.setMaximum( 2 ); int actual = scrollBar.getSelection(); assertThat( actual ).isEqualTo( 1 ); } @Test public void getSelectionAfterThumbEnlargement() { scrollBar.setSelection( DEFAULT_MAXIMUM - DEFAULT_THUMB ); scrollBar.setThumb( DEFAULT_THUMB * 2 ); int actual = scrollBar.getSelection(); assertThat( actual ).isEqualTo( DEFAULT_MAXIMUM - DEFAULT_THUMB * 2 ); } @Test public void setSelection() { int expected = 12; scrollBar.setSelection( expected ); int actual = scrollBar.getSelection(); assertThat( actual ).isEqualTo( expected ); } @Test public void setSelectionTwice() { int selection = 12; scrollBar.setSelection( selection ); PaintListener listener = registerPaintListener( scrollBar ); scrollBar.setSelection( selection ); assertThatNoLayoutUpdateHasBeenTriggered( listener ); } @Test public void setSelectionWithValueBelowMinimum() { scrollBar.setSelection( DEFAULT_MINIMUM - 1 ); int actual = scrollBar.getSelection(); assertThat( actual ).isEqualTo( scrollBar.getMinimum() ); } @Test public void setSelectionWithMaximumValue() { scrollBar.setSelection( DEFAULT_MAXIMUM ); int actual = scrollBar.getSelection(); assertThat( actual ).isEqualTo( scrollBar.getMaximum() - scrollBar.getThumb() ); } @Test public void setSelectionTriggersLayout() { shell.layout(); Rectangle before = scrollBar.drag.getControl().getBounds(); scrollBar.setSelection( 20 ); Rectangle after = scrollBar.drag.getControl().getBounds(); assertThat( after ).isNotEqualTo( before ); } @Test public void setSelectionInternal() { int expected = 12; scrollBar.setSelectionInternal( expected, SWT.NONE ); int actual = scrollBar.getSelection(); assertThat( actual ).isEqualTo( expected ); } @Test public void setSelectionInternalWithValueBelowMinimum() { scrollBar.setSelectionInternal( DEFAULT_MINIMUM - 1, SWT.NONE ); int actual = scrollBar.getSelection(); assertThat( actual ).isEqualTo( scrollBar.getMinimum() ); } @Test public void setSelectionInternalWithMaximumValue() { scrollBar.setSelectionInternal( DEFAULT_MAXIMUM, SWT.NONE ); int actual = scrollBar.getSelection(); assertThat( actual ).isEqualTo( scrollBar.getMaximum() - scrollBar.getThumb() ); } @Test public void setSelectionInternalTriggersLayout() { shell.layout(); Rectangle before = scrollBar.drag.getControl().getBounds(); scrollBar.setSelectionInternal( 20, SWT.NONE ); Rectangle after = scrollBar.drag.getControl().getBounds(); assertThat( after ).isNotEqualTo( before ); } @Test public void resize() { shell.layout(); Rectangle before = scrollBar.drag.getControl().getBounds(); shell.setSize( 800, 800 ); Rectangle after = scrollBar.drag.getControl().getBounds(); assertThat( after ).isNotEqualTo( before ); } @Test public void initialSizeSettings() { Point size = scrollBar.getSize(); assertThat( size.y ).isEqualTo( FlatScrollBar.BAR_BREADTH ); } @Test public void addSelectionListener() { ArgumentCaptor<SelectionEvent> captor = forClass( SelectionEvent.class ); SelectionListener listener = mock( SelectionListener.class ); scrollBar.addSelectionListener( listener ); scrollBar.setSelectionInternal( 2, SWT.DRAG ); verify( listener ).widgetSelected( captor.capture() ); assertThat( captor.getValue().widget ).isSameAs( scrollBar ); assertThat( captor.getValue().detail ).isEqualTo( SWT.DRAG ); assertThat( scrollBar.getSelection() ).isEqualTo( 2 ); } @Test public void removeSelectionListener() { SelectionListener listener = mock( SelectionListener.class ); scrollBar.addSelectionListener( listener ); scrollBar.removeSelectionListener( listener ); scrollBar.setSelectionInternal( 2, SWT.NONE ); verify( listener, never() ).widgetSelected( any( SelectionEvent.class ) ); } @Test public void addUntypedSelectionListener() { ArgumentCaptor<Event> captor = forClass( Event.class ); Listener listener = mock( Listener.class ); scrollBar.addListener( SWT.Selection, listener ); scrollBar.setSelectionInternal( 2, SWT.DRAG ); verify( listener ).handleEvent( captor.capture() ); assertThat( captor.getValue().widget ).isSameAs( scrollBar ); assertThat( captor.getValue().detail ).isEqualTo( SWT.DRAG ); assertThat( scrollBar.getSelection() ).isEqualTo( 2 ); } @Test public void removeUntypedSelectionListener() { Listener listener = mock( Listener.class ); scrollBar.addListener( SWT.Selection, listener ); scrollBar.removeListener( SWT.Selection, listener ); scrollBar.setSelectionInternal( 2, SWT.NONE ); verify( listener, never() ).handleEvent( any( Event.class ) ); } @Test @ConditionalIgnore( condition = NonWindowsPlatform.class ) public void addCommonListener() { ArgumentCaptor<Event> captor = forClass( Event.class ); Listener listener = mock( Listener.class ); scrollBar.addListener( SWT.FocusIn, listener ); scrollBar.forceFocus(); verify( listener ).handleEvent( captor.capture() ); assertThat( captor.getValue().widget ).isSameAs( scrollBar ); } @Test @ConditionalIgnore( condition = GtkPlatform.class ) public void removeCommonListener() { Listener listener = mock( Listener.class ); scrollBar.addListener( SWT.FocusIn, listener ); scrollBar.removeListener( SWT.FocusIn, listener ); scrollBar.forceFocus(); verify( listener, never() ).handleEvent( any( Event.class ) ); } @Test public void setSelectionDoesNotTriggerScrollEvent() { SelectionListener listener = mock( SelectionListener.class ); scrollBar.addSelectionListener( listener ); scrollBar.setSelection( 2 ); verify( listener, never() ).widgetSelected( any( SelectionEvent.class ) ); } @Test public void setSelectionOnDrag() { scrollBar.notifyListeners( SWT.DRAG ); scrollBar.setSelection( 12 ); int actual = scrollBar.getSelection(); assertThat( actual ).isEqualTo( DEFAULT_SELECTION ); } @Test public void setSelectionOnDragWithUnrelatedType() { scrollBar.notifyListeners( SWT.DRAG ); scrollBar.notifyListeners( SWT.HOME ); scrollBar.setSelection( 12 ); int actual = scrollBar.getSelection(); assertThat( actual ).isEqualTo( DEFAULT_SELECTION ); } @Test public void setSelectionAfterDragEnd() { int expected = 12; scrollBar.notifyListeners( SWT.DRAG ); scrollBar.notifyListeners( SWT.NONE ); scrollBar.setSelection( expected ); int actual = scrollBar.getSelection(); assertThat( actual ).isEqualTo( expected ); } @Test public void notifyListeners() { ArgumentCaptor<SelectionEvent> captor = forClass( SelectionEvent.class ); SelectionListener listener = mock( SelectionListener.class ); scrollBar.addSelectionListener( listener ); scrollBar.setSelection( 2 ); scrollBar.notifyListeners( SWT.DRAG ); verify( listener ).widgetSelected( captor.capture() ); assertThat( captor.getValue().widget ).isSameAs( scrollBar ); assertThat( captor.getValue().detail ).isEqualTo( SWT.DRAG ); assertThat( scrollBar.getSelection() ).isEqualTo( 2 ); } @Test public void layoutTriggersPaint() { PaintListener listener = registerPaintListener( scrollBar ); Point size = scrollBar.getSize(); scrollBar.setSize( size.x + 1, size.y ); flushPendingEvents(); verify( listener, atLeastOnce() ).paintControl( any( PaintEvent.class ) ); } @Test public void controlLayout() { Layout layout = scrollBar.getLayout(); assertThat( layout ).isExactlyInstanceOf( FlatScrollBarLayout.class ); } private static PaintListener registerPaintListener( FlatScrollBar scrollBar ) { PaintListener result = mock( PaintListener.class ); scrollBar.addPaintListener( result ); return result; } private static void assertThatNoLayoutUpdateHasBeenTriggered( PaintListener listener ) { verify( listener, never() ).paintControl( any( PaintEvent.class ) ); } }