package org.apache.felix.ipojo.junit4osgi.command; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. */ import junit.framework.AssertionFailedError; import junit.framework.Test; import junit.framework.TestResult; import org.apache.felix.ipojo.InstanceManager; import org.apache.felix.ipojo.junit4osgi.OSGiJunitRunner; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; import org.osgi.framework.BundleListener; import javax.swing.*; import javax.swing.table.TableColumn; import java.awt.*; import java.util.ArrayList; import java.util.List; /** * Swing Runner for Junit4Osgi. * * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a> */ public class SwingRunner extends javax.swing.JFrame implements BundleListener { /** * UUID. */ private static final long serialVersionUID = 1L; /** * Bundle context (to register the bundle listener). */ private BundleContext m_context; /** * OSGi Junit Runner Service. */ private OSGiJunitRunner m_runner; /** * State variable describing if we are executing tests. */ private boolean m_running = false; // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton btnSearch; private javax.swing.JButton m_allButton; private javax.swing.JButton m_executeButton; private javax.swing.JLabel m_executedResults; private javax.swing.JScrollPane m_message; private javax.swing.JTextArea m_messageArea; private javax.swing.JButton m_ok; private javax.swing.JProgressBar m_progress; private javax.swing.JDialog m_resultDialog; private javax.swing.JScrollPane m_resultScroll; private javax.swing.JTable m_resultTable; private javax.swing.JPanel m_statusBar; private javax.swing.JList m_suiteList; private javax.swing.JScrollPane m_suiteScroll; private javax.swing.JTextField txtSearchTest; // End of variables declaration//GEN-END:variables public SwingRunner(BundleContext bc) { m_running = false; m_context = bc; } private void internalInitComponents() { initComponents(); } /** * Start method. */ public void start() { internalInitComponents(); setVisible(true); m_resultDialog.setVisible(false); refreshSuites(); m_context.addBundleListener(this); m_executedResults.setText(" \t No executed tests"); m_progress.setIndeterminate(false); m_progress.setMaximum(100); m_progress.setValue(100); TableColumn column = null; for (int i = 0; i < m_resultTable.getColumnCount(); i++) { column = m_resultTable.getColumnModel().getColumn(i); if (i == 0) { column.setPreferredWidth(350); // first column is bigger } else { column.setPreferredWidth(50); column.setCellRenderer(new ResultCellRenderer()); } } } /** * Stop method. */ public void stop() { m_context.removeBundleListener(this); dispose(); } /** * Refresh the list of available test suites. */ @SuppressWarnings("unchecked") private void refreshSuites() { String textToSearch = txtSearchTest.getText(); List<Test> tests = m_runner.getTests(); TestListModel lm = (TestListModel) m_suiteList.getModel(); lm.clear(); for (Test test : tests) { String testName = test.toString(); if (textToSearch != null && !textToSearch.trim().equals("")) { if (testName.toLowerCase().indexOf(textToSearch.toLowerCase()) != -1) { lm.addTest(test); } } else { // found all lm.addTest(test); } } //getInstanceManager().onExit(this, "refreshSuites", null); } /** * This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { m_resultDialog = new javax.swing.JDialog(); m_message = new javax.swing.JScrollPane(); m_messageArea = new javax.swing.JTextArea(); m_ok = new javax.swing.JButton(); m_statusBar = new javax.swing.JPanel(); m_progress = new javax.swing.JProgressBar(); m_executeButton = new javax.swing.JButton(); m_allButton = new javax.swing.JButton(); m_suiteScroll = new javax.swing.JScrollPane(); m_suiteList = new javax.swing.JList(); m_resultScroll = new javax.swing.JScrollPane(); m_resultTable = new javax.swing.JTable(); m_executedResults = new javax.swing.JLabel(); txtSearchTest = new javax.swing.JTextField(); btnSearch = new javax.swing.JButton(); m_resultDialog.setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE); m_resultDialog.setMinimumSize(new java.awt.Dimension(1024, 600)); m_resultDialog.addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosed(java.awt.event.WindowEvent evt) { onDialogClosed(evt); } public void windowClosing(java.awt.event.WindowEvent evt) { onDialogClosed(evt); } }); m_message.setBorder(null); m_message.setMinimumSize(new java.awt.Dimension(300, 202)); m_message.setPreferredSize(new java.awt.Dimension(300, 202)); m_messageArea.setBackground(javax.swing.UIManager.getDefaults().getColor("Panel.background")); m_messageArea.setColumns(20); m_messageArea.setEditable(false); m_messageArea.setLineWrap(true); m_messageArea.setRows(5); m_messageArea.setWrapStyleWord(true); m_messageArea.setMinimumSize(new java.awt.Dimension(300, 250)); m_messageArea.setPreferredSize(new java.awt.Dimension(250, 200)); m_message.setViewportView(m_messageArea); m_resultDialog.getContentPane().add(m_message, java.awt.BorderLayout.CENTER); m_ok.setText("Ok"); m_ok.setPreferredSize(new java.awt.Dimension(120, 23)); m_ok.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { okActionPerformed(evt); } }); m_resultDialog.getContentPane().add(m_ok, java.awt.BorderLayout.SOUTH); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setTitle("Junit Runner"); setMinimumSize(null); m_progress.setIndeterminate(true); m_progress.setMinimumSize(null); m_progress.setPreferredSize(null); javax.swing.GroupLayout m_statusBarLayout = new javax.swing.GroupLayout(m_statusBar); m_statusBar.setLayout(m_statusBarLayout); m_statusBarLayout.setHorizontalGroup( m_statusBarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(m_progress, javax.swing.GroupLayout.DEFAULT_SIZE, 466, Short.MAX_VALUE) ); m_statusBarLayout.setVerticalGroup( m_statusBarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(m_statusBarLayout.createSequentialGroup() .addComponent(m_progress, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); m_executeButton.setText("Execute"); m_executeButton.setMaximumSize(new java.awt.Dimension(90, 23)); m_executeButton.setMinimumSize(new java.awt.Dimension(90, 23)); m_executeButton.setPreferredSize(new java.awt.Dimension(100, 23)); m_executeButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { executeButtonActionPerformed(evt); } }); m_allButton.setText("Select All"); m_allButton.setMaximumSize(new java.awt.Dimension(90, 23)); m_allButton.setMinimumSize(new java.awt.Dimension(90, 23)); m_allButton.setPreferredSize(new java.awt.Dimension(100, 23)); m_allButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { allButtonActionPerformed(evt); } }); m_suiteScroll.setAutoscrolls(true); m_suiteList.setModel(new TestListModel()); m_suiteList.setMaximumSize(null); m_suiteList.setMinimumSize(null); m_suiteList.setPreferredSize(null); m_suiteScroll.setViewportView(m_suiteList); m_resultScroll.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); m_resultTable.setAutoCreateRowSorter(true); m_resultTable.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N m_resultTable.setModel(new ResultTableModel()); m_resultTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_ALL_COLUMNS); m_resultTable.setMaximumSize(null); m_resultTable.setMinimumSize(null); m_resultTable.setPreferredSize(null); m_resultTable.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { resultTableMouseClicked(evt); } }); m_resultScroll.setViewportView(m_resultTable); m_executedResults.setText("aaaaaaaaaaaaaaa"); m_executedResults.setPreferredSize(null); btnSearch.setText("Search"); btnSearch.setMaximumSize(new java.awt.Dimension(90, 23)); btnSearch.setMinimumSize(new java.awt.Dimension(90, 23)); btnSearch.setPreferredSize(new java.awt.Dimension(100, 23)); btnSearch.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnSearchActionPerformed(evt); } }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(m_resultScroll, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 598, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() .addComponent(m_statusBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(m_executedResults, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(txtSearchTest, javax.swing.GroupLayout.Alignment.LEADING) .addComponent(m_suiteScroll, javax.swing.GroupLayout.DEFAULT_SIZE, 492, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(m_executeButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(m_allButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(btnSearch, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(txtSearchTest, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(btnSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(m_allButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(m_executeButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(m_suiteScroll, javax.swing.GroupLayout.DEFAULT_SIZE, 152, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(m_resultScroll, javax.swing.GroupLayout.PREFERRED_SIZE, 415, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(m_executedResults, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(m_statusBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) ); pack(); }// </editor-fold>//GEN-END:initComponents /** * Execute button action. * * @param evt : event. */ private void executeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_executeButtonActionPerformed if (m_running) { return; } // Collect selected test. int[] indices = m_suiteList.getSelectedIndices(); List<Test> list = new ArrayList<Test>(indices.length); TestListModel model = (TestListModel) m_suiteList.getModel(); for (int i = 0; i < indices.length; i++) { list.add(model.getTestElementAt(indices[i])); } setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); executeTest(list); }//GEN-LAST:event_m_executeButtonActionPerformed /** * All button action. * * @param evt : event. */ private void allButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_allButtonActionPerformed int max = m_suiteList.getModel().getSize(); int[] indices = new int[max]; for (int i = 0; i < max; i++) { indices[i] = i; } m_suiteList.setSelectedIndices(indices); }//GEN-LAST:event_m_allButtonActionPerformed /** * Listener on table click. * * @param evt : event. */ private void resultTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_m_resultTableMouseClicked Point p = evt.getPoint(); int row = m_resultTable.rowAtPoint(p); int col = m_resultTable.columnAtPoint(p); ResultTableModel model = (ResultTableModel) m_resultTable.getModel(); String message = model.getMessage(row, col); if (message != null) { setEnabled(false); m_resultDialog.setTitle("Test Report"); m_messageArea.setText(message); m_resultDialog.setVisible(true); } }//GEN-LAST:event_m_resultTableMouseClicked /** * Ok button action. * * @param evt : event. */ private void okActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_okActionPerformed m_resultDialog.setVisible(false); setEnabled(true); }//GEN-LAST:event_m_okActionPerformed /** * Listener when the test report is closed. * * @param evt : event. */ private void onDialogClosed(java.awt.event.WindowEvent evt) { m_resultDialog.setVisible(false); setEnabled(true); } private void btnSearchActionPerformed(java.awt.event.ActionEvent evt) { refreshSuites(); } /** * Execute method. * * @param list : list of test to execute. */ private void executeTest(final List<Test> list) { Runnable thread = new Runnable() { public void run() { ResultTableModel model = (ResultTableModel) m_resultTable.getModel(); m_running = true; m_executeButton.setText("Running..."); m_progress.setIndeterminate(true); model.clear(); for (int i = 0; i < list.size(); i++) { TestResult tr = new TestResult(); tr.addListener(new MyTestListener()); list.get(i).run(tr); } m_running = false; m_progress.setIndeterminate(false); m_progress.setMaximum(100); m_progress.setValue(100); m_executeButton.setText("Execute"); computeExecutedTest(); setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } }; new Thread(thread).start(); } /** * Compute executed tests. * (Status bar message) */ private void computeExecutedTest() { ResultTableModel results = (ResultTableModel) m_resultTable.getModel(); String m = " \t "; m += results.getTestCount() + " tests executed / "; m += results.getSucess() + " success / "; m += results.getFailures() + " failures / "; m += results.getErrors() + " errors "; m_executedResults.setText(m); } private class MyTestListener implements junit.framework.TestListener { /** * Table model. */ ResultTableModel m_model = (ResultTableModel) m_resultTable.getModel(); /** * Add an error. * * @param arg0 : test which throws an error. * @param arg1 : thrown exception. * @see junit.framework.TestListener#addError(junit.framework.Test, Throwable) */ public void addError(Test arg0, Throwable arg1) { m_model.addTest(arg0, arg1); adjustScroll(); } /** * Add a failure. * * @param arg0 : failing test. * @param arg1 : thrown failure. * @see junit.framework.TestListener#addError(junit.framework.Test, Throwable) */ public void addFailure(Test arg0, AssertionFailedError arg1) { m_model.addTest(arg0, arg1); adjustScroll(); } /** * End of a test. * * @param arg0 : test. * @see junit.framework.TestListener#endTest(junit.framework.Test) */ public void endTest(Test arg0) { m_model.addTest(arg0); adjustScroll(); } /** * Start of a test. * * @param arg0 : test. * @see junit.framework.TestListener#startTest(junit.framework.Test) */ public void startTest(Test arg0) { // Nothing to do here. } /** * Adjust the scrolling bar of the result table. */ private void adjustScroll() { JScrollBar bar = m_resultScroll.getVerticalScrollBar(); if ((bar != null) && (bar.isVisible())) { bar.setValue(Integer.MAX_VALUE); } } } public void bundleChanged(BundleEvent bundleevent) { refreshSuites(); } }