/*******************************************************************************
* Copyright (c) 2010, 2015 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.internal.widgets.canvaskit;
import static org.eclipse.rap.rwt.internal.lifecycle.WidgetUtil.getId;
import static org.eclipse.rap.rwt.internal.protocol.RemoteObjectFactory.getRemoteObject;
import static org.eclipse.rap.rwt.testfixture.internal.TestMessage.getParent;
import static org.eclipse.swt.internal.widgets.canvaskit.GCOperationWriter.getGcId;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import java.io.IOException;
import org.eclipse.rap.json.JsonArray;
import org.eclipse.rap.json.JsonObject;
import org.eclipse.rap.rwt.internal.lifecycle.PhaseId;
import org.eclipse.rap.rwt.internal.protocol.Operation.CallOperation;
import org.eclipse.rap.rwt.internal.protocol.Operation.CreateOperation;
import org.eclipse.rap.rwt.internal.remote.RemoteObjectRegistry;
import org.eclipse.rap.rwt.remote.OperationHandler;
import org.eclipse.rap.rwt.scripting.ClientListener;
import org.eclipse.rap.rwt.testfixture.internal.Fixture;
import org.eclipse.rap.rwt.testfixture.internal.TestMessage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.internal.graphics.GCAdapter;
import org.eclipse.swt.internal.graphics.GCOperation.DrawLine;
import org.eclipse.swt.internal.graphics.GCOperation.SetProperty;
import org.eclipse.swt.internal.widgets.controlkit.ControlLCATestUtil;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class CanvasLCA_Test {
private Display display;
private Shell shell;
private CanvasLCA lca;
private Canvas canvas;
@Before
public void setUp() {
Fixture.setUp();
display = new Display();
shell = new Shell( display );
lca = CanvasLCA.INSTANCE;
canvas = new Canvas( shell, SWT.NONE );
}
@After
public void tearDown() {
Fixture.tearDown();
}
@Test
public void testCommonControlProperties() throws IOException {
ControlLCATestUtil.testCommonControlProperties( canvas );
}
@Test
public void testRenderCreate() throws IOException {
lca.renderInitialization( canvas );
TestMessage message = Fixture.getProtocolMessage();
CreateOperation canvasCreate = message.findCreateOperation( canvas );
assertEquals( "rwt.widgets.Canvas", canvasCreate.getType() );
assertEquals( getId( shell ), canvasCreate.getProperties().get( "parent" ).asString() );
String canvasId = getId( canvas );
CreateOperation gcCreate = message.findCreateOperation( getGcId( canvas ) );
assertEquals( "rwt.widgets.GC", gcCreate.getType() );
assertEquals( canvasId, gcCreate.getProperties().get( "parent" ).asString() );
}
@Test
public void testRenderInitialization_setsOperationHandler() throws IOException {
String id = getId( canvas );
lca.renderInitialization( canvas );
OperationHandler handler = RemoteObjectRegistry.getInstance().get( id ).getHandler();
assertTrue( handler instanceof CanvasOperationHandler );
}
@Test
public void testReadData_usesOperationHandler() {
CanvasOperationHandler handler = spy( new CanvasOperationHandler( canvas ) );
getRemoteObject( getId( canvas ) ).setHandler( handler );
Fixture.fakeNotifyOperation( getId( canvas ), "Help", new JsonObject() );
lca.readData( canvas );
verify( handler ).handleNotifyHelp( canvas, new JsonObject() );
}
@Test
public void testRenderParent() throws IOException {
lca.renderInitialization( canvas );
TestMessage message = Fixture.getProtocolMessage();
CreateOperation operation = message.findCreateOperation( canvas );
assertEquals( getId( canvas.getParent() ), getParent( operation ) );
}
@Test
public void testWriqteSingleGCOperation() throws IOException {
canvas.setSize( 50, 50 );
canvas.setFont( new Font( display, "Arial", 11, SWT.NORMAL ) );
Fixture.markInitialized( display );
Fixture.markInitialized( canvas );
Fixture.preserveWidgets();
GCAdapter adapter = canvas.getAdapter( GCAdapter.class );
adapter.addGCOperation( new DrawLine( 1, 2, 3, 4 ) );
lca.renderChanges( canvas );
CallOperation init = getGCOperation( canvas, "init" );
assertEquals( 50, init.getParameters().get( "width" ).asInt() );
assertEquals( 50, init.getParameters().get( "height" ).asInt() );
JsonArray expectedFont = JsonArray.readFrom( "[[\"Arial\"], 11, false, false]" );
assertEquals( expectedFont, init.getParameters().get( "font" ) );
JsonArray expectedFillStyle = JsonArray.readFrom( "[255, 255, 255, 255]" );
assertEquals( expectedFillStyle, init.getParameters().get( "fillStyle" ) );
JsonArray expectedStrokeStyle = JsonArray.readFrom( "[74, 74, 74, 255]" );
assertEquals( expectedStrokeStyle, init.getParameters().get( "strokeStyle" ) );
CallOperation draw = getGCOperation( canvas, "draw" );
assertEquals( 4, draw.getParameters().get( "operations" ).asArray().size() );
}
@Test
public void testWriteMultipleGCOperations() throws IOException {
canvas.setSize( 50, 50 );
canvas.setFont( new Font( display, "Arial", 11, SWT.NORMAL ) );
Fixture.markInitialized( display );
Fixture.markInitialized( canvas );
Fixture.preserveWidgets();
GCAdapter adapter = canvas.getAdapter( GCAdapter.class );
adapter.addGCOperation( new DrawLine( 1, 2, 3, 4 ) );
adapter.addGCOperation( new DrawLine( 5, 6, 7, 8 ) );
lca.renderChanges( canvas );
CallOperation draw = getGCOperation( canvas, "draw" );
assertEquals( 8, draw.getParameters().get( "operations" ).asArray().size() );
}
// see bug 323080
@Test
public void testMultipleGC_SetFont() throws IOException {
canvas.setSize( 50, 50 );
canvas.setFont( new Font( display, "Arial", 11, SWT.NORMAL ) );
Fixture.markInitialized( display );
Fixture.markInitialized( canvas );
Fixture.preserveWidgets();
GC gc = new GC( canvas );
gc.setFont( new Font( display, "Tahoma", 16, SWT.BOLD ) );
gc.dispose();
gc = new GC( canvas );
gc.setFont( new Font( display, "Tahoma", 16, SWT.BOLD ) );
gc.dispose();
gc = new GC( canvas );
gc.setFont( new Font( display, "Tahoma", 16, SWT.BOLD ) );
gc.dispose();
lca.renderChanges( canvas );
TestMessage message = Fixture.getProtocolMessage();
assertEquals( 0, message.getOperationCount() );
}
@Test
public void testTrimTrailingSetOperations() throws IOException {
canvas.setSize( 50, 50 );
canvas.setFont( new Font( display, "Arial", 11, SWT.NORMAL ) );
Fixture.markInitialized( display );
Fixture.markInitialized( canvas );
Fixture.preserveWidgets();
GCAdapter adapter = canvas.getAdapter( GCAdapter.class );
adapter.addGCOperation( new DrawLine( 1, 2, 3, 4 ) );
adapter.addGCOperation( new DrawLine( 5, 6, 7, 8 ) );
Font font = new Font( display, "Arial", 15, SWT.NORMAL );
adapter.addGCOperation( new SetProperty( font.getFontData()[ 0 ] ) );
SetProperty operation = new SetProperty( SetProperty.LINE_WIDTH, 5 );
adapter.addGCOperation( operation );
lca.renderChanges( canvas );
CallOperation draw = getGCOperation( canvas, "draw" );
assertEquals( 8, draw.getParameters().get( "operations" ).asArray().size() );
assertEquals( 0, adapter.getGCOperations().length );
}
@Test
public void testNoDrawOperations() throws IOException {
canvas.setSize( 50, 50 );
canvas.setFont( new Font( display, "Arial", 11, SWT.NORMAL ) );
Fixture.markInitialized( display );
Fixture.markInitialized( canvas );
Fixture.preserveWidgets();
GCAdapter adapter = canvas.getAdapter( GCAdapter.class );
Font font = new Font( display, "Arial", 15, SWT.NORMAL );
adapter.addGCOperation( new SetProperty( font.getFontData()[ 0 ] ) );
SetProperty operation = new SetProperty( SetProperty.LINE_WIDTH, 5 );
adapter.addGCOperation( operation );
lca.renderChanges( canvas );
assertNull( getGCOperation( canvas, "draw" ) );
assertEquals( 0, adapter.getGCOperations().length );
}
@Test
public void testRenderOperations_empty() throws IOException {
Fixture.fakePhase( PhaseId.PROCESS_ACTION );
canvas.setSize( 50, 50 );
canvas.setFont( new Font( display, "Arial", 11, SWT.NORMAL ) );
Fixture.markInitialized( display );
Fixture.markInitialized( canvas );
Fixture.preserveWidgets();
canvas.addPaintListener( new PaintListener() {
@Override
public void paintControl( PaintEvent event ) {
event.gc.drawLine( 1, 2, 3, 4 );
event.gc.drawLine( 5, 6, 7, 8 );
}
} );
Fixture.fakeResponseWriter();
lca.renderChanges( canvas );
TestMessage message = Fixture.getProtocolMessage();
assertEquals( 0, message.getOperationCount() );
}
@Test
public void testRenderOperations_resize() throws IOException {
Fixture.fakePhase( PhaseId.PROCESS_ACTION );
Canvas canvas = new Canvas( shell, SWT.NONE );
canvas.setSize( 50, 50 );
canvas.setFont( new Font( display, "Arial", 11, SWT.NORMAL ) );
Fixture.markInitialized( display );
Fixture.markInitialized( canvas );
Fixture.preserveWidgets();
canvas.addPaintListener( new PaintListener() {
@Override
public void paintControl( PaintEvent event ) {
event.gc.drawLine( 1, 2, 3, 4 );
event.gc.drawLine( 5, 6, 7, 8 );
}
} );
Fixture.fakeResponseWriter();
canvas.setSize( 150, 150 );
lca.renderChanges( canvas );
CallOperation init = getGCOperation( canvas, "init" );
assertEquals( 150, init.getParameters().get( "width" ).asInt() );
assertEquals( 150, init.getParameters().get( "height" ).asInt() );
CallOperation draw = getGCOperation( canvas, "draw" );
assertEquals( 8, draw.getParameters().get( "operations" ).asArray().size() );
}
@Test
public void testRenderOperations_redraw() throws IOException {
Fixture.fakePhase( PhaseId.PROCESS_ACTION );
canvas.setSize( 50, 50 );
canvas.setFont( new Font( display, "Arial", 11, SWT.NORMAL ) );
Fixture.markInitialized( display );
Fixture.markInitialized( canvas );
Fixture.preserveWidgets();
canvas.addPaintListener( new PaintListener() {
@Override
public void paintControl( PaintEvent event ) {
event.gc.drawLine( 1, 2, 3, 4 );
event.gc.drawLine( 5, 6, 7, 8 );
}
} );
Fixture.fakeResponseWriter();
canvas.redraw();
lca.renderChanges( canvas );
CallOperation draw = getGCOperation( canvas, "draw" );
assertEquals( 8, draw.getParameters().get( "operations" ).asArray().size() );
}
@Test
public void testClearDrawing() throws IOException {
Fixture.fakePhase( PhaseId.PROCESS_ACTION );
canvas.setSize( 50, 50 );
canvas.setFont( new Font( display, "Arial", 11, SWT.NORMAL ) );
canvas.getAdapter( GCAdapter.class );
Fixture.markInitialized( display );
Fixture.markInitialized( canvas );
Fixture.preserveWidgets();
canvas.addPaintListener( new PaintListener() {
@Override
public void paintControl( PaintEvent event ) {
}
} );
Fixture.fakeResponseWriter();
canvas.redraw();
lca.renderChanges( canvas );
assertNotNull( getGCOperation( canvas, "init" ) );
assertNull( getGCOperation( canvas, "draw" ) );
}
@Test
public void testRenderClientArea() {
canvas.setSize( 110, 120 );
CanvasLCA.renderClientArea( canvas );
TestMessage message = Fixture.getProtocolMessage();
Rectangle clientArea = canvas.getClientArea();
assertEquals( clientArea, toRectangle( message.findSetProperty( canvas, "clientArea" ) ) );
}
@Test
public void testRenderClientArea_SizeZero() {
canvas.setSize( 0, 0 );
CanvasLCA.renderClientArea( canvas );
TestMessage message = Fixture.getProtocolMessage();
Rectangle clientArea = new Rectangle( 0, 0, 0, 0 );
assertEquals( clientArea, toRectangle( message.findSetProperty( canvas, "clientArea" ) ) );
}
@Test
public void testRenderClientArea_SizeUnchanged() {
Fixture.markInitialized( canvas );
canvas.setSize( 110, 120 );
lca.preserveValues( canvas );
CanvasLCA.renderClientArea( canvas );
TestMessage message = Fixture.getProtocolMessage();
assertNull( message.findSetOperation( canvas, "clientArea" ) );
}
@Test
public void testRenderChanges_rendersClientListener() throws IOException {
canvas.addListener( SWT.Paint, new ClientListener( "" ) );
lca.renderChanges( canvas );
TestMessage message = Fixture.getProtocolMessage();
assertNotNull( message.findCallOperation( canvas, "addListener" ) );
}
private Rectangle toRectangle( Object property ) {
JsonArray jsonArray = ( JsonArray )property;
Rectangle result = new Rectangle(
jsonArray.get( 0 ).asInt(),
jsonArray.get( 1 ).asInt(),
jsonArray.get( 2 ).asInt(),
jsonArray.get( 3 ).asInt()
);
return result;
}
private static CallOperation getGCOperation( Canvas canvas, String method ) {
TestMessage message = Fixture.getProtocolMessage();
return message.findCallOperation( getGcId( canvas ), method );
}
}