tester project

This commit is contained in:
Martin Pernollet 2018-02-24 22:15:36 +01:00
parent 15c28a492c
commit 82319ab910
28 changed files with 18094 additions and 0 deletions

18
jzy3d-tester/.gitignore vendored Normal file
View File

@ -0,0 +1,18 @@
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
/target/
.classpath
.project
.settings/

44
jzy3d-tester/README.md Normal file
View File

@ -0,0 +1,44 @@
# jzy3d-tester
A set of tools to test charts
## ChartTester
ChartTester is A non regression test tool allowing to compare screenshots of charts.
Works as follow
- Generates an image first time the test is ran. The developer should verify the image is correct.
- Compare a chart screenshot with the reference image. Test succeed if the two images are similar. If image differ, a DIFF image is generated indicating where pixel differ.
```java
Chart chart = ...;
ChartTester.assertSimilar(chart, "path/to/reference.png");
```
## Mocks
A simple implementation of GL interface is provided to keep in memory all calls to GL primitives (glVertex3f, glColor, etc).
It is used to ensure Jzy3d geometries and datamodel properly lead to expected GL calls :
```java
// Given
Point p = new Point();
p.setData(new Coord3d(3, 30, 1000));
// When
GLMock glMock = new GLMock();
p.draw(glMock, null, null);
// Then
Assert.assertTrue(glMock.vertex3f_contains(3, 30, 1000));
```
## Replay
Replay is a tool to record a sequence of mouse actions on a chart and then replay the mouse scenario to ensure the final chart image is the same as the reference scenario.

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

64
jzy3d-tester/pom.xml Normal file
View File

@ -0,0 +1,64 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.jzy3d</groupId>
<artifactId>jzy3d-tester</artifactId>
<version>1.0.2-SNAPSHOT</version>
<name>Jzy3d Tester</name>
<parent>
<groupId>org.jzy3d</groupId>
<artifactId>jzy3d-master</artifactId>
<version>1.0.2-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.jzy3d</groupId>
<artifactId>jzy3d-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<type>jar</type>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.6</version>
<configuration>
<systemProperties>
<property>
<name>java.util.logging.config.file</name>
<value>logging.properties</value>
</property>
</systemProperties>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- RELEASE PLUGIN TO HELP CREATE RELEASE BRANCHES -->
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,58 @@
package org.jzy3d.junit;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import org.jzy3d.maths.IntegerCoord2d;
public class ChartTestFailed extends Exception{
/**
*
*/
private static final long serialVersionUID = 3514756078633688965L;
public ChartTestFailed() {
super();
}
public ChartTestFailed(String message, Throwable cause) {
super(message, cause);
}
public ChartTestFailed(String message) {
super(message);
}
public ChartTestFailed(Throwable cause) {
super(cause);
}
public ChartTestFailed(String message, BufferedImage actual, BufferedImage expected) {
super(message);
this.actual = actual;
this.expected = expected;
}
public BufferedImage getActualImage() {
return actual;
}
public BufferedImage getExpectedImage() {
return expected;
}
public void addDiffCoordinates(int i, int j){
if(diffs==null)
diffs = new ArrayList<IntegerCoord2d>();
diffs.add(new IntegerCoord2d(i, j));
}
public List<IntegerCoord2d> getDiffCoordinates(){
return diffs;
}
protected BufferedImage actual;
protected BufferedImage expected;
protected List<IntegerCoord2d> diffs;
}

View File

@ -0,0 +1,319 @@
package org.jzy3d.junit;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.apache.log4j.Logger;
import org.junit.Assert;
import org.jzy3d.chart.AWTChart;
import org.jzy3d.chart.Chart;
import org.jzy3d.chart.controllers.mouse.camera.AWTCameraMouseController;
import org.jzy3d.chart.factories.AWTChartComponentFactory;
import org.jzy3d.chart.factories.IChartComponentFactory.Toolkit;
import org.jzy3d.maths.IntegerCoord2d;
import org.jzy3d.plot3d.primitives.AbstractDrawable;
import org.jzy3d.plot3d.rendering.canvas.Quality;
import org.jzy3d.plot3d.rendering.view.AWTRenderer3d;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.util.texture.TextureData;
import com.jogamp.opengl.util.texture.TextureIO;
/**
* Primitives for chart tests.
*
* A chart having a screenshot different from the test case
* image will generate throw a ChartTestFailed exception.
*
* @author martin
*/
public class ChartTester{
static Logger logger = Logger.getLogger(ChartTester.class);
public static AWTChart offscreen(AbstractDrawable... drawables) {
// Initialize chart
Quality q = Quality.Intermediate;
AWTChartComponentFactory f = new AWTChartComponentFactory();
AWTChart chart = (AWTChart)f.newChart(q, Toolkit.offscreen);
AWTCameraMouseController mouse = (AWTCameraMouseController) chart.addMouseCameraController();
// Optimise processor
chart.setAnimated(false);// keep animated otherwise mouse wheel not properly updating
mouse.setUpdateViewDefault(!chart.getQuality().isAnimated());
for (AbstractDrawable d : drawables)
chart.add(d);
return chart;
}
public static void assertSimilar(Chart chart, String testImage){
try {
new ChartTester().execute(chart, testImage);
} catch (IOException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
assertTrue(testImage, true);
}
/*
* In Java, a mouse click only registers if the mouse is pressed and
* released without moving the mouse at all. This is difficult for most
* users to accomplish, so most UI elements (like buttons) react to the
* mouse press and release events and ignore the "click".
*/
/**
* Run a chart and verify if its screenshot is pixelwise similar to the test
* case image.
*
* If test case image does not exist, build it for the first time.
*
* Failure to compare the chart with the test case image will create an
* image <code>data/tests/error-[name].png</code>. This image is always
* deleted before running a testcase.
*
* Calling clean() will delete the test case image.
*
* @param chart
* @param testImage
* @throws IOException
* if a non chart related error occurs. Actual chart test errors
* call <code>fail(...)</code>
*/
public void execute(Chart chart, String testImage) throws IOException {
clean(getTestCaseFailedFileName());
if (!isBuilt(testImage))
build(chart, testImage);
test(chart, testImage);
}
public void execute(Chart chart) throws IOException {
execute(chart, getTestCaseFileName());
}
/* Primitives to test images */
public void clean(String testImage) {
if (!cleanFile(testImage) && isBuilt(testImage))
logger.warn("test case file not cleaned: " + testImage);
}
public boolean cleanFile(String file) {
return new File(file).delete();
}
public void build(Chart chart, String testImage) throws IOException {
logger.warn("building the screenshot to assert later as no test image is available: " + testImage);
screenshot(chart, testImage);
}
public void build(TextureData image, String testImage) throws IOException {
logger.warn("saving the image to assert later as no test image is available: " + testImage);
screenshot(image, testImage);
}
public boolean isBuilt(String testImage) {
return new File(testImage).exists();
}
public void test(Chart chart, String testImage) throws IOException {
try {
logger.info("compare chart with " + testImage);
compare(chart, testImage);
} catch (IOException e) {
fail("IOException: " + e.getMessage() + " for " + testImage);
} catch (ChartTestFailed e) {
String errorFile = getTestCaseFailedFileName() + new File(testImage).getName().replace(".", "#ERROR#.");
String diffFile = getTestCaseFailedFileName() + new File(testImage).getName().replace(".", "#DIFF#.");
screenshot(chart, errorFile);
BufferedImage expected = e.getExpectedImage();
for(IntegerCoord2d diffs : e.getDiffCoordinates()){
pixelInvert(expected, diffs);
}
ImageIO.write(expected, "png", new File(diffFile));
fail("Chart test failed: " + e.getMessage() + " see " + testImage);
}
}
private void pixelInvert(BufferedImage expected, IntegerCoord2d diffs) {
int rgb = expected.getRGB(diffs.x, diffs.y);
int alpha = ((rgb >> 24) & 0xff);
int red = ((rgb >> 16) & 0xff);
int green = ((rgb >> 8) & 0xff);
int blue = ((rgb ) & 0xff);
rgb = (alpha << 24) | (255-red << 16) | (255-green << 8) | 255-blue;
expected.setRGB(diffs.x, diffs.y, rgb);
}
/* */
/**
* Compare the image displayed by the chart with an image given by filename
* @param chart
* @param filename
* @throws IOException
* @throws ChartTestFailed
*/
public void compare(Chart chart, String filename) throws IOException, ChartTestFailed {
// Will compare buffered image
if(chart.getCanvas().getRenderer() instanceof AWTRenderer3d){
chart.screenshot();
AWTRenderer3d awtR = (AWTRenderer3d)chart.getCanvas().getRenderer();
BufferedImage actual = awtR.getLastScreenshotImage();
BufferedImage expected = loadBufferedImage(filename);
compare(actual, expected);
}
else {
TextureData actual = chart.screenshot();
TextureData expected = loadTextureData(filename, chart.getView().getCurrentGL());
fail("CAN NOT COMPARE TEXTURE DATA FOR THE MOMENT");
}
}
public BufferedImage loadBufferedImage(String filename) throws IOException{
return ImageIO.read(new File(filename));
}
public TextureData loadTextureData(String filename, GL gl) throws IOException {
TextureData i2 = TextureIO.newTextureData(gl.getGLProfile(), new File(filename), true, null);
return i2;
}
public void compare(BufferedImage actual, BufferedImage expected) throws ChartTestFailed {
// int rbg = image.getRGB((int) x, (maxRow) - ((int) y));
int i1W = actual.getWidth();
int i1H = actual.getHeight();
int i2W = expected.getWidth();
int i2H = expected.getHeight();
if (i1W == i2W && i1H == i2H) {
ChartTestFailed potentialFailure = new ChartTestFailed("pixel diff", actual, expected);
boolean ok = true;
for (int i = 0; i < i1W; i++) {
for (int j = 0; j < i1H; j++) {
int p1rgb = actual.getRGB(i, j);
int p2rgb = expected.getRGB(i, j);
if (p1rgb != p2rgb) {
ok = false;
potentialFailure.addDiffCoordinates(i, j);
//String m = "pixel diff start @(" + i + "," + j + ")";
//throw new ChartTestFailed(m, i1, i2);
}
}
}
if(!ok){
throw potentialFailure;
}
} else {
String m = "image size differ: i1={" + i1W + "," + i1H + "} i2={" + i2W + "," + i2H + "}";
throw new ChartTestFailed(m);
}
}
/**
* Compare images pixel-wise.
*
* @param i1
* @param i2
* @throws ChartTestFailed
* as soon as a pixel difference can be found
*/
public void compare(TextureData i1, TextureData i2) throws ChartTestFailed {
// int rbg = image.getRGB((int) x, (maxRow) - ((int) y));
int i1W = i1.getWidth();
int i1H = i1.getHeight();
int i2W = i2.getWidth();
int i2H = i2.getHeight();
if (i1W == i2W && i1H == i2H) {
for (int i = 0; i < i1W; i++) {
for (int j = 0; j < i1H; j++) {
/*int p1rgb = i1.getRGB(i, j);
int p2rgb = i2.getRGB(i, j);
if (p1rgb != p2rgb) {
String m = "pixel diff @(" + i + "," + j + ")";
throw new ChartTestFailed(m, i1, i2);
}*/
}
}
} else {
String m = "image size differ: i1={" + i1W + "," + i1H + "} i2={" + i2W + "," + i2H + "}";
throw new ChartTestFailed(m);
}
}
/* */
public void screenshot(Chart chart, String filename) throws IOException {
screenshot(chart.screenshot(), filename);
}
public void screenshot(TextureData image, String testImage) throws IOException {
File output = new File(testImage);
if (!output.getParentFile().exists())
output.getParentFile().mkdirs();
TextureIO.write(image, output);
}
/* */
public File getTestCaseFile() {
return new File(getTestCaseFileName());
}
public String getTestCaseFileName() {
return getTestCaseFileName(getTestName());
}
public String getTestCaseFileName(String testName) {
return getTestCaseFolder() + testName + ".png";
}
public String getTestCaseFailedFileName() {
return getTestCaseFolder() + "error-";
}
public String getTestCaseFolder() {
return "data/tests/";
}
public String getTestName() {
return this.getClass().getSimpleName();
}
public String getTestCanvasType() {
return "offscreen, " + WIDTH + ", " + HEIGHT;
}
/* */
// int bufImgType = BufferedImage.TYPE_3BYTE_BGR;// );
protected int WIDTH = 800;
protected int HEIGHT = 600;
}

View File

@ -0,0 +1,256 @@
package org.jzy3d.junit.replay;
import java.awt.Component;
import java.awt.Frame;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.File;
import java.io.IOException;
import org.apache.log4j.Logger;
import org.jzy3d.chart.Chart;
import org.jzy3d.junit.replay.events.ComponentEventLog;
import org.jzy3d.junit.replay.events.IComponentEventLog.ComponentEventType;
import org.jzy3d.junit.replay.events.IEventLog;
import org.jzy3d.junit.replay.events.IKeyEventLog.KeyEventType;
import org.jzy3d.junit.replay.events.IMouseEventLog.MouseEventType;
import org.jzy3d.junit.replay.events.IWindowEventLog.WindowEventType;
import org.jzy3d.junit.replay.events.KeyEventLog;
import org.jzy3d.junit.replay.events.MouseEventLog;
import org.jzy3d.junit.replay.events.WindowEventLog;
import org.jzy3d.utils.LoggerUtils;
import com.jogamp.opengl.util.texture.TextureIO;
public class EventRecorder extends Timestamped implements MouseListener, MouseMotionListener, MouseWheelListener, KeyListener, ComponentListener, WindowListener {
protected Component awt;
protected Scenario scenario;
protected Chart chart;
protected int nScreenshot = 0;
public EventRecorder(String scenario, Component awt) {
this(scenario, awt, null);
}
public EventRecorder(String scenario, Component awt, Frame frame) {
this(scenario, awt, frame, null);
}
public EventRecorder(String scenario, Component awt, Frame frame, Chart chart) {
this.chart = chart;
this.awt = awt;
this.scenario = new Scenario(scenario);
addListeners(awt);
if(frame!=null)
addWindowListeners(frame);
t.tic();
LoggerUtils.minimal();
}
protected void addListeners(Component awt) {
awt.addMouseListener(this);
awt.addMouseMotionListener(this);
awt.addMouseWheelListener(this);
awt.addKeyListener(this);
awt.addComponentListener(this);
}
protected void addWindowListeners(Frame frame) {
frame.addWindowListener(this);
}
protected void register(IEventLog event) {
debugMs(event);
scenario.register(event);
}
protected void onExit() {
try {
scenario.save();
} catch (Exception e) {
logger.error(e);
}
}
public Chart getChart() {
return chart;
}
public void setChart(Chart chart) {
this.chart = chart;
}
protected boolean isScreenshotKey(KeyEvent e) {
return e.getKeyChar() == 's';
}
protected boolean isExit(KeyEvent e) {
return e.getKeyChar() == 'q';
}
protected String screenshotFile(int n) {
return ScenarioFiles.SCENARIO_FOLDER + "/" + scenario.getName() + "/" + scenario.getName() + "-" + n + ".png";
}
protected void screenshot(Chart chart, String filename) throws IOException {
File output = new File(filename);
if (!output.getParentFile().exists())
output.mkdirs();
TextureIO.write(chart.screenshot(), output);
Logger.getLogger(EventRecorder.class).info("screenshot:" + filename);
}
/* MOUSE */
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
register(new MouseEventLog(MouseEventType.MOUSE_WHEEL, e.getWheelRotation(), getButton(e), since()));
}
@Override
public void mouseDragged(MouseEvent e) {
register(new MouseEventLog(MouseEventType.MOUSE_DRAGGED, e.getX(), e.getY(), getButton(e), since()));
}
@Override
public void mouseMoved(MouseEvent e) {
register(new MouseEventLog(MouseEventType.MOUSE_MOVED, e.getX(), e.getY(), getButton(e), since()));
}
@Override
public void mouseClicked(MouseEvent e) {
register(new MouseEventLog(MouseEventType.MOUSE_CLICKED, e.getX(), e.getY(), getButton(e), since()));
}
@Override
public void mousePressed(MouseEvent e) {
register(new MouseEventLog(MouseEventType.MOUSE_PRESSED, e.getX(), e.getY(), getButton(e), since()));
}
@Override
public void mouseReleased(MouseEvent e) {
register(new MouseEventLog(MouseEventType.MOUSE_RELEASED, e.getX(), e.getY(), getButton(e), since()));
}
protected int getButton(MouseEvent e) {
int button = 0;
if (e.getButton() == MouseEvent.BUTTON1)
button = InputEvent.BUTTON1_MASK;
if (e.getButton() == MouseEvent.BUTTON2)
button = InputEvent.BUTTON2_MASK;
if (e.getButton() == MouseEvent.BUTTON3)
button = InputEvent.BUTTON3_MASK;
return button;
}
/* COMPONENT */
@Override
public void componentHidden(ComponentEvent e) {
register(new ComponentEventLog(ComponentEventType.COMPONENT_HIDDEN, since()));
}
@Override
public void componentMoved(ComponentEvent e) {
register(new ComponentEventLog(ComponentEventType.COMPONENT_MOVED, e.getComponent().getSize(), e.getComponent().getBounds(), since()));
}
@Override
public void componentResized(ComponentEvent e) {
register(new ComponentEventLog(ComponentEventType.COMPONENT_RESIZED, e.getComponent().getSize(), e.getComponent().getBounds(), since()));
}
@Override
public void componentShown(ComponentEvent e) {
register(new ComponentEventLog(ComponentEventType.COMPONENT_SHOWN, e.getComponent().getSize(), e.getComponent().getBounds(), since()));
}
/* KEY */
@Override
public void keyTyped(KeyEvent e) {
// handle screenshot query
if (isScreenshotKey(e)) {
try {
screenshot(chart, screenshotFile(nScreenshot));
} catch (IOException e1) {
Logger.getLogger(EventRecorder.class).error(screenshotFile(nScreenshot), e1);
}
nScreenshot++;
}
else if(isExit(e)){
onExit();
}
// or register standard event
else {
register(new KeyEventLog(KeyEventType.KEY_TYPED, e.getKeyCode(), since()));
}
}
@Override
public void keyPressed(KeyEvent e) {
register(new KeyEventLog(KeyEventType.KEY_PRESS, e.getKeyCode(), since()));
}
@Override
public void keyReleased(KeyEvent e) {
register(new KeyEventLog(KeyEventType.KEY_RELEASE, e.getKeyCode(), since()));
}
// protected String s
/* WINDOW */
@Override
public void windowClosing(WindowEvent e) {
register(new WindowEventLog(WindowEventType.WINDOW_CLOSING, e.getWindow().getSize(), since()));
onExit();
}
@Override
public void windowOpened(WindowEvent e) {
register(new WindowEventLog(WindowEventType.WINDOW_OPENED, e.getWindow().getSize(), since()));
}
@Override
public void windowClosed(WindowEvent e) {
register(new WindowEventLog(WindowEventType.WINDOW_CLOSED, since()));
}
/* UNUSED */
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void windowActivated(WindowEvent arg0) {
}
@Override
public void windowDeactivated(WindowEvent arg0) {
}
@Override
public void windowDeiconified(WindowEvent arg0) {
}
@Override
public void windowIconified(WindowEvent arg0) {
}
}

View File

@ -0,0 +1,305 @@
package org.jzy3d.junit.replay;
import java.awt.AWTException;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Insets;
import java.awt.Robot;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Iterator;
import org.apache.log4j.Logger;
import org.jzy3d.junit.replay.events.IComponentEventLog;
import org.jzy3d.junit.replay.events.IComponentEventLog.ComponentEventType;
import org.jzy3d.junit.replay.events.IEventLog;
import org.jzy3d.junit.replay.events.IKeyEventLog;
import org.jzy3d.junit.replay.events.IKeyEventLog.KeyEventType;
import org.jzy3d.junit.replay.events.IMouseEventLog;
import org.jzy3d.junit.replay.events.IMouseEventLog.MouseEventType;
import org.jzy3d.junit.replay.events.IWindowEventLog;
public class EventReplay extends Timestamped{
static Logger logger = Logger.getLogger(EventReplay.class);
protected Component component;
protected Frame frame;
protected Robot robot;
protected Scenario currentScenario;
protected boolean mute = false;
protected boolean mustStop = false;
public EventReplay(final Component component, Frame frame){
/*component.addMouseListener(new MouseAdapter(){
public void mouseDragged(MouseEvent e){
logger.info("DRAGGING");
}
});*/
this.component = component;
this.frame = frame;
configureFocus(component, frame);
}
protected void configureFocus(Component component, Frame frame) {
component.addFocusListener(new FocusListener() {
@Override
public void focusLost(FocusEvent arg0) {
mute();
logger.info("mute event replay as component lost focus");
}
@Override
public void focusGained(FocusEvent arg0) {
unmute();
logger.info("unmute event replay as component gained focus");
}
});
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent arg0) {
stop();
logger.info("stop replay as window closes");
}
});
}
/* REPLAY */
public void replay(String scenario) throws Exception {
currentScenario = new Scenario(scenario);
currentScenario.load();
replay(currentScenario);
}
public void replay(Scenario scenario) {
//component.requestFocusInWindow();
getRobot().setAutoWaitForIdle(false);
start();
while(scenario.getEvents().size()>0){
Iterator<IEventLog> events = scenario.getEvents().iterator();
while(events.hasNext()){
IEventLog event = events.next();
if(elapsedMs(event)){
if(!mute)
replay(event);
//debug(event);
events.remove();
}
if(mustStop){
scenario.info("done replay after " + elapsedMs()/1000 + " s");
scenario.info("exiting before end");
return;
}
}
}
scenario.info("done replay after " + elapsedMs()/1000 + " s");
/*for(IEventLog event: scenario.getEvents()){
replay(event);
}*/
}
public void replay(IEventLog event) {
if(event instanceof IMouseEventLog)
replay((IMouseEventLog)event);
else if(event instanceof IKeyEventLog)
replay((IKeyEventLog)event);
else if(event instanceof IComponentEventLog)
replay((IComponentEventLog)event);
else if(event instanceof IWindowEventLog)
replay((IWindowEventLog)event);
}
public void replay(IMouseEventLog mouse) {
Insets insets = frame.getInsets();
MouseEventType type = mouse.getType();
if(type==MouseEventType.MOUSE_CLICKED)
getRobot().mousePress(mouse.getButton());
else if(type==MouseEventType.MOUSE_PRESSED){
getRobot().mousePress(mouse.getButton());
}
else if(type==MouseEventType.MOUSE_RELEASED){
getRobot().mouseRelease(mouse.getButton());
}
else if(type==MouseEventType.MOUSE_DRAGGED){
getRobot().mouseMove(moveX(mouse, insets), moveY(mouse, insets));
}
else if(type==MouseEventType.MOUSE_MOVED){
getRobot().mouseMove(moveX(mouse, insets), moveY(mouse, insets));
}
else if(type==MouseEventType.MOUSE_WHEEL){
getRobot().mouseWheel(mouse.getValue());
}
//if(type!=MouseEventType.MOUSE_DRAGGED && type!=MouseEventType.MOUSE_MOVED)
// log(mouse);
}
protected int moveY(IMouseEventLog mouse, Insets insets) {
return mouse.getCoord().y + frame.getBounds().y + insets.top;
}
protected int moveX(IMouseEventLog mouse, Insets insets) {
return mouse.getCoord().x + frame.getBounds().x + insets.left;
}
public void replay(IKeyEventLog key) {
try{
if(key.getKeyCode()!=0){
if(key.getType()==KeyEventType.KEY_PRESS)
doKeyPress(key);
else if(key.getType()==KeyEventType.KEY_RELEASE)
doKeyRelease(key);
else
logger.warn("ignore key event " + key);
}
else
logger.warn("ignore key event " + key + " because keycode=0");
}
catch(Exception e){
log(key);
e.printStackTrace();
}
}
protected void doKeyPress(IKeyEventLog key){
getRobot().keyPress(key.getKeyCode());
//keys[key.getKeyCode()]++;
}
protected void doKeyRelease(IKeyEventLog key){
getRobot().keyRelease(key.getKeyCode());
//keys[key.getKeyCode()]--;
}
protected void mute(){
mute = true;
}
protected void unmute() {
mute = false;
}
protected void stop() {
mustStop = true;
}
protected int[] keys = new int[256];
public void replay(IWindowEventLog window) {
log(window, " not supported");
}
public void replay(IComponentEventLog component) {
if(component.getType().equals(ComponentEventType.COMPONENT_RESIZED)){
Dimension size = component.getSize();
frame.setSize(size);
}
//log(component, " not supported");
}
protected void log(IEventLog event){
logger.info("replay: " + event);
}
protected void log(IEventLog event, String info){
logger.info("replay: " + event + " " + info);
}
public Robot getRobot(){
if(robot==null)
try {
robot = new Robot();
} catch (AWTException e) {
throw new RuntimeException(e);
}
robot.setAutoWaitForIdle(true);
return robot;
}
/* UTILS 2 */
/**
MOUSE_PRESSED, x:170, y:154, bt:0, since:925
MOUSE_DRAGGED, x:149, y:171, bt:0, since:1428
MOUSE_RELEASED, x:125, y:56, bt:0, since:3898
MOUSE_MOVED, x:107, y:55, bt:0, since:3899
* @param mouse
*/
protected boolean detectDragEnd(IMouseEventLog mouse){
MouseEventType type = mouse.getType();
if(type==MouseEventType.MOUSE_PRESSED){
drag = new IMouseEventLog[3];
drag[0] = mouse;
}
else if(type==MouseEventType.MOUSE_DRAGGED)
drag[1] = mouse;
else if(type==MouseEventType.MOUSE_RELEASED){
drag[2] = mouse;
boolean f = full(drag);
drag = new IMouseEventLog[3];
if(f)
return true;
}
return false;
}
protected boolean full(IMouseEventLog[] drag){
return drag!=null && drag[0]!=null && drag[1]!=null && drag[2]!=null;
}
protected IMouseEventLog[] drag = new IMouseEventLog[3];
/* UTILS */
protected void debug(IEventLog event) {
if(event instanceof IMouseEventLog){
IMouseEventLog mouse = (IMouseEventLog)event;
//if(isMouseMoveOrDrag(mouse)){
debugMs(event);
//}
}
else
debugMs(event);
}
protected boolean isMouseMoveOrDrag(IMouseEventLog mouse) {
return mouse.getType()!=MouseEventType.MOUSE_DRAGGED && mouse.getType()!=MouseEventType.MOUSE_MOVED;
}
protected void addVerifyingListeners(final Component component){
component.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
logger.info("ASSERT DRAGGED CALLED ON COMPONENT");
}
});
component.addMouseListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
logger.info("ASSERT MOVED CALLED ON COMPONENT");
}
});
}
protected void addFocusListener(final Component component, Frame frame) {
frame.addWindowFocusListener(new WindowAdapter() {
@Override
public void windowGainedFocus(WindowEvent e) {
component.requestFocusInWindow();
}
});
}
}

View File

@ -0,0 +1,10 @@
package org.jzy3d.junit.replay;
public class EventReplayDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}

View File

@ -0,0 +1,105 @@
package org.jzy3d.junit.replay;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.jzy3d.io.SimpleFile;
import org.jzy3d.junit.replay.events.EventParser;
import org.jzy3d.junit.replay.events.IEventLog;
public class Scenario {
static Logger logger = Logger.getLogger(Scenario.class);
protected List<IEventLog> events;
protected String name;
public Scenario(String name){
this.name = name;
this.events = new ArrayList<IEventLog>();
}
public void register(IEventLog event){
logger.info(event);
events.add(event);
}
public List<IEventLog> getEvents() {
return events;
}
public void setEvents(List<IEventLog> events) {
this.events = events;
}
public void save() throws Exception{
save(ScenarioFiles.SCENARIO_FOLDER + name + "/", name);
}
protected void save(String folder) throws Exception{
save(folder + "/" + name + "/", name);
}
protected void save(String folder, String name) throws Exception{
File ff = new File(folder);
if(!ff.exists())
ff.mkdirs();
saveEvents(folder, name);
}
protected void saveEvents(String folder, String name) throws Exception {
StringBuilder sb = new StringBuilder();
for(IEventLog log: events)
sb.append(log.toString() + "\n");
String file = getEventFile(folder, name);
SimpleFile.write(sb.toString(), file);
info("saved " + events.size() + " events in " + file);
}
public void info(String file) {
logger.info("---------------------------------------------------");
logger.info(file);
logger.info("---------------------------------------------------");
//Logger.getLogger(this.getClass()).info("saved events: " + file);
}
public String getEventFile(String folder, String name) {
return folder + name + ScenarioFiles.FILE_EVENTS;
}
/* */
public void load() throws Exception{
load(ScenarioFiles.SCENARIO_FOLDER, name);
}
protected void load(String folder, String name) throws IOException{
loadEvents(folder, name);
}
protected void loadEvents(String folder, String name) throws IOException {
events.clear();
String file = getEventFile(folder, name);
List<String> lines = SimpleFile.read(file);
EventParser parser = new EventParser();
for(String s: lines){
//logger.info("read : " + s);
IEventLog event = parser.parse(s);
if(event!=null){
logger.info("parsed : " + event);
events.add(event);
}
else
logger.error("non parsable event : " + s);
}
info("parsed " + events.size() + " events from " + file);
}
public String getName() {
return name;
}
}

View File

@ -0,0 +1,7 @@
package org.jzy3d.junit.replay;
public class ScenarioFiles {
public static String SCENARIO_FOLDER = "data/scenarios/";
public static String FILE_EVENTS = "-events.txt";
public static String FILE_SCREENSHOT = "-screenshot-";
}

View File

@ -0,0 +1,60 @@
package org.jzy3d.junit.replay;
import org.apache.log4j.Logger;
import org.jzy3d.junit.replay.events.IEventLog;
import org.jzy3d.maths.TicToc;
/** To be enhanced (wrapper tictoc)*/
public class Timestamped {
static Logger logger = Logger.getLogger(Timestamped.class);
protected TicToc t = new TicToc();
public Timestamped() {
super();
}
public void start() {
t.tic();
}
public long startup() {
return t.getStart();
}
public long now() {
long now = t.rawToc();
return now;
}
public long since() {
t.toc();
return (long)t.elapsedMilisecond();
}
public long since(long now) {
return now - startup();
}
public long elapsedMs() {
return (now() - startup())/(1000*1000);
}
public boolean elapsedMs(IEventLog event) {
return elapsedMs(event.since());
}
public boolean elapsedMs(long time) {
return elapsedMs() > time;
}
public void debugMs(IEventLog event) {
debugMs(event.since());
}
public void debugMs(long time){
long elapsed = elapsedMs();
logger.info("-> @[" + time/1000 + " s] (" + time + " ms): elapsed:" + elapsed);
//logger.info("-> @[" + time/1000 + " s] (" + time + " ms): elapsed:" + elapsed + ", now:" + now + ", start:" + startup());
}
}

View File

@ -0,0 +1,16 @@
package org.jzy3d.junit.replay.events;
public class AbstractEventLog implements IEventLog{
protected long since;
@Override
public long since() {
return since;
}
public AbstractEventLog() {
super();
}
}

View File

@ -0,0 +1,60 @@
package org.jzy3d.junit.replay.events;
import java.awt.Dimension;
import java.awt.Rectangle;
public class ComponentEventLog extends AbstractEventLog implements IComponentEventLog {
protected ComponentEventType type;
protected Object value;
protected Dimension size;
protected Rectangle bounds;
public ComponentEventLog(ComponentEventType type, long since) {
this.type = type;
this.since = since;
}
public ComponentEventLog(ComponentEventType type, Object value, long since) {
this.type = type;
this.value = value;
this.since = since;
}
public ComponentEventLog(ComponentEventType type, Dimension size, Rectangle bounds, long since) {
this.type = type;
this.since = since;
this.size = size;
this.bounds = bounds;
}
@Override
public ComponentEventType getType() {
return type;
}
@Override
public Object getValue() {
return value;
}
@Override
public Dimension getSize() {
return size;
}
@Override
public Rectangle getBounds() {
return bounds;
}
@Override
public String toString() {
if (value != null)
return type + ", value:" + value + ", since:" + since;
else if (size != null || bounds!=null)
return type + ", size:" + size + ", bounds:" + bounds + ", since:" + since;
else
return type + ", since:" + since;
}
}

View File

@ -0,0 +1,154 @@
package org.jzy3d.junit.replay.events;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jzy3d.junit.replay.events.IComponentEventLog.ComponentEventType;
import org.jzy3d.junit.replay.events.IKeyEventLog.KeyEventType;
import org.jzy3d.junit.replay.events.IMouseEventLog.MouseEventType;
import org.jzy3d.junit.replay.events.IWindowEventLog.WindowEventType;
public class EventParser {
static String word = "\\w+";
static String word_list = "[\\w|,]+";
static String num = "\\d+";
static String antislash = "\\\\";
static String slash = "\\/";
/*
COMPONENT_RESIZED, size:java.awt.Dimension[width=490,height=470], bounds:java.awt.Rectangle[x=5,y=25,width=490,height=470], since:524
COMPONENT_MOVED, size:java.awt.Dimension[width=498,height=471], bounds:java.awt.Rectangle[x=1,y=28,width=498,height=471], since:785
WINDOW_OPENED, v:java.awt.Dimension[width=500,height=500], since:525
WINDOW_CLOSING, v:java.awt.Dimension[width=500,height=500], since:5120
WINDOW_CLOSED, since:5120
MOUSE_MOVED, x:232, y:94, bt:0, since:702
MOUSE_PRESSED, x:244, y:245, bt:1, since:1397
MOUSE_DRAGGED, x:241, y:239, bt:0, since:1558
MOUSE_RELEASED, x:145, y:58, bt:1, since:16214
MOUSE_WHEEL, v:1, bt:0, since:3205
KEY_PRESS, code:83, since:6750
KEY_TYPED, code:0, since:6750
KEY_RELEASE, code:83, since:6946
*/
static Pattern mouseMovedPattern = Pattern.compile("MOUSE_MOVED, x:("+num+"), y:("+num+"), bt:("+num+"), since:("+num+")");
static Pattern mousePressedPattern = Pattern.compile("MOUSE_PRESSED, x:("+num+"), y:("+num+"), bt:("+num+"), since:("+num+")");
static Pattern mouseDraggedPattern = Pattern.compile("MOUSE_DRAGGED, x:("+num+"), y:("+num+"), bt:("+num+"), since:("+num+")");
static Pattern mouseReleasePattern = Pattern.compile("MOUSE_RELEASED, x:("+num+"), y:("+num+"), bt:("+num+"), since:("+num+")");
static Pattern mouseWheelPattern = Pattern.compile("MOUSE_WHEEL, v:("+num+"), bt:("+num+"), since:("+num+")");
static Pattern keyPressPattern = Pattern.compile("KEY_PRESS.*, code:("+num+"), since:("+num+")");
static Pattern keyTypedPattern = Pattern.compile("KEY_TYPED.*, code:("+num+"), since:("+num+")");
static Pattern keyReleasePattern = Pattern.compile("KEY_RELEASE.*, code:("+num+"), since:("+num+")");
static Pattern windowOpenedPattern = Pattern.compile("WINDOW_OPENED.*, since:("+num+")");
static Pattern windowClosingPattern = Pattern.compile("WINDOW_CLOSING.*, since:("+num+")");
static Pattern windowClosedPattern = Pattern.compile("WINDOW_CLOSED.*, since:("+num+")");
static Pattern componentResizedPattern = Pattern.compile("COMPONENT_RESIZED, size:java.awt.Dimension[width=("+num+"),height=("+num+")], bounds:java.awt.Rectangle[x=("+num+"),y=("+num+"),width=("+num+"),height=("+num+")] since:("+num+")");
//static Pattern componentResizedPattern = Pattern.compile("COMPONENT_RESIZED.*, since:("+num+")");
static Pattern componentMovedPattern = Pattern.compile("COMPONENT_MOVED.*, since:("+num+")");
public IEventLog parse(String event){
// MOUSE
Matcher mouseMovedMatcher = mouseMovedPattern.matcher(event);
if(mouseMovedMatcher.matches())
return parseMouseEvent(mouseMovedMatcher, MouseEventType.MOUSE_MOVED);
Matcher mousePressedMatcher = mousePressedPattern.matcher(event);
if(mousePressedMatcher.matches())
return parseMouseEvent(mousePressedMatcher, MouseEventType.MOUSE_PRESSED);
Matcher mouseDraggedMatcher = mouseDraggedPattern.matcher(event);
if(mouseDraggedMatcher.matches())
return parseMouseEvent(mouseDraggedMatcher, MouseEventType.MOUSE_DRAGGED);
Matcher mouseReleasedMatcher = mouseReleasePattern.matcher(event);
if(mouseReleasedMatcher.matches())
return parseMouseEvent(mouseReleasedMatcher, MouseEventType.MOUSE_RELEASED);
Matcher mouseWheelMatcher = mouseWheelPattern.matcher(event);
if(mouseWheelMatcher.matches())
return parseMouseWheelEvent(mouseWheelMatcher);
// KEYBOARD
Matcher windowOpenMatcher = windowOpenedPattern.matcher(event);
if(windowOpenMatcher.matches())
return parseWindowEvent(windowOpenMatcher, WindowEventType.WINDOW_OPENED);
Matcher windowClosingMatcher = windowClosingPattern.matcher(event);
if(windowClosingMatcher.matches())
return parseWindowEvent(windowClosingMatcher, WindowEventType.WINDOW_CLOSING);
Matcher windowClosedMatcher = windowClosedPattern.matcher(event);
if(windowClosedMatcher.matches())
return parseWindowEvent(windowClosedMatcher, WindowEventType.WINDOW_CLOSED);
// WINDOW
Matcher keyPressMatcher = keyPressPattern.matcher(event);
if(keyPressMatcher.matches())
return parseKeyEvent(keyPressMatcher, KeyEventType.KEY_PRESS);
Matcher keyTypedMatcher = keyTypedPattern.matcher(event);
if(keyTypedMatcher.matches())
return parseKeyEvent(keyTypedMatcher, KeyEventType.KEY_TYPED);
Matcher keyReleaseMatcher = keyReleasePattern.matcher(event);
if(keyReleaseMatcher.matches())
return parseKeyEvent(keyReleaseMatcher, KeyEventType.KEY_RELEASE);
// COMPONENT
Matcher componentResizedMatcher = componentResizedPattern.matcher(event);
if(componentResizedMatcher.matches())
return parseComponentEvent(componentResizedMatcher, ComponentEventType.COMPONENT_RESIZED);
Matcher componentMovedMatcher = componentMovedPattern.matcher(event);
if(componentMovedMatcher.matches())
return parseComponentEvent(componentMovedMatcher, ComponentEventType.COMPONENT_MOVED);
return null;
}
protected IMouseEventLog parseMouseEvent(Matcher matcher, MouseEventType type) {
int x = Integer.parseInt(matcher.group(1));
int y = Integer.parseInt(matcher.group(2));
int b = Integer.parseInt(matcher.group(3));
int s = Integer.parseInt(matcher.group(4));
return new MouseEventLog(type, x, y, b, s);
}
protected IMouseEventLog parseMouseWheelEvent(Matcher matcher) {
int v = Integer.parseInt(matcher.group(1));
int b = Integer.parseInt(matcher.group(2));
int s = Integer.parseInt(matcher.group(3));
return new MouseEventLog(MouseEventType.MOUSE_WHEEL, v, b, s);
}
protected IKeyEventLog parseKeyEvent(Matcher matcher, KeyEventType type) {
int c = Integer.parseInt(matcher.group(1));
int s = Integer.parseInt(matcher.group(2));
return new KeyEventLog(type, c, s);
}
protected IWindowEventLog parseWindowEvent(Matcher matcher, WindowEventType type) {
int s = Integer.parseInt(matcher.group(1));
return new WindowEventLog(type, s);
}
protected IComponentEventLog parseComponentEvent(Matcher matcher, ComponentEventType type) {
int w = Integer.parseInt(matcher.group(1));
int h = Integer.parseInt(matcher.group(2));
int rx = Integer.parseInt(matcher.group(3));
int ry = Integer.parseInt(matcher.group(4));
int rw = Integer.parseInt(matcher.group(5));
int rh = Integer.parseInt(matcher.group(6));
int s = Integer.parseInt(matcher.group(7));
return new ComponentEventLog(type, new Dimension(w,h), new Rectangle(rx,ry,rw,rh), s);
}
}

View File

@ -0,0 +1,18 @@
package org.jzy3d.junit.replay.events;
import java.awt.Dimension;
import java.awt.Rectangle;
public interface IComponentEventLog extends IEventLog{
public ComponentEventType getType();
public Object getValue();
public Dimension getSize();
public Rectangle getBounds();
public enum ComponentEventType {
COMPONENT_HIDDEN,
COMPONENT_RESIZED,
COMPONENT_SHOWN,
COMPONENT_MOVED,
}
}

View File

@ -0,0 +1,5 @@
package org.jzy3d.junit.replay.events;
public interface IEventLog {
public long since();
}

View File

@ -0,0 +1,12 @@
package org.jzy3d.junit.replay.events;
public interface IKeyEventLog extends IEventLog{
public KeyEventType getType();
public int getKeyCode();
public enum KeyEventType{
KEY_PRESS,
KEY_RELEASE,
KEY_TYPED
}
}

View File

@ -0,0 +1,21 @@
package org.jzy3d.junit.replay.events;
import org.jzy3d.maths.IntegerCoord2d;
public interface IMouseEventLog extends IEventLog{
public MouseEventType getType();
public IntegerCoord2d getCoord();
public int getValue();
public int getButton();
public int getClicks();
public enum MouseEventType{
MOUSE_CLICKED,
MOUSE_PRESSED,
MOUSE_RELEASED,
MOUSE_MOVED,
MOUSE_DRAGGED,
MOUSE_WHEEL
}
}

View File

@ -0,0 +1,13 @@
package org.jzy3d.junit.replay.events;
public interface IWindowEventLog extends IEventLog{
public WindowEventType getType();
public Object getValue();
public enum WindowEventType{
WINDOW_OPENED,
WINDOW_CLOSING,
WINDOW_CLOSED,
WINDOW_MOVED,
}
}

View File

@ -0,0 +1,27 @@
package org.jzy3d.junit.replay.events;
public class KeyEventLog extends AbstractEventLog implements IKeyEventLog{
protected int keyCode;
protected KeyEventType type;
public KeyEventLog(KeyEventType type, int keyCode, long since) {
this.keyCode = keyCode;
this.type = type;
this.since = since;
}
@Override
public KeyEventType getType() {
return type;
}
@Override
public int getKeyCode() {
return keyCode;
}
@Override
public String toString() {
return type + ", code:" + keyCode + ", since:" + since;
}
}

View File

@ -0,0 +1,61 @@
package org.jzy3d.junit.replay.events;
import java.awt.event.InputEvent;
import org.jzy3d.maths.IntegerCoord2d;
public class MouseEventLog extends AbstractEventLog implements IMouseEventLog{
public MouseEventLog(MouseEventType type, int x, int y, int button, long since){
this.type = type;
this.button = button;
this.since = since;
this.coord = new IntegerCoord2d(x, y);
}
public MouseEventLog(MouseEventType type, int value, int button, long since){
this.type = type;
this.button = button;
this.value = value;
this.since = since;
}
@Override
public IntegerCoord2d getCoord() {
return coord;
}
@Override
public int getButton() {
return button;
}
@Override
public int getClicks() {
return clicks;
}
@Override
public MouseEventType getType() {
return type;
}
@Override
public int getValue() {
return value;
}
@Override
public String toString(){
if(coord!=null)
return type + ", x:" + coord.x + ", y:" + coord.y + ", bt:" + button + ", since:" + since;
else
return type + ", v:" + value + ", bt:" + button + ", since:" + since;
}
protected MouseEventType type;
protected IntegerCoord2d coord;
protected int value;
protected int button = InputEvent.BUTTON1_MASK;
protected int clicks;
}

View File

@ -0,0 +1,35 @@
package org.jzy3d.junit.replay.events;
public class WindowEventLog extends AbstractEventLog implements IWindowEventLog{
public WindowEventLog(WindowEventType type, long since) {
this.since = since;
this.type = type;
}
public WindowEventLog(WindowEventType type, Object value, long since) {
this.since = since;
this.type = type;
this.value = value;
}
@Override
public WindowEventType getType() {
return type;
}
@Override
public Object getValue() {
return value;
}
@Override
public String toString(){
if(value!=null)
return type + ", v:" + value + ", since:" + since;
else
return type + ", since:" + since;
}
protected WindowEventType type;
protected Object value;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
package org.jzy3d.mocks.jzy3d;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jzy3d.colors.Color;
import org.jzy3d.maths.BoundingBox3d;
import org.jzy3d.maths.Coord2d;
import org.jzy3d.maths.Coord3d;
import org.jzy3d.plot3d.rendering.view.Camera;
import org.jzy3d.plot3d.text.align.Halign;
import org.jzy3d.plot3d.text.align.Valign;
import org.jzy3d.plot3d.text.renderers.TextBitmapRenderer;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.glu.GLU;
public class MockTextBitmapRenderer extends TextBitmapRenderer{
List<Map<String,Object>> callArguments = new ArrayList<>();
@Override
public BoundingBox3d drawText(GL gl, GLU glu, Camera cam, String text, Coord3d position, Halign halign, Valign valign, Color color, Coord2d screenOffset, Coord3d sceneOffset) {
Map<String,Object> args = new HashMap<String,Object>();
args.put("text", text);
args.put("position", position);
args.put("halign", halign);
args.put("valign", valign);
args.put("color", color);
args.put("screenOffset", screenOffset);
args.put("sceneOffset", sceneOffset);
callArguments.add(args);
return new BoundingBox3d();
}
public List<Map<String, Object>> getCallArguments() {
return callArguments;
}
public Map<String, Object> getCallArguments_whereTextEquals(String text) {
for(Map<String, Object> args: callArguments){
if(text.equals(args.get("text"))){
return args;
}
}
return null;
}
}

View File

@ -0,0 +1,49 @@
package org.jzy3d.junit;
import java.awt.image.BufferedImage;
import java.io.IOException;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.jzy3d.junit.ChartTester;
import org.jzy3d.junit.ChartTestFailed;
/**
* Testing the test tool!
*
* @author martin
*
*/
public class TestChartTester {
ChartTester test;
@Before
public void before(){
test = new ChartTester();
}
@Test
public void compareImageWithHerselfSucceed() throws IOException{
BufferedImage bi = test.loadBufferedImage("data/test-test/testimage.png");
try {
test.compare(bi, bi);
} catch (ChartTestFailed e) {
Assert.fail(e.getMessage());
}
Assert.assertTrue(true);
}
@Test
public void compareImageWithAnotherFails() throws IOException{
BufferedImage bi1 = test.loadBufferedImage("data/test-test/testimage.png");
BufferedImage bi2 = test.loadBufferedImage("data/test-test/testimage2.png");
try {
test.compare(bi1, bi2);
} catch (ChartTestFailed e) {
Assert.assertTrue(e.getMessage(), true);
return;
}
Assert.fail("two different image should throw an exception");
}
}