Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

A few test classes for the renderer package

  • Loading branch information...
commit cef25d3aa3f0cf0c093efced73789fb34a320bbf 1 parent 003581e
gilleain torrance gilleain authored egonw committed
123 src/test/org/openscience/cdk/renderer/ElementUtility.java
View
@@ -0,0 +1,123 @@
+package org.openscience.cdk.renderer;
+
+import java.awt.geom.AffineTransform;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openscience.cdk.renderer.RendererModel;
+import org.openscience.cdk.renderer.elements.ElementGroup;
+import org.openscience.cdk.renderer.elements.IRenderingElement;
+import org.openscience.cdk.renderer.elements.LineElement;
+import org.openscience.cdk.renderer.elements.OvalElement;
+import org.openscience.cdk.renderer.font.IFontManager;
+import org.openscience.cdk.renderer.visitor.IDrawVisitor;
+
+/**
+ * Utility class for testing.
+ *
+ * @author maclean
+ *
+ */
+public class ElementUtility implements IDrawVisitor {
+
+ private List<IRenderingElement> elements = new ArrayList<IRenderingElement>();
+
+ private AffineTransform transform;
+
+ private RendererModel model;
+
+ private boolean getElementGroups = false;
+
+ public int numberOfElements() {
+ return this.elements.size();
+ }
+
+ public void setTransform(AffineTransform transform) {
+ this.transform = transform;
+ }
+
+ public void visit(IRenderingElement element) {
+ if (element instanceof ElementGroup) {
+ if (getElementGroups) {
+ this.elements.add(element);
+ }
+ ((ElementGroup) element).visitChildren(this);
+ } else {
+ this.elements.add(element);
+ }
+ }
+
+ public List<IRenderingElement> getElements() {
+ return this.elements;
+ }
+
+ public List<IRenderingElement> getAllSimpleElements(IRenderingElement root) {
+ getElementGroups = false;
+ root.accept(this);
+ return elements;
+ }
+
+ public int[] transformPoint(double x, double y) {
+ double[] src = new double[] {x, y};
+ double[] dest = new double[2];
+ this.transform.transform(src, 0, dest, 0, 1);
+ return new int[] { (int) dest[0], (int) dest[1] };
+ }
+
+ public void setFontManager(IFontManager fontManager) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void setRendererModel(RendererModel rendererModel) {
+ this.model = rendererModel;
+ }
+
+ public RendererModel getModel() {
+ return this.model;
+ }
+
+ public String toString(int[] p) {
+ return String.format("(%d, %d)", p[0], p[1]);
+ }
+
+ public String toString(double x, double y) {
+ return String.format("(%+3.1f, %+3.1f)", x, y);
+ }
+
+ public String toString(double x, double y, double r) {
+ return String.format("(%+3.1f, %+3.1f, %+3.1f)", x, y, r);
+ }
+
+ public String toString(IRenderingElement element) {
+ if (element instanceof LineElement) {
+ LineElement e = (LineElement) element;
+ String p1 = toString(e.x1, e.y1);
+ String p2 = toString(e.x2, e.y2);
+ String p1T = toString(transformPoint(e.x1, e.y1));
+ String p2T = toString(transformPoint(e.x2, e.y2));
+ String lineFormat = "Line [%s, %s] -> [%s, %s]";
+ return String.format(lineFormat, p1, p2, p1T, p2T);
+ } else if (element instanceof OvalElement) {
+ OvalElement e = (OvalElement) element;
+ double r = e.radius;
+ String c = toString(e.x, e.y, r);
+ String p1 = toString(transformPoint(e.x - r, e.y - r));
+ String p2 = toString(transformPoint(e.x + r, e.y + r));
+ return String.format("Oval [%s] -> [%s, %s]", c, p1, p2);
+ } else if (element instanceof ElementGroup) {
+ return "Element Group";
+ } else {
+ return "Unknown element";
+ }
+ }
+
+ public void printToStream(IRenderingElement root, PrintStream stream) {
+ root.accept(this);
+ for (IRenderingElement element : this.elements) {
+ stream.print(toString(element));
+ }
+ }
+
+}
92 src/test/org/openscience/cdk/renderer/RendererTest.java
View
@@ -0,0 +1,92 @@
+package org.openscience.cdk.renderer;
+
+import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+import org.openscience.cdk.interfaces.IBond;
+import org.openscience.cdk.interfaces.IChemObjectBuilder;
+import org.openscience.cdk.interfaces.IMolecule;
+import org.openscience.cdk.layout.StructureDiagramGenerator;
+import org.openscience.cdk.nonotify.NoNotificationChemObjectBuilder;
+import org.openscience.cdk.renderer.Renderer;
+import org.openscience.cdk.renderer.RendererModel;
+import org.openscience.cdk.renderer.elements.IRenderingElement;
+import org.openscience.cdk.renderer.font.AWTFontManager;
+import org.openscience.cdk.renderer.generators.BasicAtomGenerator;
+import org.openscience.cdk.renderer.generators.BasicBondGenerator;
+import org.openscience.cdk.renderer.generators.IGenerator;
+import org.openscience.cdk.renderer.generators.BasicAtomGenerator.CompactAtom;
+import org.openscience.cdk.renderer.generators.BasicAtomGenerator.CompactShape;
+import org.openscience.cdk.renderer.generators.BasicAtomGenerator.KekuleStructure;
+import org.openscience.cdk.renderer.generators.BasicAtomGenerator.Shape;
+import org.openscience.cdk.renderer.generators.BasicAtomGenerator.ShowEndCarbons;
+
+/**
+ * @author maclean
+ *
+ */
+public class RendererTest {
+
+ private IChemObjectBuilder builder = NoNotificationChemObjectBuilder.getInstance();
+
+ private StructureDiagramGenerator sdg = new StructureDiagramGenerator();
+
+ public IMolecule layout(IMolecule molecule) {
+ sdg.setMolecule(molecule);
+ try {
+ sdg.generateCoordinates();
+ } catch (Exception e) {
+ System.err.println(e);
+ }
+ return sdg.getMolecule();
+ }
+
+ public IMolecule makeSquare() {
+ IMolecule square = builder.newMolecule();
+ square.addAtom(builder.newAtom("C"));
+ square.addAtom(builder.newAtom("C"));
+ square.addAtom(builder.newAtom("C"));
+ square.addAtom(builder.newAtom("C"));
+ square.addBond(0, 1, IBond.Order.SINGLE);
+ square.addBond(0, 3, IBond.Order.SINGLE);
+ square.addBond(1, 2, IBond.Order.SINGLE);
+ square.addBond(2, 3, IBond.Order.SINGLE);
+
+ return layout(square);
+ }
+
+ @Test
+ public void testSquareMolecule() {
+ IMolecule square = makeSquare();
+
+ List<IGenerator> generators = new ArrayList<IGenerator>();
+ generators.add(new BasicBondGenerator());
+ BasicAtomGenerator atomGenerator = new BasicAtomGenerator();
+ generators.add(atomGenerator);
+
+ Renderer renderer = new Renderer(generators, new AWTFontManager());
+ RendererModel model = renderer.getRenderer2DModel();
+ model.getRenderingParameter(CompactShape.class).setValue(Shape.OVAL);
+ model.getRenderingParameter(CompactAtom.class).setValue(true);
+ model.getRenderingParameter(KekuleStructure.class).setValue(true);
+ model.getRenderingParameter(ShowEndCarbons.class).setValue(true);
+
+ // nasty hacks
+// ((IGeneratorParameter<Shape>)atomGenerator.getParameters().get(4)).setValue(Shape.OVAL);
+// ((IGeneratorParameter<Boolean>)atomGenerator.getParameters().get(5)).setValue(true);
+// ((IGeneratorParameter<Boolean>)atomGenerator.getParameters().get(6)).setValue(true);
+// ((IGeneratorParameter<Boolean>)atomGenerator.getParameters().get(7)).setValue(true);
+
+ ElementUtility visitor = new ElementUtility();
+ Rectangle screen = new Rectangle(0, 0, 100, 100);
+ renderer.setup(square, screen);
+ renderer.paint(square, visitor);
+
+ for (IRenderingElement element : visitor.getElements()) {
+ System.out.println(visitor.toString(element));
+ }
+ }
+
+}
177 src/test/org/openscience/cdk/renderer/generators/AbstractGeneratorTest.java
View
@@ -0,0 +1,177 @@
+package org.openscience.cdk.renderer.generators;
+
+import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
+import java.util.List;
+
+import javax.vecmath.Point2d;
+
+import org.openscience.cdk.interfaces.IAtomContainer;
+import org.openscience.cdk.interfaces.IBond;
+import org.openscience.cdk.interfaces.IChemObjectBuilder;
+import org.openscience.cdk.nonotify.NoNotificationChemObjectBuilder;
+import org.openscience.cdk.renderer.ElementUtility;
+import org.openscience.cdk.renderer.RendererModel;
+import org.openscience.cdk.renderer.elements.IRenderingElement;
+import org.openscience.cdk.renderer.elements.LineElement;
+import org.openscience.cdk.renderer.elements.OvalElement;
+
+/**
+ * Base class for test classes that test IGenerators.
+ *
+ * @author maclean
+ *
+ */
+public abstract class AbstractGeneratorTest {
+
+ protected IChemObjectBuilder builder =
+ NoNotificationChemObjectBuilder.getInstance();
+
+ protected RendererModel model;
+
+ protected ElementUtility elementUtil;
+
+ /**
+ * Sets up the model and transform.
+ * Call from the 'Before' method in subclasses.
+ */
+ public void setup() {
+ model = new RendererModel();
+ elementUtil = new ElementUtility();
+ elementUtil.setTransform(this.getTransform());
+ }
+
+ /**
+ * Implement this in derived classes, either returning null if no custom
+ * canvas is desired, or with a Rectangle with the appropriate size.
+ *
+ * @return a Rectangle representing a custom drawing canvas
+ */
+ public abstract Rectangle getCustomCanvas();
+
+ /**
+ * Gets the default canvas for drawing on.
+ *
+ * @return a Rectangle representing the default drawing canvas
+ */
+ public Rectangle getDefaultCanvas() {
+ return new Rectangle(0, 0, 100, 100);
+ }
+
+ /**
+ * Gets the transform to be used when converting rendering elements into
+ * graphical objects.
+ *
+ * @return the affine transform based on the current canvas
+ */
+ public AffineTransform getTransform() {
+ Rectangle canvas = getCustomCanvas();
+ if (canvas == null) {
+ canvas = this.getDefaultCanvas();
+ }
+ return makeTransform(canvas);
+ }
+
+ /**
+ * Uses a rectangle canvas to work out how to translate from model space
+ * to screen space.
+ *
+ * @param canvas the rectangular canvas to draw on
+ * @return the transform needed to translate to screen space
+ */
+ public AffineTransform makeTransform(Rectangle canvas) {
+ AffineTransform transform = new AffineTransform();
+ int cX = canvas.x + canvas.width / 2;
+ int cY = canvas.y + canvas.height / 2;
+ transform.translate(cX, cY);
+ // TODO : include scale and zoom!
+ return transform;
+ }
+
+ /**
+ * A utility method to determine the length of a line element (in
+ * model space)
+ *
+ * @param line the line element to determine the length of
+ * @return a length
+ */
+ public static double length(LineElement line) {
+ return
+ AbstractGeneratorTest.distance(line.x1, line.y1, line.x2, line.y2);
+ }
+
+ public static double distance(double x1, double y1, double x2, double y2) {
+ return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
+ }
+
+ public static Point2d center(List<IRenderingElement> elements) {
+ double centerX = 0.0;
+ double centerY = 0.0;
+ double counter = 0;
+ for (IRenderingElement element : elements) {
+ if (element instanceof OvalElement) {
+ OvalElement o = (OvalElement) element;
+ centerX += o.x;
+ centerY += o.y;
+ counter++;
+ } else if (element instanceof LineElement) {
+ LineElement l = (LineElement) element;
+ centerX += l.x1;
+ centerX += l.x2;
+ centerY += l.y1;
+ centerY += l.y2;
+ counter += 2;
+ }
+ }
+ if (counter > 0) {
+ return new Point2d(centerX / counter, centerY / counter);
+ } else {
+ return new Point2d(0, 0);
+ }
+ }
+
+ /**
+ * Makes a single atom, centered on the origin.
+ *
+ * @return an atom container with a single atom
+ */
+ public IAtomContainer makeSingleAtom() {
+ IAtomContainer container = builder.newAtomContainer();
+ container.addAtom(builder.newAtom("C", new Point2d(0,0)));
+ return container;
+ }
+
+ /**
+ * Makes a single C-C bond aligned horizontally. The endpoints are (0, -1)
+ * and (0, 1) in model space.
+ *
+ * @return an atom container with a single C-C bond
+ */
+ public IAtomContainer makeSingleBond() {
+ IAtomContainer container = builder.newAtomContainer();
+ container.addAtom(builder.newAtom("C", new Point2d(0,-1)));
+ container.addAtom(builder.newAtom("C", new Point2d(0, 1)));
+ container.addBond(0, 1, IBond.Order.SINGLE);
+ return container;
+ }
+
+ /**
+ * Make a square (sort-of cyclobutane, without any hydrogens) centered on
+ * the origin, with a bond length of 2.
+ *
+ * @return four carbon atoms connected by bonds into a square
+ */
+ public IAtomContainer makeSquare() {
+ IAtomContainer container = builder.newAtomContainer();
+ container.addAtom(builder.newAtom("C", new Point2d(-1,-1)));
+ container.addAtom(builder.newAtom("C", new Point2d( 1,-1)));
+ container.addAtom(builder.newAtom("C", new Point2d( 1, 1)));
+ container.addAtom(builder.newAtom("C", new Point2d(-1, 1)));
+ container.addBond(0, 1, IBond.Order.SINGLE);
+ container.addBond(0, 3, IBond.Order.SINGLE);
+ container.addBond(1, 2, IBond.Order.SINGLE);
+ container.addBond(2, 3, IBond.Order.SINGLE);
+ return container;
+
+ }
+}
74 src/test/org/openscience/cdk/renderer/generators/BasicAtomGeneratorTest.java
View
@@ -0,0 +1,74 @@
+package org.openscience.cdk.renderer.generators;
+
+import java.awt.Rectangle;
+import java.util.List;
+
+import javax.vecmath.Point2d;
+
+import junit.framework.Assert;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.openscience.cdk.interfaces.IAtomContainer;
+import org.openscience.cdk.renderer.elements.IRenderingElement;
+import org.openscience.cdk.renderer.elements.OvalElement;
+import org.openscience.cdk.renderer.generators.BasicAtomGenerator.Shape;
+
+public class BasicAtomGeneratorTest extends AbstractGeneratorTest {
+
+ private BasicAtomGenerator generator;
+
+ @Override
+ public Rectangle getCustomCanvas() {
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Before
+ public void setup() {
+ super.setup();
+ this.generator = new BasicAtomGenerator();
+ ((IGeneratorParameter<Shape>)generator.getParameters().get(4)).setValue(Shape.OVAL);
+ ((IGeneratorParameter<Boolean>)generator.getParameters().get(5)).setValue(true);
+ ((IGeneratorParameter<Boolean>)generator.getParameters().get(6)).setValue(true);
+ ((IGeneratorParameter<Boolean>)generator.getParameters().get(7)).setValue(true);
+ }
+
+ @Test
+ public void testSingleAtom() {
+ IAtomContainer singleAtom = makeSingleAtom();
+
+ // nothing should be made
+ IRenderingElement root = generator.generate(singleAtom, model);
+ List<IRenderingElement> elements = elementUtil.getAllSimpleElements(root);
+ Assert.assertEquals(1, elements.size());
+ }
+
+ @Test
+ public void testSingleBond() {
+ IAtomContainer container = makeSingleBond();
+
+ // generate the single line element
+ IRenderingElement root = generator.generate(container, model);
+ List<IRenderingElement> elements = elementUtil.getAllSimpleElements(root);
+ Assert.assertEquals(2, elements.size());
+
+ // test that the endpoints are distinct
+ OvalElement ovalA = (OvalElement) elements.get(0);
+ OvalElement ovalB = (OvalElement) elements.get(1);
+ Assert.assertNotSame(0, distance(ovalA.x, ovalA.y, ovalB.x, ovalB.y));
+ }
+
+ @Test
+ public void testSquare() {
+ IAtomContainer square = makeSquare();
+
+ // generate all four atoms
+ IRenderingElement root = generator.generate(square, model);
+ List<IRenderingElement> elements = elementUtil.getAllSimpleElements(root);
+ Assert.assertEquals(4, elements.size());
+
+ // test that the center is at the origin
+ Assert.assertEquals(new Point2d(0,0), center(elements));
+ }
+}
75 src/test/org/openscience/cdk/renderer/generators/BasicBondGeneratorTest.java
View
@@ -0,0 +1,75 @@
+package org.openscience.cdk.renderer.generators;
+
+import java.awt.Rectangle;
+import java.util.List;
+
+import javax.vecmath.Point2d;
+
+import junit.framework.Assert;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.openscience.cdk.interfaces.IAtomContainer;
+import org.openscience.cdk.renderer.elements.IRenderingElement;
+import org.openscience.cdk.renderer.elements.LineElement;
+import org.openscience.cdk.renderer.generators.BasicBondGenerator;
+
+/**
+ * Test the BasicBondGenerator.
+ *
+ * @author maclean
+ *
+ */
+public class BasicBondGeneratorTest extends AbstractGeneratorTest {
+
+ private BasicBondGenerator generator;
+
+ @Override
+ public Rectangle getCustomCanvas() {
+ return null;
+ }
+
+ @Before
+ public void setup() {
+ super.setup();
+ this.generator = new BasicBondGenerator();
+ }
+
+ @Test
+ public void testSingleAtom() {
+ IAtomContainer singleAtom = makeSingleAtom();
+
+ // nothing should be made
+ IRenderingElement root = generator.generate(singleAtom, model);
+ List<IRenderingElement> elements = elementUtil.getAllSimpleElements(root);
+ Assert.assertEquals(0, elements.size());
+ }
+
+ @Test
+ public void testSingleBond() {
+ IAtomContainer container = makeSingleBond();
+
+ // generate the single line element
+ IRenderingElement root = generator.generate(container, model);
+ List<IRenderingElement> elements = elementUtil.getAllSimpleElements(root);
+ Assert.assertEquals(1, elements.size());
+
+ // test that the endpoints are distinct
+ LineElement line = (LineElement) elements.get(0);
+ Assert.assertNotSame(0, AbstractGeneratorTest.length(line));
+ }
+
+ @Test
+ public void testSquare() {
+ IAtomContainer square = makeSquare();
+
+ // generate all four bonds
+ IRenderingElement root = generator.generate(square, model);
+ List<IRenderingElement> elements = elementUtil.getAllSimpleElements(root);
+ Assert.assertEquals(4, elements.size());
+
+ // test that the center is at the origin
+ Assert.assertEquals(new Point2d(0,0), center(elements));
+ }
+
+}
Please sign in to comment.
Something went wrong with that request. Please try again.