Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,35 @@ void shapeConversionsTranslateBetweenSpaces() throws Exception {
RecordingChart chart = new RecordingChart();
ChartComponent component = new PositionedChartComponent(chart, 10, 15);

Rectangle screenRect = new Rectangle(component.getAbsoluteX(), component.getAbsoluteY(), 40, 50);
Rectangle chartBounds = component.screenToChartShape(screenRect).getBounds();
assertEquals(0, chartBounds.getX());
assertEquals(0, chartBounds.getY());
assertEquals(0, chartBounds.getSize().getWidth());
assertEquals(0, chartBounds.getSize().getHeight());

Rectangle chartRect = new Rectangle(0, 0, 40, 50);
Rectangle screenBounds = component.chartToScreenShape(chartRect).getBounds();
assertEquals(0, screenBounds.getX());
assertEquals(0, screenBounds.getY());
assertEquals(0, screenBounds.getSize().getWidth());
assertEquals(0, screenBounds.getSize().getHeight());
Rectangle screenRect = new Rectangle(component.getAbsoluteX() + 6, component.getAbsoluteY() + 4, 40, 50);
Shape chartShape = component.screenToChartShape(screenRect);
Rectangle chartBounds = chartShape.getBounds();
assertEquals(screenRect.getX() - component.getAbsoluteX(), chartBounds.getX());
assertEquals(screenRect.getY() - component.getAbsoluteY(), chartBounds.getY());
assertEquals(screenRect.getSize().getWidth(), chartBounds.getWidth());
assertEquals(screenRect.getSize().getHeight(), chartBounds.getHeight());

Shape roundTrippedScreenShape = component.chartToScreenShape(chartShape);
Rectangle roundTrippedScreenBounds = roundTrippedScreenShape.getBounds();
assertEquals(screenRect.getX(), roundTrippedScreenBounds.getX());
assertEquals(screenRect.getY(), roundTrippedScreenBounds.getY());
assertEquals(screenRect.getSize().getWidth(), roundTrippedScreenBounds.getWidth());
assertEquals(screenRect.getSize().getHeight(), roundTrippedScreenBounds.getHeight());

Rectangle chartRect = new Rectangle(3, 7, 40, 50);
Shape screenShape = component.chartToScreenShape(chartRect);
Rectangle screenBounds = screenShape.getBounds();
assertEquals(chartRect.getX() + component.getAbsoluteX(), screenBounds.getX());
assertEquals(chartRect.getY() + component.getAbsoluteY(), screenBounds.getY());
assertEquals(chartRect.getSize().getWidth(), screenBounds.getWidth());
assertEquals(chartRect.getSize().getHeight(), screenBounds.getHeight());

Shape roundTrippedChartShape = component.screenToChartShape(screenShape);
Rectangle roundTrippedChartBounds = roundTrippedChartShape.getBounds();
assertEquals(chartRect.getX(), roundTrippedChartBounds.getX());
assertEquals(chartRect.getY(), roundTrippedChartBounds.getY());
assertEquals(chartRect.getSize().getWidth(), roundTrippedChartBounds.getWidth());
assertEquals(chartRect.getSize().getHeight(), roundTrippedChartBounds.getHeight());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@
import com.codename1.ui.plaf.UIManager;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.mockito.Mockito;

import java.lang.reflect.Field;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
Expand Down Expand Up @@ -87,13 +90,21 @@ protected void setUpDisplay() throws Exception {

@AfterEach
protected void tearDownDisplay() throws Exception {
flushSerialCalls();
resetUIManager();
setDisplayField("codenameOneGraphics", null);
setDisplayField("impl", null);
setDisplayField("pluginSupport", null);
setDisplayField("codenameOneRunning", false);
setDisplayField("edt", null);
Util.setImplementation(null);
if (implementation != null) {
Mockito.reset(implementation);
}
implementation = null;
pluginSupport = null;
codenameOneGraphics = null;
display = null;
}

private void setDisplayField(String fieldName, Object value) throws Exception {
Expand All @@ -109,7 +120,58 @@ private void setDisplayField(String fieldName, Object value) throws Exception {
private void resetUIManager() throws Exception {
Field instanceField = UIManager.class.getDeclaredField("instance");
instanceField.setAccessible(true);
UIManager instance = (UIManager) instanceField.get(null);
if (instance != null) {
clearMap(instance, "styles");
clearMap(instance, "selectedStyles");
clearMap(instance, "themeConstants");
clearMap(instance, "imageCache");
clearMap(instance, "parseCache");

Field themePropsField = UIManager.class.getDeclaredField("themeProps");
themePropsField.setAccessible(true);
Object themeProps = themePropsField.get(instance);
if (themeProps instanceof Map) {
((Map) themeProps).clear();
}
themePropsField.set(instance, null);

Field resourceBundleField = UIManager.class.getDeclaredField("resourceBundle");
resourceBundleField.setAccessible(true);
Object resourceBundle = resourceBundleField.get(instance);
if (resourceBundle instanceof Hashtable) {
((Hashtable) resourceBundle).clear();
}
resourceBundleField.set(instance, null);

Field bundleField = UIManager.class.getDeclaredField("bundle");
bundleField.setAccessible(true);
Object bundle = bundleField.get(instance);
if (bundle instanceof Map) {
((Map) bundle).clear();
}
bundleField.set(instance, null);
}
instanceField.set(null, null);

Field accessibleField = UIManager.class.getDeclaredField("accessible");
accessibleField.setAccessible(true);
accessibleField.setBoolean(null, true);

Field localeAccessibleField = UIManager.class.getDeclaredField("localeAccessible");
localeAccessibleField.setAccessible(true);
localeAccessibleField.setBoolean(null, true);
}

private void clearMap(UIManager manager, String fieldName) throws Exception {
Field field = UIManager.class.getDeclaredField(fieldName);
field.setAccessible(true);
Object value = field.get(manager);
if (value instanceof Map) {
((Map) value).clear();
} else if (value instanceof Hashtable) {
((Hashtable) value).clear();
}
}

private Graphics createGraphics() throws Exception {
Expand Down
164 changes: 164 additions & 0 deletions maven/core-unittests/src/test/java/com/codename1/ui/GraphicsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package com.codename1.ui;

import com.codename1.test.UITestBase;
import com.codename1.ui.Paint;
import com.codename1.ui.Stroke;
import com.codename1.ui.geom.Rectangle;
import com.codename1.ui.geom.Shape;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;

import java.lang.reflect.Constructor;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.same;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

class GraphicsTest extends UITestBase {

private Object nativeGraphics;

@BeforeEach
@Override
protected void setUpDisplay() throws Exception {
super.setUpDisplay();
nativeGraphics = new Object();
}

private Graphics newGraphics() throws Exception {
Constructor<Graphics> constructor = Graphics.class.getDeclaredConstructor(Object.class);
constructor.setAccessible(true);
return constructor.newInstance(nativeGraphics);
}

@Test
void testTranslateDelegatesWhenSupported() throws Exception {
when(implementation.isTranslationSupported()).thenReturn(true);
when(implementation.getTranslateX(nativeGraphics)).thenReturn(3);
when(implementation.getTranslateY(nativeGraphics)).thenReturn(4);
Graphics graphics = newGraphics();
graphics.translate(5, 6);
verify(implementation).translate(nativeGraphics, 5, 6);
assertEquals(3, graphics.getTranslateX());
assertEquals(4, graphics.getTranslateY());
}

@Test
void testTranslateWithoutSupportAccumulates() throws Exception {
when(implementation.isTranslationSupported()).thenReturn(false);
Graphics graphics = newGraphics();
graphics.translate(2, 3);
graphics.translate(1, -1);
verify(implementation, never()).translate(eq(nativeGraphics), anyInt(), anyInt());
assertEquals(3, graphics.getTranslateX());
assertEquals(2, graphics.getTranslateY());
}

@Test
void testSetColorAndSetAndGetColor() throws Exception {
Graphics graphics = newGraphics();
graphics.setColor(0x123456);
verify(implementation).setColor(nativeGraphics, 0x123456);
int previous = graphics.setAndGetColor(0xABCDEF);
assertEquals(0x123456, previous);
verify(implementation).setColor(nativeGraphics, 0xABCDEF & 0xFFFFFF);
}

@Test
void testClipRectUsesTranslationOffsets() throws Exception {
Graphics graphics = newGraphics();
graphics.translate(5, 7);
graphics.clipRect(1, 2, 3, 4);
verify(implementation).clipRect(nativeGraphics, 6, 9, 3, 4);
}

@Test
void testSetClipShapeAppliesTranslation() throws Exception {
when(implementation.isShapeSupported(nativeGraphics)).thenReturn(true);
when(implementation.isShapeClipSupported(nativeGraphics)).thenReturn(true);
Graphics graphics = newGraphics();
graphics.translate(10, 5);
Rectangle shape = new Rectangle(0, 0, 10, 10);
graphics.setClip(shape);
ArgumentCaptor<Shape> shapeCaptor = ArgumentCaptor.forClass(Shape.class);
verify(implementation).setClip(eq(nativeGraphics), shapeCaptor.capture());
Rectangle bounds = shapeCaptor.getValue().getBounds();
assertEquals(10, bounds.getX());
assertEquals(5, bounds.getY());
}

@Test
void testDrawShapeTranslatesWhenNeeded() throws Exception {
when(implementation.isShapeSupported(nativeGraphics)).thenReturn(true);
Graphics graphics = newGraphics();
graphics.translate(3, 4);
Rectangle shape = new Rectangle(0, 0, 5, 5);
Stroke stroke = new Stroke(1, Stroke.CAP_BUTT, Stroke.JOIN_MITER, 1f);
graphics.drawShape(shape, stroke);
ArgumentCaptor<Shape> shapeCaptor = ArgumentCaptor.forClass(Shape.class);
verify(implementation).drawShape(eq(nativeGraphics), shapeCaptor.capture(), eq(stroke));
Rectangle bounds = shapeCaptor.getValue().getBounds();
assertEquals(3, bounds.getX());
assertEquals(4, bounds.getY());
}

@Test
void testFillShapeWithPaintUsesCustomPaint() throws Exception {
when(implementation.isShapeSupported(nativeGraphics)).thenReturn(true);
when(implementation.isShapeClipSupported(nativeGraphics)).thenReturn(true);
when(implementation.getClipX(nativeGraphics)).thenReturn(0);
when(implementation.getClipY(nativeGraphics)).thenReturn(0);
when(implementation.getClipWidth(nativeGraphics)).thenReturn(100);
when(implementation.getClipHeight(nativeGraphics)).thenReturn(100);
Graphics graphics = newGraphics();
Paint paint = mock(Paint.class);
graphics.setColor(paint);
Rectangle shape = new Rectangle(0, 0, 10, 10);
graphics.fillShape(shape);
verify(paint).paint(same(graphics), eq(0.0), eq(0.0), eq(10.0), eq(10.0));
verify(implementation).setClip(eq(nativeGraphics), any(Shape.class));
verify(implementation).clipRect(nativeGraphics, 0, 0, 100, 100);
verify(implementation).setClip(nativeGraphics, 0, 0, 100, 100);
}

@Test
void testPushAndPopClipDelegates() throws Exception {
Graphics graphics = newGraphics();
graphics.pushClip();
graphics.popClip();
verify(implementation).pushClip(nativeGraphics);
verify(implementation).popClip(nativeGraphics);
}

@Test
void testDrawLineAppliesTranslation() throws Exception {
Graphics graphics = newGraphics();
graphics.translate(2, 3);
graphics.drawLine(1, 1, 4, 4);
verify(implementation).drawLine(nativeGraphics, 3, 4, 6, 7);
}

@Test
void testGetClipReflectsCurrentTranslation() throws Exception {
when(implementation.getClipX(nativeGraphics)).thenReturn(50);
when(implementation.getClipY(nativeGraphics)).thenReturn(60);
Graphics graphics = newGraphics();
graphics.translate(5, 7);
assertEquals(45, graphics.getClipX());
assertEquals(53, graphics.getClipY());
}

@Test
void testSetAlphaDelegatesToImplementation() throws Exception {
Graphics graphics = newGraphics();
graphics.setAlpha(128);
verify(implementation).setAlpha(nativeGraphics, 128);
}
}
Loading
Loading