1/* 2 [The "BSD licence"] 3 Copyright (c) 2009 Shaoting Cai 4 All rights reserved. 5 6 Redistribution and use in source and binary forms, with or without 7 modification, are permitted provided that the following conditions 8 are met: 9 1. Redistributions of source code must retain the above copyright 10 notice, this list of conditions and the following disclaimer. 11 2. Redistributions in binary form must reproduce the above copyright 12 notice, this list of conditions and the following disclaimer in the 13 documentation and/or other materials provided with the distribution. 14 3. The name of the author may not be used to endorse or promote products 15 derived from this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27*/ 28 29package org.antlr.gunit.swingui; 30 31import java.awt.BorderLayout; 32import java.awt.Color; 33import java.awt.Component; 34import java.awt.Dimension; 35import javax.swing.BorderFactory; 36import javax.swing.BoxLayout; 37import javax.swing.JLabel; 38import javax.swing.JLabel; 39import javax.swing.JPanel; 40import javax.swing.JScrollPane; 41import javax.swing.JTextArea; 42import javax.swing.JTree; 43import javax.swing.event.TreeModelListener; 44import javax.swing.tree.DefaultMutableTreeNode; 45import javax.swing.tree.DefaultTreeModel; 46import javax.swing.tree.TreeCellRenderer; 47import javax.swing.tree.TreeModel; 48import javax.swing.tree.TreePath; 49import org.antlr.gunit.swingui.ImageFactory; 50import org.antlr.gunit.swingui.model.*; 51 52/** 53 * 54 * @author scai 55 */ 56public class RunnerController implements IController { 57 58 /* MODEL */ 59 //private TestSuite testSuite; 60 61 /* VIEW */ 62 private RunnerView view = new RunnerView(); 63 public class RunnerView extends JPanel { 64 65 private JTextArea textArea = new JTextArea(); 66 67 private JTree tree = new JTree(); 68 69 private JScrollPane scroll = new JScrollPane(tree, 70 JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, 71 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 72 73 public void initComponents() { 74 //textArea.setOpaque(false); 75 tree.setOpaque(false); 76 scroll.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY)); 77 scroll.setOpaque(false); 78 this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 79 this.add(scroll); 80 this.setBorder(BorderFactory.createEmptyBorder()); 81 this.setOpaque(false); 82 } 83 84 }; 85 86 public RunnerController() { 87 } 88 89 public Object getModel() { 90 return null; 91 } 92 93 public Component getView() { 94 return view; 95 } 96 97 public void update() { 98 view.initComponents(); 99 } 100 101 public void OnShowSuiteResult(TestSuite suite) { 102 update(); 103 view.tree.setModel(new RunnerTreeModel(suite)); 104 view.tree.setCellRenderer(new RunnerTreeRenderer()); 105 } 106 107 public void OnShowRuleResult(Rule rule) { 108 update(); 109 110 111 112 /* 113 StringBuffer result = new StringBuffer(); 114 115 result.append("Testing result for rule: " + rule.getName()); 116 result.append("\n--------------------\n\n"); 117 118 for(TestCase testCase: rule.getTestCases()){ 119 result.append(testCase.isPass() ? "PASS" : "FAIL"); 120 result.append("\n"); 121 } 122 result.append("\n--------------------\n"); 123 view.textArea.setText(result.toString()); 124 */ 125 } 126 127 128 129 private class TestSuiteTreeNode extends DefaultMutableTreeNode { 130 131 private TestSuite data ; 132 133 public TestSuiteTreeNode(TestSuite suite) { 134 super(suite.getGrammarName()); 135 for(int i=0; i<suite.getRuleCount(); ++i) { 136 final Rule rule = suite.getRule(i); 137 if(rule.getNotEmpty()) this.add(new TestGroupTreeNode(rule)); 138 } 139 data = suite; 140 } 141 142 @Override 143 public String toString() { 144 return String.format("%s (%d test groups)", 145 data.getGrammarName(), 146 this.getChildCount()); 147 } 148 149 } ; 150 151 private class TestGroupTreeNode extends DefaultMutableTreeNode { 152 153 private Rule data; 154 private boolean hasFail = false; 155 156 private TestGroupTreeNode(Rule rule) { 157 super(rule.getName()); 158 for(TestCase tc: rule.getTestCases()) { 159 this.add(new TestCaseTreeNode(tc)); 160 } 161 162 data = rule; 163 } 164 165 @Override 166 public String toString() { 167 int iPass = 0; 168 int iFail = 0; 169 for(TestCase tc: data.getTestCases()) { 170 if(tc.isPass()) 171 ++iPass; 172 else 173 ++iFail; 174 } 175 176 hasFail = iFail > 0; 177 178 return String.format("%s (pass %d, fail %d)", 179 data.getName(), iPass, iFail); 180 } 181 } ; 182 183 private class TestCaseTreeNode extends DefaultMutableTreeNode { 184 185 private TestCase data; 186 187 private TestCaseTreeNode(TestCase tc) { 188 super(tc.toString()); 189 data = tc; 190 } 191 } ; 192 193 private class RunnerTreeModel extends DefaultTreeModel { 194 195 public RunnerTreeModel(TestSuite testSuite) { 196 super(new TestSuiteTreeNode(testSuite)); 197 } 198 } 199 200 private class RunnerTreeRenderer implements TreeCellRenderer { 201 202 public Component getTreeCellRendererComponent(JTree tree, Object value, 203 boolean selected, boolean expanded, boolean leaf, int row, 204 boolean hasFocus) { 205 206 JLabel label = new JLabel(); 207 208 if(value instanceof TestSuiteTreeNode) { 209 210 label.setText(value.toString()); 211 label.setIcon(ImageFactory.getSingleton().TESTSUITE); 212 213 } else if(value instanceof TestGroupTreeNode) { 214 215 TestGroupTreeNode node = (TestGroupTreeNode) value; 216 label.setText(value.toString()); 217 label.setIcon( node.hasFail ? 218 ImageFactory.getSingleton().TESTGROUPX : 219 ImageFactory.getSingleton().TESTGROUP); 220 221 } else if(value instanceof TestCaseTreeNode) { 222 223 TestCaseTreeNode node = (TestCaseTreeNode) value; 224 label.setIcon( (node.data.isPass())? 225 ImageFactory.getSingleton().RUN_PASS : 226 ImageFactory.getSingleton().RUN_FAIL); 227 label.setText(value.toString()); 228 229 } else { 230 throw new IllegalArgumentException( 231 "Invalide tree node type + " + value.getClass().getName()); 232 } 233 234 return label; 235 236 } 237 238 } 239 240} 241