/** * 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.ReconciliationHelper.stubReconciliation; import static com.codeaffine.eclipse.swt.widget.scrollable.TreeHelper.createTree; import static com.codeaffine.eclipse.swt.widget.scrollable.TreeHelper.expandTopBranch; import static java.util.stream.Collectors.toList; 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.doNothing; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Scrollable; import org.eclipse.swt.widgets.Tree; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import com.codeaffine.eclipse.swt.test.util.DisplayHelper; import com.codeaffine.eclipse.swt.widget.scrollable.context.AdaptionContext; import com.codeaffine.eclipse.swt.widget.scrollable.context.Reconciliation; import com.codeaffine.eclipse.swt.widget.scrollable.context.ScrollableControl; @SuppressWarnings( "rawtypes" ) public class ScrollableLayoutTest { @Rule public final DisplayHelper displayHelper = new DisplayHelper(); private StructuredScrollableLayouter scrollableLayouter; private OverlayLayouter overlayLayouter; private Reconciliation reconciliation; private AdaptionContext<?> context; private ScrollableLayout layout; @Before public void setUp() { context = createContext(); overlayLayouter = mock( OverlayLayouter.class ); scrollableLayouter = mock( StructuredScrollableLayouter.class ); reconciliation = stubReconciliation(); layout = new ScrollableLayout( context, overlayLayouter, scrollableLayouter, reconciliation ); } @Test public void layout() { ArgumentCaptor<AdaptionContext> captor = forClass( AdaptionContext.class ); layout.layout( null, true ); InOrder order = order(); order.verify( reconciliation ).runWhileSuspended( any( Runnable.class ) ); order.verify( scrollableLayouter ).layout( captor.capture() ); order.verify( overlayLayouter ).layout( captor.capture() ); order.verifyNoMoreInteractions(); assertContextGetsUpdated( captor ); } @Test public void ensureReconciliationClamp() { doNothing().when( reconciliation ).runWhileSuspended( any( Runnable.class ) ); expandTopBranch( ( Tree )context.getScrollable().getControl() ); context.updatePreferredSize(); layout.layout( null, true ); InOrder order = order(); order.verify( reconciliation ).runWhileSuspended( any( Runnable.class ) ); order.verify( overlayLayouter, never() ).layout( any( AdaptionContext.class ) ); order.verify( scrollableLayouter, never() ).layout( any( AdaptionContext.class ) ); order.verifyNoMoreInteractions(); } @Test public void computeSize() { Point actual = layout.computeSize( null, SWT.DEFAULT, SWT.DEFAULT, true ); assertThat( actual ).isEqualTo( context.getScrollable().computeSize( SWT.DEFAULT, SWT.DEFAULT, true ) ); } private AdaptionContext<Scrollable> createContext() { Scrollable scrollable = createTree( createShell( displayHelper ), 6, 4 ); ScrollableControl<Scrollable> scrollableControl = new ScrollableControl<>( scrollable ); return new AdaptionContext<>( scrollable.getParent(), scrollableControl ); } private InOrder order() { return inOrder( reconciliation, overlayLayouter, scrollableLayouter ); } private void assertContextGetsUpdated( ArgumentCaptor<AdaptionContext> captor ) { List<AdaptionContext> captured = captor.getAllValues(); captured.forEach( actual -> assertThat( actual ).isNotSameAs( context ) ); captured.forEach( actual -> assertThat( filterForActual( captured, actual ) ).hasSize( 1 ) ); } private static List<AdaptionContext> filterForActual( List<AdaptionContext> captured, AdaptionContext actual ) { return captured.stream().filter( current -> current == actual ).collect( toList() ); } }