// PathVisio, // a tool for data visualization and analysis using Biological Pathways // Copyright 2006-2011 BiGCaT Bioinformatics // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // package org.pathvisio.core.model; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Set; import junit.framework.TestCase; import org.bridgedb.Xref; import org.bridgedb.bio.BioDataSource; import org.pathvisio.core.data.XrefWithSymbol; import org.pathvisio.core.preferences.PreferenceManager; import org.pathvisio.core.util.Utils; public class Test extends TestCase implements PathwayListener, PathwayElementListener { Pathway data; PathwayElement o; List received; List receivedElementEvents; PathwayElement l; private static final File PATHVISIO_BASEDIR = new File ("../.."); public void setUp() { PreferenceManager.init(); data = new Pathway(); data.addListener(this); o = PathwayElement.createPathwayElement(ObjectType.DATANODE); received = new ArrayList(); receivedElementEvents = new ArrayList(); o.addListener(this); data.add (o); l = PathwayElement.createPathwayElement(ObjectType.LINE); data.add(l); received.clear(); receivedElementEvents.clear(); } public void testFields () { o.setMCenterX(1.0); assertEquals ("test set/get CenterX", 1.0, o.getMCenterX(), 0.0001); assertEquals ("Setting CenterX should generate single event", receivedElementEvents.size(), 1); assertEquals ("test getProperty()", 1.0, (Double)o.getStaticProperty(StaticProperty.CENTERX), 0.0001); try { o.setStaticProperty(StaticProperty.CENTERX, null); fail("Setting centerx property to null should generate exception"); } catch (Exception e) {} // however, you should be able to set graphRef to null assertNull ("graphref null by default", l.getStartGraphRef()); l.setStartGraphRef(null); assertNull ("can set graphRef to null", l.getStartGraphRef()); } public void testProperties() throws IOException, ConverterException { // set 10 dynamic properties in two ways for (int i = 0; i < 5; ++i) { o.setDynamicProperty("Hello" + i, "World" + i); } for (int i = 5; i < 10; ++i) { o.setPropertyEx("Hello" + i, "World" + i); } // check contents of dynamic properties assertEquals("World0", o.getDynamicProperty("Hello0")); for (int i = 0; i < 10; ++i) { assertEquals("World" + i, o.getDynamicProperty("Hello" + i)); } // check non-existing dynamic property assertNull (o.getDynamicProperty("NonExistingProperty")); // check that we have 10 dynamic properties, no more, no less. Set dynamicKeys = o.getDynamicPropertyKeys(); assertEquals (10, dynamicKeys.size()); // check that superset dynamic + static also contains dynamic properties assertEquals("World0", o.getPropertyEx("Hello0")); for (int i = 0; i < 10; ++i) { assertEquals("World" + i, o.getPropertyEx("Hello" + i)); } // check setting null property try { o.setStaticProperty(null, new Object()); fail("Setting null property should generate exception"); } catch (NullPointerException e) {} // check setting non string / StaticProperty property try { o.setPropertyEx(new Object(), new Object()); fail("Using key that is not String or StaticProperty should generate exception"); } catch (IllegalArgumentException e) {} // test storage of dynamic properties File temp = File.createTempFile ("dynaprops.test", ".gpml"); temp.deleteOnExit(); // set an id on this element so we can find it back easily String id = o.setGeneratedGraphId(); // store data.writeToXml(temp, false); // and read back Pathway p2 = new Pathway(); p2.readFromXml(temp, true); // get same datanode back PathwayElement o2 = p2.getElementById(id); // check that it still has the dynamic properties after storing / reading assertEquals ("World5", o2.getDynamicProperty("Hello5")); assertEquals ("World3", o2.getPropertyEx("Hello3")); // sanity check: no non-existing properties assertNull (o2.getDynamicProperty("NonExistingProperty")); assertNull (o2.getPropertyEx("NonExistingProperty")); // check that dynamic properties are copied. PathwayElement o3 = o2.copy(); assertEquals ("World7", o3.getPropertyEx("Hello7")); // check that it's a deep copy o2.setDynamicProperty("Hello7", "Something other than 'World7'"); assertEquals ("World7", o3.getPropertyEx("Hello7")); assertEquals ("Something other than 'World7'", o2.getPropertyEx("Hello7")); } public void testColor() { try { o.setColor(null); fail("Shouldn't be able to set color null"); } catch (Exception e) {} } public void testObjectType() { assertEquals ("getObjectType() test", o.getObjectType(), ObjectType.DATANODE); assertEquals (ObjectType.SHAPE, ObjectType.getTagMapping("Shape")); assertNull (ObjectType.getTagMapping("Non-existing tag")); try { PathwayElement.createPathwayElement (null); fail ("Shouldn't be able to create invalid object type"); } catch (NullPointerException e) { } } public void testParent() { // remove data.remove (o); assertNull ("removing object set parents null", o.getParent()); assertEquals (received.size(), 1); assertEquals ("Event type should be DELETED", received.get(0).getType(), PathwayEvent.DELETED); // re-add data.add(o); assertEquals ("adding sets parent", o.getParent(), data); assertEquals (received.size(), 2); assertEquals ("Event type should be ADDED", received.get(1).getType(), PathwayEvent.ADDED); } /** * Test graphRef's and graphId's * */ public void testRef() { assertTrue ("query non-existing list of ref", data.getReferringObjects("abcde").size() == 0); // create link o.setGraphId("1"); l.setStartGraphRef("1"); assertTrue ("reference created", data.getReferringObjects("1").contains(l.getMStart())); l.setStartGraphRef("2"); assertTrue ("reference removed", data.getReferringObjects("1").size() == 0); PathwayElement o2 = PathwayElement.createPathwayElement(ObjectType.DATANODE); data.add (o2); // create link in opposite order o.setGraphId("2"); l.setEndGraphRef("2"); assertTrue ("reference created (2)", data.getReferringObjects("2").contains(l.getMEnd())); } /** * test that Xref and XrefWithSymbol obey the equals contract */ public void testXRefEquals() { Object[] testList = new Object[] { new Xref("1007_at", BioDataSource.AFFY), new Xref("3456", BioDataSource.AFFY), new Xref("1007_at", BioDataSource.ENTREZ_GENE), new Xref ("3456", BioDataSource.ENTREZ_GENE), new Xref ("3456", BioDataSource.ENTREZ_GENE), new XrefWithSymbol("3456", BioDataSource.ENTREZ_GENE, "INSR"), new XrefWithSymbol("3456", BioDataSource.ENTREZ_GENE, "Insulin Receptor"), }; for (int i = 0; i < testList.length; ++i) { Object refi = testList[i]; // equals must be reflexive assertTrue (refi.equals(refi)); // never equal to null assertFalse (refi.equals(null)); } for (int i = 1; i < testList.length; ++i) for (int j = 0; j < i; ++j) { // equals must be symmetric Object refi = testList[i]; Object refj = testList[j]; assertEquals ("Symmetry fails for " + refj + " and " + refi, refi.equals(refj), refj.equals(refi) ); // hashcode contract if (refi.equals(refj)) { assertEquals (refi.hashCode(), refj.hashCode()); } } // equals must be transitive for (int i = 2; i < testList.length; ++i) for (int j = 1; j < i; ++j) for (int k = 0; k < j; ++k) { Object refi = testList[i]; Object refj = testList[j]; Object refk = testList[k]; if (refi.equals (refj) && refj.equals (refk)) { assertTrue (refk.equals (refi)); } if (refj.equals (refk) && refk.equals (refi)) { assertTrue (refi.equals (refj)); } if (refk.equals (refi) && refi.equals (refj)) { assertTrue (refk.equals (refj)); } } } /** * Test for maintaining list of unique id's per Pathway. * */ public void testRefUniq() { String src = "123123"; String s1 = src.substring (3, 6); String s2 = src.substring (0, 3); assertFalse ("s1 should not be the same reference as s2", s1 == s2); assertTrue ("s1 should be equal to s2", s1.equals (s2)); // test for uniqueness o.setGraphId(s1); PathwayElement o2 = PathwayElement.createPathwayElement(ObjectType.DATANODE); data.add (o2); assertSame (o.getParent(), o2.getParent()); assertEquals ("Setting graphId on first element", o.getGraphId(), "123"); try { o2.setGraphId(s2); // try setting the same id again fail("shouldn't be able to set the same id twice"); } catch (IllegalArgumentException e) { } // test random id String x = data.getUniqueGraphId(); try { // test that we can use it as unique id o.setGraphId(x); assertEquals (x, o.getGraphId()); // test that we can't use the same id twice o2.setGraphId(x); fail("shouldn't be able to set the same id twice"); } catch (IllegalArgumentException e) {} // test that a second random id is unique again x = data.getUniqueGraphId(); o2.setGraphId(x); assertEquals (x, o2.getGraphId()); // test setting id first, then parent PathwayElement o3 = PathwayElement.createPathwayElement(ObjectType.DATANODE); x = data.getUniqueGraphId(); o3.setGraphId(x); data.add (o3); assertEquals (o3.getGraphId(), x); try { PathwayElement o4 = PathwayElement.createPathwayElement(ObjectType.DATANODE); // try setting the same id again o4.setGraphId(x); data.add (o4); fail("shouldn't be able to set the same id twice"); } catch (IllegalArgumentException e) {} } public void testRef2() { o.setGraphId("1"); PathwayElement o2 = PathwayElement.createPathwayElement(ObjectType.DATANODE); // note: parent not set yet! o2.setGraphId ("3"); data.add(o2); // reference should now be created assertNull ("default endGraphRef is null", l.getEndGraphRef()); l.setEndGraphRef("3"); assertTrue ("reference created through adding", data.getReferringObjects("3").contains(l.getMEnd())); } public void testXml2007() throws IOException, ConverterException { File testFile = new File (PATHVISIO_BASEDIR, "testData/test.gpml"); assertTrue (testFile.exists()); data.readFromXml(testFile, false); assertTrue ("Loaded a bunch of objects from xml", data.getDataObjects().size() > 20); File temp = File.createTempFile ("data.test", ".gpml"); temp.deleteOnExit(); data.writeToXml(temp, false); } public void testWrongFormat() { try { data.readFromXml(new File (PATHVISIO_BASEDIR, "testData/test.mapp"), false); fail ("Loading wrong format, Exception expected"); } catch (Exception e) {} } public void testXml2008a() throws IOException, ConverterException { File testFile = new File (PATHVISIO_BASEDIR, "testData/test2.gpml"); assertTrue (testFile.exists()); data.readFromXml(testFile, false); assertTrue ("Loaded a bunch of objects from xml", data.getDataObjects().size() > 20); File temp = File.createTempFile ("data.test", ".gpml"); temp.deleteOnExit(); data.writeToXml(temp, false); } // bug 440: valid gpml file is rejected // because it doesn't contain Pathway.Graphics public void testBug440() throws ConverterException { try { data.readFromXml(new File(PATHVISIO_BASEDIR, "testData/nographics-test.gpml"), false); } catch (ConverterException e) { fail ("No converter exception expected"); } } /** * test exporting of .mapp (genmapp format) * Note: this test is only run whenever os.name starts with Windows */ public void testMapp() throws IOException, ConverterException { if (Utils.getOS() == Utils.OS_WINDOWS) { data = new MappFormat().doImport(new File(PATHVISIO_BASEDIR, "testData/test.mapp")); assertTrue ("Loaded a bunch of objects from mapp", data.getDataObjects().size() > 20); File temp = File.createTempFile ("data.test", ".mapp"); temp.deleteOnExit(); data.writeToMapp(temp); try { data = new MappFormat().doImport(new File (PATHVISIO_BASEDIR, "testData/test.gpml")); fail ("Loading wrong format, Exception expected"); } catch (Exception e) {} } } /** * test exporting of .svg */ public void testSvg() throws IOException, ConverterException { data.readFromXml(new File(PATHVISIO_BASEDIR, "testData/test.gpml"), false); assertTrue ("Loaded a bunch of objects from xml", data.getDataObjects().size() > 20); File temp = File.createTempFile ("data.test", ".svg"); temp.deleteOnExit(); data.writeToSvg(temp); } /** * test exporting of .png */ public void testPng() throws IOException, ConverterException { data.readFromXml(new File(PATHVISIO_BASEDIR, "testData/test.gpml"), false); assertTrue ("Loaded a bunch of objects from xml", data.getDataObjects().size() > 20); File temp = File.createTempFile ("data.test", ".png"); temp.deleteOnExit(); BatikImageExporter exporter = new BatikImageExporter(BatikImageExporter.TYPE_PNG); exporter.doExport(temp, data); } /** * test exporting of .png */ public void testPng2() throws IOException, ConverterException { data.readFromXml(new File(PATHVISIO_BASEDIR, "testData/test.gpml"), false); assertTrue ("Loaded a bunch of objects from xml", data.getDataObjects().size() > 20); File temp = File.createTempFile ("data.test", ".png"); temp.deleteOnExit(); RasterImageExporter exporter = new RasterImageExporter(BatikImageExporter.TYPE_PNG); exporter.doExport(temp, data); } /** * test exporting of .pdf */ public void testPdf() throws IOException, ConverterException { data.readFromXml(new File(PATHVISIO_BASEDIR, "testData/test.gpml"), false); assertTrue ("Loaded a bunch of objects from xml", data.getDataObjects().size() > 20); File temp = File.createTempFile ("data.test", ".pdf"); temp.deleteOnExit(); BatikImageExporter exporter = new BatikImageExporter(BatikImageExporter.TYPE_PDF); exporter.doExport(temp, data); } /** * test exporting of .txt */ public void testTxt() throws IOException, ConverterException { data.readFromXml(new File(PATHVISIO_BASEDIR, "testData/test.gpml"), false); assertTrue ("Loaded a bunch of objects from xml", data.getDataObjects().size() > 20); File temp = File.createTempFile ("data.test", ".txt"); temp.deleteOnExit(); DataNodeListExporter exporter = new DataNodeListExporter(); exporter.doExport(temp, data); } /** * test exporting of .pwf */ public void testPwf() throws IOException, ConverterException { data.readFromXml(new File(PATHVISIO_BASEDIR, "testData/test.gpml"), false); assertTrue ("Loaded a bunch of objects from xml", data.getDataObjects().size() > 20); File temp = File.createTempFile ("data.test", ".pwf"); temp.deleteOnExit(); EUGeneExporter exporter = new EUGeneExporter(); exporter.doExport(temp, data); } /** * Test that there is one and only one MAPPINFO object * */ public void testMappInfo() { PathwayElement mi; mi = data.getMappInfo(); assertEquals (mi.getObjectType(), ObjectType.MAPPINFO); assertTrue (data.getDataObjects().contains(mi)); assertNotNull (mi); // test that adding a new mappinfo object replaces the old one. PathwayElement mi2 = PathwayElement.createPathwayElement(ObjectType.MAPPINFO); data.add (mi2); assertSame ("MappInfo should be replaced", data.getMappInfo(), mi2); assertNotSame ("Old MappInfo should be gone", data.getMappInfo(), mi); assertNull ("Old MappInfo should not have a parent anymore", mi.getParent()); assertSame ("New MappInfo should now have a parent", mi2.getParent(), data); mi = data.getMappInfo(); try { data.remove(mi); fail ("Shouldn't be able to remove mappinfo object!"); } catch (IllegalArgumentException e) {} } /** * Test that there is one and only one MAPPINFO object * */ public void testInfoBox() { PathwayElement ib; ib = data.getInfoBox(); assertTrue (data.getDataObjects().contains(ib)); assertNotNull (ib); assertEquals (ib.getObjectType(), ObjectType.INFOBOX); PathwayElement ib2 = PathwayElement.createPathwayElement(ObjectType.INFOBOX); data.add (ib2); assertSame ("Infobox should be replaced", data.getInfoBox(), ib2); assertNotSame ("Old Infobox should be gone", data.getInfoBox(), ib); assertNull ("Old Infobox should not have a parent anymore", ib.getParent()); assertSame ("New Infobox should now have a parent", ib2.getParent(), data); ib = data.getMappInfo(); try { data.remove(ib); fail ("Shouldn't be able to remove mappinfo object!"); } catch (IllegalArgumentException e) {} } public void testValidator() throws IOException { File tmp = File.createTempFile("test", ".gpml"); o.setMCenterX(50.0); o.setMCenterY(50.0); o.setInitialSize(); o.setGraphId(data.getUniqueGraphId()); PathwayElement o2 = PathwayElement.createPathwayElement (ObjectType.LINE); o2.setMStartX(10.0); o2.setMStartY(10.0); o2.setInitialSize(); data.add(o2); PathwayElement o3 = PathwayElement.createPathwayElement (ObjectType.LABEL); o3.setMCenterX(100.0); o3.setMCenterY(50); o3.setGraphId(data.getUniqueGraphId()); data.add(o3); PathwayElement mi; mi = data.getMappInfo(); assertTrue ("Mi shouldn't be null", mi != null); try { data.writeToXml(tmp, false); } catch (ConverterException e) { e.printStackTrace(); fail ("Exception while writing newly created pathway"); } } // event listener // receives events generated on objects o and data public void gmmlObjectModified(PathwayEvent e) { // store all received events received.add(e); } public void gmmlObjectModified(PathwayElementEvent e) { receivedElementEvents.add(e); } public void pathwayModified(PathwayEvent e) { gmmlObjectModified (e); } /** * Dangling references, pointing to nothing, can occur in theory. * These should be removed. */ public void testDanglingRef() throws IOException, ConverterException { // create a dangling ref assertEquals (data.fixReferences(), 0); l.setStartGraphRef("dangle"); File temp = File.createTempFile ("data.test", ".gpml"); temp.deleteOnExit(); assertEquals (data.fixReferences(), 1); assertEquals (data.fixReferences(), 0); // should still validate try { data.writeToXml(temp, true); } catch (ConverterException e) { e.printStackTrace(); fail ("Dangling reference should have been removed"); } } }