/*******************************************************************************
* Copyright (c) 2013, 2014 EclipseSource and others.
* 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:
* EclipseSource - initial API and implementation
******************************************************************************/
package org.eclipse.swt.widgets;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.internal.lifecycle.PhaseId;
import org.eclipse.rap.rwt.testfixture.internal.Fixture;
import org.eclipse.swt.SWT;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class AcceleratorBinding_Test {
private Display display;
private MenuItem menuItem;
private AcceleratorBinding acceleratorSupport;
@Before
public void setUp() {
Fixture.setUp();
Fixture.fakePhase( PhaseId.PROCESS_ACTION );
display = new Display();
menuItem = mock( MenuItem.class );
menuItem.display = display;
acceleratorSupport = new AcceleratorBinding( menuItem );
}
@After
public void tearDown() {
Fixture.tearDown();
}
@Test
public void testGetAccelerator_returnsZeroByDefault() {
assertEquals( 0, acceleratorSupport.getAccelerator() );
}
@Test
public void testSetAccelerator() {
acceleratorSupport.setAccelerator( SWT.ALT | 'A' );
assertEquals( SWT.ALT | 'A', acceleratorSupport.getAccelerator() );
}
@Test
public void testSetAcceleratorTwice_addsDisplayFilterOnce() {
display = mock( Display.class );
menuItem.display = display;
acceleratorSupport.setAccelerator( SWT.ALT | 'A' );
acceleratorSupport.setAccelerator( SWT.ALT | 'A' );
verify( display, times( 1 ) ).addFilter( SWT.KeyDown, acceleratorSupport );
}
@Test
public void testSetAcceleratorToZero_removesDisplayFilter() {
display = mock( Display.class );
menuItem.display = display;
acceleratorSupport.setAccelerator( SWT.ALT | 'A' );
acceleratorSupport.setAccelerator( SWT.NONE );
verify( display, times( 1 ) ).removeFilter( SWT.KeyDown, acceleratorSupport );
}
@Test
public void testSetAccelerator_addsActiveKey_letter() {
acceleratorSupport.setAccelerator( SWT.ALT | 'A' );
assertTrue( getActiveKeys().contains( "ALT+A" ) );
}
@Test
public void testSetAccelerator_addsActiveKey_number() {
acceleratorSupport.setAccelerator( SWT.ALT | '1' );
assertTrue( getActiveKeys().contains( "ALT+1" ) );
}
@Test
public void testSetAccelerator_addsActiveKey_punctuation() {
acceleratorSupport.setAccelerator( SWT.ALT | '.' );
assertTrue( getActiveKeys().contains( "ALT+." ) );
}
@Test
public void testSetAccelerator_addsActiveKey_special() {
acceleratorSupport.setAccelerator( SWT.ALT | SWT.F4 );
assertTrue( getActiveKeys().contains( "ALT+F4" ) );
}
@Test
public void testSetAccelerator_addsCancelKey() {
acceleratorSupport.setAccelerator( SWT.ALT | 'A' );
assertTrue( getCancelKeys().contains( "ALT+A" ) );
}
@Test
public void testSetAccelerator_keepsExistingActiveKey() {
setActiveKeys( "CTRL+B" );
acceleratorSupport.setAccelerator( SWT.ALT | 'A' );
assertTrue( getActiveKeys().contains( "CTRL+B" ) );
}
@Test
public void testSetAccelerator_keepsExistingCancelKey() {
setCancelKeys( "CTRL+B" );
acceleratorSupport.setAccelerator( SWT.ALT | 'A' );
assertTrue( getCancelKeys().contains( "CTRL+B" ) );
}
@Test
public void testRelease_callsSetWithZero() {
acceleratorSupport = spy( acceleratorSupport );
acceleratorSupport.release();
verify( acceleratorSupport ).setAccelerator( 0 );
}
@Test
public void testRelease_removesActiveKey() {
acceleratorSupport.setAccelerator( SWT.ALT | 'A' );
acceleratorSupport.release();
assertTrue( getActiveKeys().isEmpty() );
}
@Test
public void testRelease_removesCancelKey() {
acceleratorSupport.setAccelerator( SWT.ALT | 'A' );
acceleratorSupport.release();
assertFalse( getActiveKeys().contains( "ALT+A" ) );
}
@Test
public void testRelease_doesNotRemoveExistingActiveKeys() {
setActiveKeys( "CTRL+S", "CTRL+T" );
acceleratorSupport.setAccelerator( SWT.CTRL | 'T' );
acceleratorSupport.release();
assertTrue( getActiveKeys().contains( "CTRL+T" ) );
}
@Test
public void testRelease_doesNotRemoveExistingCancelKeys() {
setCancelKeys( "CTRL+S", "CTRL+T" );
acceleratorSupport.setAccelerator( SWT.CTRL | 'T' );
acceleratorSupport.release();
assertTrue( getCancelKeys().contains( "CTRL+T" ) );
}
@Test
public void testKeyDownEvent_triggersHandleAcceleratorActivation() {
acceleratorSupport.setAccelerator( SWT.ALT | 'A' );
when( Boolean.valueOf( menuItem.isEnabled() ) ).thenReturn( Boolean.TRUE );
display.sendEvent( SWT.KeyDown, mockKeyDownEvent( SWT.ALT, 'A' ) );
verify( menuItem ).handleAcceleratorActivation();
}
@Test
public void testKeyDownEvent_triggersHandleAcceleratorActivation_withSmallLetterInEvent() {
acceleratorSupport.setAccelerator( SWT.ALT | 'A' );
when( Boolean.valueOf( menuItem.isEnabled() ) ).thenReturn( Boolean.TRUE );
display.sendEvent( SWT.KeyDown, mockKeyDownEvent( SWT.ALT, 'a' ) );
verify( menuItem ).handleAcceleratorActivation();
}
@Test
public void testKeyDownEvent_triggersHandleAcceleratorActivation_withSmallLetterInAccelerator() {
acceleratorSupport.setAccelerator( SWT.ALT | 'a' );
when( Boolean.valueOf( menuItem.isEnabled() ) ).thenReturn( Boolean.TRUE );
display.sendEvent( SWT.KeyDown, mockKeyDownEvent( SWT.ALT, 'A' ) );
verify( menuItem ).handleAcceleratorActivation();
}
@Test
public void testKeyDownEvent_triggersHandleAcceleratorActivation_withNumberInAccelerator() {
acceleratorSupport.setAccelerator( SWT.ALT | '1' );
when( Boolean.valueOf( menuItem.isEnabled() ) ).thenReturn( Boolean.TRUE );
display.sendEvent( SWT.KeyDown, mockKeyDownEvent( SWT.ALT, '1' ) );
verify( menuItem ).handleAcceleratorActivation();
}
@Test
public void testKeyDownEvent_triggersHandleAcceleratorActivation_withSpecialInAccelerator() {
acceleratorSupport.setAccelerator( SWT.ALT | SWT.F4 );
when( Boolean.valueOf( menuItem.isEnabled() ) ).thenReturn( Boolean.TRUE );
display.sendEvent( SWT.KeyDown, mockKeyDownEvent( SWT.ALT, SWT.F4 ) );
verify( menuItem ).handleAcceleratorActivation();
}
@Test
public void testKeyDownEvent_triggersHandleAcceleratorActivation_withPunctuationInAccelerator() {
acceleratorSupport.setAccelerator( SWT.ALT | '.' );
when( Boolean.valueOf( menuItem.isEnabled() ) ).thenReturn( Boolean.TRUE );
display.sendEvent( SWT.KeyDown, mockKeyDownEvent( SWT.ALT, '.' ) );
verify( menuItem ).handleAcceleratorActivation();
}
@Test
public void testKeyDownEvent_doesNotTriggerHandleAcceleratorActivation_onDisabledItem() {
acceleratorSupport.setAccelerator( SWT.ALT | 'A' );
display.sendEvent( SWT.KeyDown, mockKeyDownEvent( SWT.ALT, 'A' ) );
verify( menuItem, times( 0 ) ).handleAcceleratorActivation();
}
@Test
public void testKeyDownEvent_doesNotTriggerHandleAcceleratorActivation_withDifferentKey() {
acceleratorSupport.setAccelerator( SWT.ALT | 'A' );
when( Boolean.valueOf( menuItem.isEnabled() ) ).thenReturn( Boolean.TRUE );
display.sendEvent( SWT.KeyDown, mockKeyDownEvent( SWT.ALT, 'B' ) );
verify( menuItem, times( 0 ) ).handleAcceleratorActivation();
}
@Test
public void testKeyDownEvent_doesNotTriggerHandleAcceleratorActivation_withDifferentModifier() {
acceleratorSupport.setAccelerator( SWT.ALT | 'A' );
when( Boolean.valueOf( menuItem.isEnabled() ) ).thenReturn( Boolean.TRUE );
display.sendEvent( SWT.KeyDown, mockKeyDownEvent( SWT.CTRL, 'A' ) );
verify( menuItem, times( 0 ) ).handleAcceleratorActivation();
}
@Test
public void testKeyDownEvent_doesNotTriggerHandleAcceleratorActivation_withDifferentType() {
acceleratorSupport.setAccelerator( SWT.ALT | 'A' );
when( Boolean.valueOf( menuItem.isEnabled() ) ).thenReturn( Boolean.TRUE );
display.sendEvent( SWT.KeyUp, mockKeyDownEvent( SWT.ALT, 'A' ) );
verify( menuItem, times( 0 ) ).handleAcceleratorActivation();
}
@Test
public void testKeyDownEvent_doesNotTriggerHandleAcceleratorActivation_withoutAccelerator() {
when( Boolean.valueOf( menuItem.isEnabled() ) ).thenReturn( Boolean.TRUE );
display.sendEvent( SWT.KeyDown, mockKeyDownEvent( SWT.ALT, 'A' ) );
verify( menuItem, times( 0 ) ).handleAcceleratorActivation();
}
@Test
public void testAcceleratorFilter_filtersKeyDownEvent() {
acceleratorSupport.setAccelerator( SWT.ALT | 'A' );
when( Boolean.valueOf( menuItem.isEnabled() ) ).thenReturn( Boolean.TRUE );
Event keyEvent = mockKeyDownEvent( SWT.ALT, 'A' );
display.sendEvent( SWT.KeyDown, keyEvent );
assertEquals( SWT.None, keyEvent.type );
}
private void setActiveKeys( String... keys ) {
display.setData( RWT.ACTIVE_KEYS, keys );
}
private void setCancelKeys( String... keys ) {
display.setData( RWT.CANCEL_KEYS, keys );
}
private List<String> getActiveKeys() {
return getKeys( display.getData( RWT.ACTIVE_KEYS ) );
}
private List<String> getCancelKeys() {
return getKeys( display.getData( RWT.CANCEL_KEYS ) );
}
@SuppressWarnings( "unchecked" )
private static List<String> getKeys( Object data ) {
return data == null ? Collections.EMPTY_LIST : Arrays.asList( ( String[] )data );
}
private static Event mockKeyDownEvent( int modifiers, char character ) {
Event event = mock( Event.class );
event.stateMask = modifiers;
event.character = character;
return event;
}
private static Event mockKeyDownEvent( int modifiers, int keyCode ) {
Event event = mock( Event.class );
event.stateMask = modifiers;
event.keyCode = keyCode;
return event;
}
}