/** * 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.navigationbar; import static com.codeaffine.eclipse.swt.test.util.ShellHelper.createShell; import static com.codeaffine.eclipse.swt.test.util.UiThreadHelper.runInOwnThreadWithReadAndDispatch; 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.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; 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.widget.action.ActionControlBuilder; public class NavigationBarFactoryTest { private static final String ICON = "icon"; @Rule public final DisplayHelper displayHelper = new DisplayHelper(); private NavigationItemController controller; private NavigationBarFactory factory; private ImageProvider imageProvider; private NavigationItemModel model; private Shell parent; @Before public void setUp() { imageProvider = mock( ImageProvider.class ); factory = new NavigationBarFactory( imageProvider ); parent = createShell( displayHelper ); model = stubModel(); controller = stubController(); } @Test public void create() { Control bar = factory .with( model, controller, ICON ) .with( model, controller, ICON ) .create( parent ); verify( model, times( 2 ) ).getSelection(); verify( model, times( 4 ) ).addSelectionChangedListener( any( Runnable.class ) ); verify( controller, times( 2 ) ).getAddControlBuilder(); verify( controller, times( 2 ) ).getRemoveControlBuilder(); verify( controller, times( 2 ) ).getSelectControlBuilder(); verify( imageProvider, times( 2 ) ).getImage( ICON ); assertThat( parent.getChildren() ).hasSize( 1 ); assertThat( bar ).isNotNull(); } @Test public void createMultipleBars() { Control bar1 = factory.with( model, controller, ICON ).create( parent ); Control bar2 = factory.with( model, controller, ICON ).create( parent ); Control bar3 = factory.create( parent ); verify( model, times( 2 ) ).getSelection(); verify( model, times( 4 ) ).addSelectionChangedListener( any( Runnable.class ) ); verify( controller, times( 2 ) ).getAddControlBuilder(); verify( controller, times( 2 ) ).getRemoveControlBuilder(); verify( controller, times( 2 ) ).getSelectControlBuilder(); verify( imageProvider, times( 2 ) ).getImage( ICON ); assertThat( parent.getChildren() ).hasSize( 3 ); assertThat( bar1 ).isNotSameAs( bar2 ); assertThat( bar2 ).isNotSameAs( bar3 ); assertThat( bar1 ).isNotSameAs( bar3 ); assertThat( bar1 ).isNotNull(); assertThat( bar2 ).isNotNull(); assertThat( bar3 ).isNotNull(); } @Test public void selectionChanged() { Control bar = factory.with( model, controller, ICON ).create( parent ); AtomicBoolean layoutPerformed = registerLayoutPerformedStatusRecorder( bar ); simulateSelectionChanged( model ); assertThat( layoutPerformed.get() ).isTrue(); } @Test public void getActionControlImageFromImageProvider() { Image result = factory.getImageProvider().getImage( ActionControlImageAdapter.PLUS ); assertThat( result ).isNotNull(); } @Test public void dispose() { Image image = factory.getImageProvider().getImage( ActionControlImageAdapter.PLUS ); factory.dispose(); assertThat( image.isDisposed() ).isTrue(); } private static AtomicBoolean registerLayoutPerformedStatusRecorder( Control navigationBar ) { AtomicBoolean result = new AtomicBoolean(); ( ( Composite )navigationBar ).setLayout( new LayoutRecorder( result ) ); return result; } private static void simulateSelectionChanged( NavigationItemModel model ) { ArgumentCaptor<Runnable> captor = forClass( Runnable.class ); verify( model, times( 2 ) ).addSelectionChangedListener( captor.capture() ); captor.getAllValues().forEach( runnable -> runInOwnThreadWithReadAndDispatch( runnable ) ); } private static NavigationItemModel stubModel() { NavigationItemModel result = mock( NavigationItemModel.class ); when( result.getSelection() ).thenReturn( new NavigationItemModelElement( "id", "displayName" ) ); return result; } private static NavigationItemController stubController() { NavigationItemController result = mock( NavigationItemController.class ); when( result.getAddControlBuilder() ).thenReturn( new ActionControlBuilder( () -> {} ) ); when( result.getRemoveControlBuilder() ).thenReturn( new ActionControlBuilder( () -> {} ) ); when( result.getSelectControlBuilder() ).thenReturn( new ActionControlBuilder( () -> {} ) ); return result; } }