blob: ed5133debb3bd9d117a38047b7567b66e2857670 [file] [log] [blame]
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();
}
}