package test.beast.app.beauti; import static org.fest.assertions.Assertions.assertThat; import static org.fest.swing.edt.GuiActionRunner.execute; import static org.fest.swing.finder.JFileChooserFinder.findFileChooser; import java.awt.Dimension; import java.awt.FileDialog; import java.awt.event.KeyEvent; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import javax.swing.JFrame; import org.fest.swing.annotation.RunsInEDT; import org.fest.swing.edt.GuiQuery; import org.fest.swing.edt.GuiTask; import org.fest.swing.fixture.FrameFixture; import org.fest.swing.fixture.JFileChooserFixture; import org.fest.swing.fixture.JTabbedPaneFixture; import org.fest.swing.fixture.JTableFixture; import org.fest.swing.junit.testcase.FestSwingJUnitTestCase; import beast.app.beauti.Beauti; import beast.app.beauti.BeautiDoc; import beast.app.util.Utils; import beast.core.BEASTInterface; import beast.core.BEASTObject; import beast.core.Distribution; import beast.core.Function; import beast.core.Logger; import beast.core.MCMC; import beast.core.Operator; import beast.core.State; import beast.core.StateNode; import beast.core.parameter.Parameter; import beast.core.util.CompoundDistribution; import beast.math.distributions.Prior; import beast.util.XMLParser; /** * Basic test methods for Beauti * */ public class BeautiBase extends FestSwingJUnitTestCase { protected FrameFixture beautiFrame; protected Beauti beauti; protected BeautiDoc doc; @Override protected void onSetUp() { beautiFrame = new FrameFixture(robot(), createNewEditor()); beautiFrame.show(); beautiFrame.resizeTo(new Dimension(1224, 786)); JTabbedPaneFixture f = beautiFrame.tabbedPane(); beauti = (Beauti) f.target; doc = beauti.doc; } @RunsInEDT private static JFrame createNewEditor() { return execute(new GuiQuery<JFrame>() { @Override protected JFrame executeInEDT() throws Throwable { Beauti beauti = Beauti.main2(new String[] {}); return beauti.frame; } }); } String priorsAsString() { CompoundDistribution prior = (CompoundDistribution) doc.pluginmap.get("prior"); List<Distribution> priors = prior.pDistributions.get(); return "assertPriorsEqual" + pluginListAsString(priors); } String stateAsString() { State state = (State) doc.pluginmap.get("state"); List<StateNode> stateNodes = state.stateNodeInput.get(); return "assertStateEquals" + pluginListAsString(stateNodes); } String operatorsAsString() { MCMC mcmc = (MCMC) doc.mcmc.get(); List<Operator> operators = mcmc.operatorsInput.get(); return "assertOperatorsEqual" + pluginListAsString(operators); } String traceLogAsString() { Logger logger = (Logger) doc.pluginmap.get("tracelog"); List<BEASTObject> logs = logger.loggersInput.get(); return "assertTraceLogEqual" + pluginListAsString(logs); } private String pluginListAsString(List<?> list) { if (list.size() == 0) { return ""; } StringBuffer bf = new StringBuffer(); for (Object o : list) { BEASTObject beastObject = (BEASTObject) o; bf.append('"'); bf.append(beastObject.getID()); bf.append("\", "); } String str = bf.toString(); return "(" + str.substring(0, str.length()-2) + ");"; } void assertPriorsEqual(String... ids) { System.err.println("assertPriorsEqual"); CompoundDistribution prior = (CompoundDistribution) doc.pluginmap.get("prior"); List<Distribution> priors = prior.pDistributions.get(); for (String id : ids) { boolean found = false; for (BEASTObject node : priors) { if (node.getID().equals(id)) { found = true; } } assertThat(found).as("Could not find beastObject with ID " + id).isEqualTo(true); } List<String> extras = new ArrayList<>(); for (BEASTObject node : priors) { boolean found = false; for (String id : ids) { if (node.getID().equals(id)) { found = true; } } if (!found) { extras.add(node.getID()); } } if (extras.size() != 0) { System.err.println("Extra ids found: " + Arrays.toString(extras.toArray(new String[]{}))); } assertThat(ids.length).as("list of beastObjects do not match").isEqualTo(priors.size());; } private void asserListsEqual(List<?> list, String[] ids) { // check all ids are in list for (String id : ids) { boolean found = false; for (Object o: list) { BEASTObject node = (BEASTObject) o; if (node.getID().equals(id)) { found = true; break; } } assertThat(found).as("Could not find beastObject with ID " + id).isEqualTo(true); } // check all items in list have a unique ie Set<String> idsInList = new HashSet<String>(); Set<String> duplicates = new HashSet<String>(); for (Object o : list) { String id = ((BEASTObject) o).getID(); if (idsInList.contains(id)) { duplicates.add(id); } else { idsInList.add(id); } } assertThat(duplicates.size()).as("Duplicate ids found: " + Arrays.toString(duplicates.toArray())).isEqualTo(0); if (list.size() != ids.length) { // list.size > ids.length, otherwise it would have been picked up above List<String> extraIDs = new ArrayList<String>(); for (Object o : list) { String id = ((BEASTObject) o).getID(); boolean found = false; for (String id2 : ids) { if (id2.equals(id)) { found = true; break; } } if (!found) { extraIDs.add(id); } } assertThat(ids.length).as("list of beastObjects do not match: found extra items " + Arrays.toString(extraIDs.toArray())).isEqualTo(list.size()); } } void assertStateEquals(String... ids) { System.err.println("assertStateEquals"); State state = (State) doc.pluginmap.get("state"); List<StateNode> stateNodes = state.stateNodeInput.get(); asserListsEqual(stateNodes, ids); } void assertOperatorsEqual(String... ids) { System.err.println("assertOperatorsEqual"); MCMC mcmc = (MCMC) doc.mcmc.get(); List<Operator> operators = mcmc.operatorsInput.get(); asserListsEqual(operators, ids); } void assertTraceLogEqual(String... ids) { System.err.println("assertTraceLogEqual"); Logger logger = (Logger) doc.pluginmap.get("tracelog"); List<BEASTObject> logs = logger.loggersInput.get(); asserListsEqual(logs, ids); } void assertArrayEquals(Object [] o, String array) { String str = array.substring(1, array.length() - 1); String [] strs = str.split(", "); for (int i = 0; i < o.length && i < strs.length; i++) { assertThat(strs[i]).as("expected array value " + strs[i] + " instead of " + o[i].toString()).isEqualTo(o[i].toString()); } assertThat(o.length).as("arrays do not match: different lengths").isEqualTo(strs.length); } void assertParameterCountInPriorIs(int i) { // count nr of parameters in Prior objects in prior // including those for prior distributions (Normal, etc) // useful to make sure they do (or do not) get linked Set<Function> parameters = new LinkedHashSet<>(); CompoundDistribution prior = (CompoundDistribution) doc.pluginmap.get("prior"); for (Distribution p : prior.pDistributions.get()) { if (p instanceof Prior) { Prior p2 = (Prior) p; parameters.add(p2.m_x.get()); for (BEASTInterface o : p2.distInput.get().listActiveBEASTObjects()) { if (o instanceof Parameter) { parameters.add((Parameter<?>) o); } } } } System.err.println("Number of parameters in prior = " + parameters.size()); if (i >= 0) { assertThat(parameters.size()).as("Expected " + i + " parameters in prior").isEqualTo(i); } } void printBeautiState(JTabbedPaneFixture f) throws InterruptedException { doc.scrubAll(true, false); //f.selectTab("MCMC"); System.err.println(stateAsString()); System.err.println(operatorsAsString()); System.err.println(priorsAsString()); System.err.println(traceLogAsString()); } void printTableContents(JTableFixture t) { String [][] contents = t.contents(); for (int i = 0; i < contents.length; i++) { System.err.print("\"" + Arrays.toString(contents[i])); if (i < contents.length - 1) { System.err.print("*\" +"); } else { System.err.print("\""); } System.err.println(); } } void checkTableContents(JTableFixture t, String str) { String [][] contents = t.contents(); String [] strs = str.split("\\*"); assertThat(contents.length).as("tables do not match: different #rows").isEqualTo(strs.length); for (int i = 0; i < contents.length; i++) { assertArrayEquals(contents[i], strs[i]); } } void warning(String str) { System.err.println("\n\n=====================================================\n"); System.err.println(str); System.err.println("\n=====================================================\n\n"); } void makeSureXMLParses() { warning("Make sure that XML that BEAUti produces parses"); File XMLFile = new File(org.fest.util.Files.temporaryFolder() + "/x.xml"); if (XMLFile.exists()) { XMLFile.delete(); } saveFile(""+org.fest.util.Files.temporaryFolder(), "x.xml"); // JFileChooserFixture fileChooser = findFileChooser().using(robot()); // fileChooser.setCurrentDirectory(org.fest.util.Files.temporaryFolder()); // fileChooser.selectFile(new File("x.xml")).approve(); XMLParser parser = new XMLParser(); XMLFile = new File(org.fest.util.Files.temporaryFolder() + "/x.xml"); try { parser.parseFile(XMLFile); } catch (Exception e) { e.printStackTrace(); assertThat(0).as("Parser exception: " + e.getMessage()).isEqualTo(1); } } protected void saveFile(String dir, String file) { if (!Utils.isMac()) { beautiFrame.menuItemWithPath("File", "Save As").click(); JFileChooserFixture fileChooser = findFileChooser().using(robot()); fileChooser.setCurrentDirectory(new File(dir)); fileChooser.selectFile(new File(file)).approve(); } else { _file = new File(dir + "/" + file); execute(new GuiTask() { @Override protected void executeInEDT() { try { beauti.doc.save(_file); } catch (Exception e) { e.printStackTrace(); } } }); } } // for handling file open events on Mac FileDialog fileDlg = null; String _dir; File _file; void importAlignment(String dir, File ... files) { if (!Utils.isMac()) { beautiFrame.menuItemWithPath("File", "Import Alignment").click(); JFileChooserFixture fileChooser = findFileChooser().using(robot()); fileChooser.setCurrentDirectory(new File(dir)); fileChooser.selectFiles(files).approve(); // close down any popup message robot().pressKey(KeyEvent.VK_ESCAPE); } else { this._dir = dir; for (File file : files) { _file = new File(dir + "/" + file.getName()); execute(new GuiTask() { @Override protected void executeInEDT() { try { beauti.doc.importNexus(_file); beauti.refreshPanel(); } catch (Exception e) { e.printStackTrace(); } } }); } } } // void openFile(String dir, String file) { // if (!Utils.isMac() && false) { // JFileChooserFixture fileChooser = findFileChooser().using(robot()); // fileChooser.setCurrentDirectory(new File(dir)); // fileChooser.selectFile(new File(file)).approve(); // } else { // fileDlg = null; // this._dir = dir; // this._file = file; // DialogFixture dialog = WindowFinder.findDialog(FileDialog.class).using(robot()); // fileDlg = (FileDialog) dialog.target; // // execute(new GuiTask() { // protected void executeInEDT() { // fileDlg.setDirectory(_dir); // fileDlg.setFile(_file); // } // }); // robot().click( // robot().finder().find(new ComponentMatcher() { // @Override // public boolean matches(Component c) { // if (c.getName() == null) { // return false; // } // System.err.println(c.getName()); // if (c instanceof Button) { // System.err.println(">>>" + ((Button)c).getLabel()); // } // return (c.getName().equals("button0") || c.getName().equals("button3")); // } // }) // ); // } // } }