1 package org.simantics.tests.modelled.ui;
4 import java.util.concurrent.Executors;
6 import javax.annotation.PostConstruct;
7 import javax.annotation.PreDestroy;
9 import org.eclipse.e4.ui.di.Focus;
10 import org.eclipse.jface.layout.TreeColumnLayout;
11 import org.eclipse.jface.viewers.CellLabelProvider;
12 import org.eclipse.jface.viewers.ColumnWeightData;
13 import org.eclipse.jface.viewers.ISelection;
14 import org.eclipse.jface.viewers.ISelectionChangedListener;
15 import org.eclipse.jface.viewers.OwnerDrawLabelProvider;
16 import org.eclipse.jface.viewers.SelectionChangedEvent;
17 import org.eclipse.jface.viewers.TreeSelection;
18 import org.eclipse.jface.viewers.TreeViewer;
19 import org.eclipse.jface.viewers.TreeViewerColumn;
20 import org.eclipse.jface.viewers.ViewerCell;
21 import org.eclipse.swt.SWT;
22 import org.eclipse.swt.custom.CTabFolder;
23 import org.eclipse.swt.custom.CTabItem;
24 import org.eclipse.swt.custom.SashForm;
25 import org.eclipse.swt.custom.StyledText;
26 import org.eclipse.swt.custom.ViewForm;
27 import org.eclipse.swt.graphics.Point;
28 import org.eclipse.swt.layout.FormAttachment;
29 import org.eclipse.swt.layout.FormData;
30 import org.eclipse.swt.layout.GridData;
31 import org.eclipse.swt.layout.GridLayout;
32 import org.eclipse.swt.widgets.Composite;
33 import org.eclipse.swt.widgets.Event;
34 import org.eclipse.swt.widgets.Layout;
35 import org.eclipse.swt.widgets.Tree;
36 import org.eclipse.swt.widgets.TreeColumn;
37 import org.eclipse.ui.part.PageBook;
38 import org.simantics.db.Resource;
39 import org.simantics.scl.compiler.module.coverage.Coverage;
41 public class STSTestRunnerView {
43 public static final String ID = "org.simantics.tests.modelled.ui.stsTestRunnerView";
45 private Resource test;
46 private SashForm sashForm;
47 private PageBook viewerbook;
48 private TreeViewer treeViewer;
49 // private ITreeContentProvider treeContentProvider;
50 private STSTestSuiteProvider provider;
51 private StyledText output;
52 private STSCounterPanel counterPanel;
53 private STSProgressBar progressBar;
54 private Composite counterComposite;
57 void createView(Composite parent) {
59 GridLayout gridLayout= new GridLayout();
60 gridLayout.marginWidth= 0;
61 gridLayout.marginHeight= 0;
62 parent.setLayout(gridLayout);
64 counterComposite= createProgressCountPanel(parent);
65 counterComposite.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
66 counterComposite.pack();
68 SashForm sashForm = createSashForm(parent);
69 sashForm.setLayoutData(new GridData(GridData.FILL_BOTH));
72 private SashForm createSashForm(Composite parent) {
73 sashForm = new SashForm(parent, SWT.VERTICAL);
75 ViewForm top = new ViewForm(sashForm, SWT.NONE);
77 Composite empty = new Composite(top, SWT.NONE);
78 empty.setLayout(new Layout() {
80 protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
81 return new Point(1, 1); // (0, 0) does not work with super-intelligent ViewForm
84 protected void layout(Composite composite, boolean flushCache) {
87 top.setTopLeft(empty); // makes ViewForm draw the horizontal separator line ...
88 // fTestViewer= new TestViewer(top, fClipboard, this);
89 createTestViewers(top);
90 top.setContent(viewerbook);
91 treeViewer.setInput(test);
93 ViewForm bottom = new ViewForm(sashForm, SWT.NONE);
95 CTabFolder folder = new CTabFolder(bottom, SWT.BORDER);
96 folder.setLayoutData(new GridData(GridData.FILL_BOTH));
98 CTabItem item1 = new CTabItem(folder, SWT.NONE);
99 item1.setText("Execution");
100 // PageBook fViewerbook2= new PageBook(bottom, SWT.NULL);
102 output = new StyledText(folder, SWT.MULTI | SWT.READ_ONLY | SWT.V_SCROLL | SWT.H_SCROLL);
103 // output.setFont(textFont);
105 FormData formData = new FormData();
106 formData.top = new FormAttachment(0);
107 // formData.bottom = new FormAttachment(sash);
108 formData.left = new FormAttachment(0);
109 formData.right = new FormAttachment(100);
110 output.setLayoutData(formData);
112 item1.setControl(output);
113 // fViewerbook2.showPage(output);
114 bottom.setContent(folder);
115 folder.setSelection(0);
117 CTabItem item2 = new CTabItem(folder, SWT.NONE);
118 item2.setText("Coverage");
120 Composite treeComposite = new Composite(folder, SWT.NONE);
122 TreeViewer viewer = createCoverageViewer(treeComposite);
123 item2.setControl(treeComposite);
125 treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
128 public void selectionChanged(SelectionChangedEvent event) {
129 ISelection selection = event.getSelection();
130 TreeSelection sel = (TreeSelection) selection;
131 List<String> testOutput = provider.getModel().getOutput(sel.getFirstElement());
133 viewer.setInput(sel.getFirstElement());
135 StringBuilder sb = new StringBuilder();
136 for (String o : testOutput) {
139 output.setText(sb.toString());
143 sashForm.setWeights(new int[] {50, 50});
147 protected static final int COLUMN_ELEMENT = 0;
148 protected static final int COLUMN_RATIO = 1;
149 protected static final int COLUMN_COVERED = 2;
150 protected static final int COLUMN_MISSED = 3;
151 protected static final int COLUMN_TOTAL = 4;
153 private TreeViewer createCoverageViewer(Composite parent) {
154 // Composite treeViewerComposite = new Composite(parent, SWT.NONE);
156 TreeColumnLayout layout = new TreeColumnLayout();
157 parent.setLayout(layout);
159 Tree tree = new Tree(parent, SWT.MULTI | SWT.FULL_SELECTION);
160 tree.setHeaderVisible(true);
161 tree.setLinesVisible(true);
163 STSCoverageProvider provider = new STSCoverageProvider();
165 TreeViewer viewer = new TreeViewer(tree);
167 CoverageViewSorter sorter = new CoverageViewSorter(viewer);
169 final TreeViewerColumn column0 = new TreeViewerColumn(viewer, SWT.LEFT);
171 column0.setLabelProvider(new CellLabelProvider() {
175 public void update(ViewerCell cell) {
176 cell.setText(provider.getText(cell.getElement()));
177 cell.setImage(provider.getImage(cell.getElement()));
180 sorter.addColumn(column0, COLUMN_ELEMENT);
182 final TreeViewerColumn column1 = new TreeViewerColumn(viewer, SWT.RIGHT);
183 column1.setLabelProvider(new OwnerDrawLabelProvider() {
186 public void update(ViewerCell cell) {
187 cell.setText(provider.getRatio(cell.getElement()));
191 protected void erase(Event event, Object element) {
195 protected void measure(Event event, Object element) {
199 protected void paint(Event event, Object element) {
200 final Coverage coverage = (Coverage) element;
201 if (coverage != null) {
202 RedGreenBar.draw(event, column1.getColumn().getWidth(), coverage);
206 sorter.addColumn(column1, COLUMN_RATIO);
208 final TreeViewerColumn column2 = new TreeViewerColumn(viewer, SWT.RIGHT);
209 column2.setLabelProvider(new CellLabelProvider() {
212 public void update(ViewerCell cell) {
213 cell.setText(provider.getCovered(cell.getElement()));
216 sorter.addColumn(column2, COLUMN_COVERED);
218 final TreeViewerColumn column3 = new TreeViewerColumn(viewer, SWT.RIGHT);
219 column3.setLabelProvider(new CellLabelProvider() {
222 public void update(ViewerCell cell) {
223 cell.setText(provider.getMissed(cell.getElement()));
226 sorter.addColumn(column3, COLUMN_MISSED);
228 final TreeViewerColumn column4 = new TreeViewerColumn(viewer, SWT.RIGHT);
229 column4.setLabelProvider(new CellLabelProvider() {
232 public void update(ViewerCell cell) {
233 cell.setText(provider.getTotal(cell.getElement()));
236 sorter.addColumn(column4, COLUMN_TOTAL);
238 // viewer.addFilter(new ViewerFilter() {
239 // public boolean select(Viewer viewer, Object parentElement, Object element) {
240 // if (element == LOADING_ELEMENT) {
243 // final ICoverageNode c = CoverageTools.getCoverageInfo(element);
247 // final ICounter instructions = c.getInstructionCounter();
248 // if (instructions.getTotalCount() == 0) {
251 // if (settings.getHideUnusedElements() && instructions.getCoveredCount() == 0) {
258 viewer.setComparator(sorter);
260 layout.setColumnData(column0.getColumn(), new ColumnWeightData(0, 50, false));
261 layout.setColumnData(column1.getColumn(), new ColumnWeightData(0, 50, false));
262 layout.setColumnData(column2.getColumn(), new ColumnWeightData(0, 50, false));
263 layout.setColumnData(column3.getColumn(), new ColumnWeightData(0, 50, false));
264 layout.setColumnData(column4.getColumn(), new ColumnWeightData(0, 50, false));
266 String[] columns = new String[] {"Module", "Coverage", "Covered Instructions", "Missed Instructions", "Total Instructions"};
267 TreeColumn[] columns2 = viewer.getTree().getColumns();
268 for (int i = 0; i < columns2.length; i++) {
269 columns2[i].setText(columns[i]);
271 restoreColumnWidth(viewer);
272 viewer.setContentProvider(provider);
275 // viewer.addOpenListener(new IOpenListener() {
276 // public void open(OpenEvent event) {
277 // openAction.run((IStructuredSelection) event.getSelection());
281 // MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
282 // menuMgr.setRemoveAllWhenShown(true);
283 // tree.setMenu(menuMgr.createContextMenu(tree));
284 // getSite().registerContextMenu(menuMgr, viewer);
286 // CoverageTools.getSessionManager().addSessionListener(descriptionUpdater);
287 // CoverageTools.addJavaCoverageListener(coverageListener);
290 private static final int[] DEFAULT_COLUMNWIDTH = new int[] { 200, 100, 120,
293 public void restoreColumnWidth(TreeViewer viewer) {
294 final TreeColumn[] columns = viewer.getTree().getColumns();
295 for (int i = 0; i < DEFAULT_COLUMNWIDTH.length; i++) {
296 columns[i].setWidth(DEFAULT_COLUMNWIDTH[i]);
300 protected Composite createProgressCountPanel(Composite parent) {
301 Composite composite= new Composite(parent, SWT.NONE);
302 GridLayout layout= new GridLayout();
303 composite.setLayout(layout);
304 layout.numColumns = 1;
306 counterPanel = new STSCounterPanel(composite);
307 counterPanel.setLayoutData(
308 new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
309 progressBar = new STSProgressBar(composite);
310 progressBar.setLayoutData(
311 new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
315 private void createTestViewers(Composite parent) {
316 viewerbook = new PageBook(parent, SWT.NULL);
318 treeViewer = new TreeViewer(viewerbook, SWT.V_SCROLL | SWT.SINGLE);
319 treeViewer.setUseHashlookup(true);
321 STSTestSuiteModel model = new STSTestSuiteModel();
322 model.addListener(new STSExecutionListener() {
325 public void testExecuted() {
326 treeViewer.getControl().getDisplay().syncExec(() -> {
328 treeViewer.refresh();
333 provider = new STSTestSuiteProvider(model);
335 treeViewer.setContentProvider(provider);
336 treeViewer.setLabelProvider(provider);
339 viewerbook.showPage(treeViewer.getTree());
349 public void currentTest(Resource test) {
350 treeViewer.setInput(test);
354 private void refreshCounters() {
355 // TODO: Inefficient. Either
356 // - keep a boolean fHasTestRun and update only on changes, or
357 // - improve components to only redraw on changes (once!).
364 int assumptionFailureCount;
365 boolean hasErrorsOrFailures;
368 STSTestSuiteModel model = provider.getModel();
370 startedCount= model.getStartedCount();
371 ignoredCount= model.getIgnoredCount();
372 totalCount= model.getTotalCount();
373 errorCount= model.getErrorCount();
374 failureCount= model.getFailureCount();
375 assumptionFailureCount = model.getAssumptionFailureCount();
376 hasErrorsOrFailures= errorCount + failureCount > 0;
377 stopped= model.isStopped();
384 assumptionFailureCount = 0;
385 hasErrorsOrFailures= false;
389 counterPanel.setTotal(totalCount);
390 counterPanel.setRunValue(startedCount, ignoredCount, assumptionFailureCount);
391 counterPanel.setErrorValue(errorCount);
392 counterPanel.setFailureValue(failureCount);
395 if (startedCount == 0)
397 else if (startedCount == totalCount && model.isStopped())
398 ticksDone= totalCount;
400 ticksDone= startedCount - 1;
402 progressBar.reset(hasErrorsOrFailures, stopped, ticksDone, totalCount);
405 public void execute() {
406 Executors.newSingleThreadExecutor().submit(new Runnable() {
410 provider.getModel().execute();
416 public void destroy() {