]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/STSTestRunnerView.java
Ignore multiple modelled tests via context menu action
[simantics/platform.git] / bundles / org.simantics.tests.modelled.ui / src / org / simantics / tests / modelled / ui / STSTestRunnerView.java
1 package org.simantics.tests.modelled.ui;
2
3 import java.util.List;
4 import java.util.concurrent.Executors;
5
6 import javax.annotation.PostConstruct;
7 import javax.annotation.PreDestroy;
8
9 import org.eclipse.e4.ui.di.Focus;
10 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
11 import org.eclipse.jface.layout.TreeColumnLayout;
12 import org.eclipse.jface.viewers.CellLabelProvider;
13 import org.eclipse.jface.viewers.ColumnWeightData;
14 import org.eclipse.jface.viewers.ISelection;
15 import org.eclipse.jface.viewers.ISelectionChangedListener;
16 import org.eclipse.jface.viewers.OwnerDrawLabelProvider;
17 import org.eclipse.jface.viewers.SelectionChangedEvent;
18 import org.eclipse.jface.viewers.TreeSelection;
19 import org.eclipse.jface.viewers.TreeViewer;
20 import org.eclipse.jface.viewers.TreeViewerColumn;
21 import org.eclipse.jface.viewers.ViewerCell;
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.custom.CTabFolder;
24 import org.eclipse.swt.custom.CTabItem;
25 import org.eclipse.swt.custom.SashForm;
26 import org.eclipse.swt.custom.StyledText;
27 import org.eclipse.swt.custom.ViewForm;
28 import org.eclipse.swt.graphics.Point;
29 import org.eclipse.swt.layout.FormAttachment;
30 import org.eclipse.swt.layout.FormData;
31 import org.eclipse.swt.layout.GridData;
32 import org.eclipse.swt.layout.GridLayout;
33 import org.eclipse.swt.widgets.Composite;
34 import org.eclipse.swt.widgets.Event;
35 import org.eclipse.swt.widgets.Layout;
36 import org.eclipse.swt.widgets.Listener;
37 import org.eclipse.swt.widgets.Menu;
38 import org.eclipse.swt.widgets.MenuItem;
39 import org.eclipse.swt.widgets.Tree;
40 import org.eclipse.swt.widgets.TreeColumn;
41 import org.eclipse.ui.part.PageBook;
42 import org.simantics.db.Resource;
43 import org.simantics.scl.compiler.module.coverage.Coverage;
44
45 public class STSTestRunnerView {
46     
47     public static final String ID = "org.simantics.tests.modelled.ui.stsTestRunnerView";
48
49     private Resource test;
50     private SashForm sashForm;
51     private PageBook viewerbook;
52     private TreeViewer treeViewer;
53 //    private ITreeContentProvider treeContentProvider;
54     private STSTestSuiteProvider provider;
55     private StyledText output;
56     private STSCounterPanel counterPanel;
57     private STSProgressBar progressBar;
58     private Composite counterComposite;
59
60     @PostConstruct
61     void createView(MPart part, Composite parent) {
62         
63         GridLayout gridLayout= new GridLayout();
64         gridLayout.marginWidth= 0;
65         gridLayout.marginHeight= 0;
66         parent.setLayout(gridLayout);
67         
68         counterComposite = createProgressCountPanel(parent);
69         counterComposite.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
70         counterComposite.pack();
71         
72         SashForm sashForm = createSashForm(parent);
73         sashForm.setLayoutData(new GridData(GridData.FILL_BOTH));
74         
75 //        IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager();
76     }
77     
78     private SashForm createSashForm(Composite parent) {
79         sashForm = new SashForm(parent, SWT.VERTICAL);
80
81         ViewForm top = new ViewForm(sashForm, SWT.NONE);
82
83         Composite empty = new Composite(top, SWT.NONE);
84         empty.setLayout(new Layout() {
85             @Override
86             protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
87                 return new Point(1, 1); // (0, 0) does not work with super-intelligent ViewForm
88             }
89             @Override
90             protected void layout(Composite composite, boolean flushCache) {
91             }
92         });
93         top.setTopLeft(empty); // makes ViewForm draw the horizontal separator line ...
94 //        fTestViewer= new TestViewer(top, fClipboard, this);
95         createTestViewers(top);
96         top.setContent(viewerbook);
97         treeViewer.setInput(test);
98
99         ViewForm bottom = new ViewForm(sashForm, SWT.NONE);
100
101         CTabFolder folder = new CTabFolder(bottom, SWT.BORDER);
102         folder.setLayoutData(new GridData(GridData.FILL_BOTH));
103         
104         CTabItem item1 = new CTabItem(folder, SWT.NONE);
105         item1.setText("Execution");
106 //        PageBook fViewerbook2= new PageBook(bottom, SWT.NULL);
107         // Upper
108         output = new StyledText(folder, SWT.MULTI | SWT.READ_ONLY | SWT.V_SCROLL | SWT.H_SCROLL);
109 //        output.setFont(textFont);
110         {
111             FormData formData = new FormData();
112             formData.top = new FormAttachment(0);      
113 //            formData.bottom = new FormAttachment(sash);
114             formData.left = new FormAttachment(0);
115             formData.right = new FormAttachment(100);
116             output.setLayoutData(formData);
117         }
118         item1.setControl(output);
119 //        fViewerbook2.showPage(output);
120         bottom.setContent(folder);
121         folder.setSelection(0);
122
123         CTabItem item2 = new CTabItem(folder, SWT.NONE);
124         item2.setText("Coverage");
125         
126         Composite treeComposite = new Composite(folder, SWT.NONE);
127         
128         TreeViewer viewer = createCoverageViewer(treeComposite);
129         item2.setControl(treeComposite);
130         
131         treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
132             
133             @Override
134             public void selectionChanged(SelectionChangedEvent event) {
135                 ISelection selection = event.getSelection();
136                 TreeSelection sel = (TreeSelection) selection;
137                 List<String> testOutput = provider.getModel().getOutput(sel.getFirstElement());
138                 
139                 viewer.setInput(sel.getFirstElement());
140                 
141                 StringBuilder sb = new StringBuilder();
142                 for (String o : testOutput) {
143                     sb.append(o);
144                 }
145                 output.setText(sb.toString());
146             }
147         });
148         
149         sashForm.setWeights(new int[] {50, 50});
150         return sashForm;
151     }
152     
153     protected static final int COLUMN_ELEMENT = 0;
154     protected static final int COLUMN_RATIO = 1;
155     protected static final int COLUMN_COVERED = 2;
156     protected static final int COLUMN_MISSED = 3;
157     protected static final int COLUMN_TOTAL = 4;
158     
159     private TreeViewer createCoverageViewer(Composite parent) {
160         // Composite treeViewerComposite = new Composite(parent, SWT.NONE);
161
162         TreeColumnLayout layout = new TreeColumnLayout();
163         parent.setLayout(layout);
164         
165         Tree tree = new Tree(parent, SWT.MULTI | SWT.FULL_SELECTION);
166         tree.setHeaderVisible(true);
167         tree.setLinesVisible(true);
168         
169         STSCoverageProvider provider = new STSCoverageProvider();
170
171         TreeViewer viewer = new TreeViewer(tree);
172         
173         CoverageViewSorter sorter = new CoverageViewSorter(viewer);
174         
175         final TreeViewerColumn column0 = new TreeViewerColumn(viewer, SWT.LEFT);
176         
177         column0.setLabelProvider(new CellLabelProvider() {
178
179             
180             @Override
181             public void update(ViewerCell cell) {
182                 cell.setText(provider.getText(cell.getElement()));
183                 cell.setImage(provider.getImage(cell.getElement()));
184             }
185         });
186          sorter.addColumn(column0, COLUMN_ELEMENT);
187
188         final TreeViewerColumn column1 = new TreeViewerColumn(viewer, SWT.RIGHT);
189         column1.setLabelProvider(new OwnerDrawLabelProvider() {
190
191             @Override
192             public void update(ViewerCell cell) {
193                 cell.setText(provider.getRatio(cell.getElement()));
194             }
195
196             @Override
197             protected void erase(Event event, Object element) {
198             }
199
200             @Override
201             protected void measure(Event event, Object element) {
202             }
203
204             @Override
205             protected void paint(Event event, Object element) {
206                 final Coverage coverage = (Coverage) element;
207                 if (coverage != null) {
208                     RedGreenBar.draw(event, column1.getColumn().getWidth(), coverage);
209                 }
210             }
211         });
212         sorter.addColumn(column1, COLUMN_RATIO);
213
214         final TreeViewerColumn column2 = new TreeViewerColumn(viewer, SWT.RIGHT);
215         column2.setLabelProvider(new CellLabelProvider() {
216
217             @Override
218             public void update(ViewerCell cell) {
219                 cell.setText(provider.getCovered(cell.getElement()));
220             }
221         });
222         sorter.addColumn(column2, COLUMN_COVERED);
223
224         final TreeViewerColumn column3 = new TreeViewerColumn(viewer, SWT.RIGHT);
225         column3.setLabelProvider(new CellLabelProvider() {
226
227             @Override
228             public void update(ViewerCell cell) {
229                 cell.setText(provider.getMissed(cell.getElement()));
230             }
231         });
232         sorter.addColumn(column3, COLUMN_MISSED);
233
234         final TreeViewerColumn column4 = new TreeViewerColumn(viewer, SWT.RIGHT);
235         column4.setLabelProvider(new CellLabelProvider() {
236
237             @Override
238             public void update(ViewerCell cell) {
239                 cell.setText(provider.getTotal(cell.getElement()));
240             }
241         });
242         sorter.addColumn(column4, COLUMN_TOTAL);
243
244 //        viewer.addFilter(new ViewerFilter() {
245 //            public boolean select(Viewer viewer, Object parentElement, Object element) {
246 //                if (element == LOADING_ELEMENT) {
247 //                    return true;
248 //                } else {
249 //                    final ICoverageNode c = CoverageTools.getCoverageInfo(element);
250 //                    if (c == null) {
251 //                        return false;
252 //                    }
253 //                    final ICounter instructions = c.getInstructionCounter();
254 //                    if (instructions.getTotalCount() == 0) {
255 //                        return false;
256 //                    }
257 //                    if (settings.getHideUnusedElements() && instructions.getCoveredCount() == 0) {
258 //                        return false;
259 //                    }
260 //                    return true;
261 //                }
262 //            }
263 //        });
264         viewer.setComparator(sorter);
265         
266         layout.setColumnData(column0.getColumn(), new ColumnWeightData(0, 50, false));
267         layout.setColumnData(column1.getColumn(), new ColumnWeightData(0, 50, false));
268         layout.setColumnData(column2.getColumn(), new ColumnWeightData(0, 50, false));
269         layout.setColumnData(column3.getColumn(), new ColumnWeightData(0, 50, false));
270         layout.setColumnData(column4.getColumn(), new ColumnWeightData(0, 50, false));
271         
272         String[] columns = new String[] {"Module", "Coverage", "Covered Instructions", "Missed Instructions", "Total Instructions"};
273         TreeColumn[] columns2 = viewer.getTree().getColumns();
274         for (int i = 0; i < columns2.length; i++) {
275             columns2[i].setText(columns[i]);
276         }
277         restoreColumnWidth(viewer);
278         viewer.setContentProvider(provider);
279         return viewer;
280
281 //        viewer.addOpenListener(new IOpenListener() {
282 //            public void open(OpenEvent event) {
283 //                openAction.run((IStructuredSelection) event.getSelection());
284 //            }
285 //        });
286
287 //        MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
288 //        menuMgr.setRemoveAllWhenShown(true);
289 //        tree.setMenu(menuMgr.createContextMenu(tree));
290 //        getSite().registerContextMenu(menuMgr, viewer);
291 //
292 //        CoverageTools.getSessionManager().addSessionListener(descriptionUpdater);
293 //        CoverageTools.addJavaCoverageListener(coverageListener);
294     }
295     
296     private static final int[] DEFAULT_COLUMNWIDTH = new int[] { 200, 100, 120,
297             120, 120 };
298     
299     public void restoreColumnWidth(TreeViewer viewer) {
300         final TreeColumn[] columns = viewer.getTree().getColumns();
301         for (int i = 0; i < DEFAULT_COLUMNWIDTH.length; i++) {
302           columns[i].setWidth(DEFAULT_COLUMNWIDTH[i]);
303         }
304       }
305
306     protected Composite createProgressCountPanel(Composite parent) {
307         Composite composite= new Composite(parent, SWT.NONE);
308         GridLayout layout= new GridLayout();
309         composite.setLayout(layout);
310         layout.numColumns = 1;
311
312         counterPanel = new STSCounterPanel(composite);
313         counterPanel.setLayoutData(
314             new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
315         progressBar = new STSProgressBar(composite);
316         progressBar.setLayoutData(
317                 new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
318         return composite;
319     }
320     
321     private void createTestViewers(Composite parent) {
322         viewerbook = new PageBook(parent, SWT.NULL);
323
324         treeViewer = new TreeViewer(viewerbook, SWT.V_SCROLL | SWT.SINGLE);
325         treeViewer.setUseHashlookup(true);
326         
327         STSTestSuiteModel model = new STSTestSuiteModel();
328         model.addListener(new STSExecutionListener() {
329             
330             @Override
331             public void testExecuted() {
332                 treeViewer.getControl().getDisplay().syncExec(() -> {
333                     refreshCounters();
334                     treeViewer.refresh();
335                 });
336             }
337         });
338         
339         provider = new STSTestSuiteProvider(model);
340         
341         treeViewer.setContentProvider(provider);
342         treeViewer.setLabelProvider(provider);
343
344         
345         Menu menu = new Menu(treeViewer.getControl());
346         
347         MenuItem item1 = new MenuItem(menu, SWT.PUSH);
348         item1.setText("Stop");
349         item1.addListener(SWT.Selection, new Listener() {
350             
351             @Override
352             public void handleEvent(Event event) {
353                 TreeSelection selec = (TreeSelection) treeViewer.getSelection();
354                 if (!selec.isEmpty()) {
355                     Object elem = selec.getFirstElement();
356                     provider.getModel().interrupt();
357                     
358                 }
359             }
360         });
361         
362         treeViewer.getControl().setMenu(menu);
363         
364
365         viewerbook.showPage(treeViewer.getTree());
366         
367     }
368     
369
370     @Focus
371     void setFocus() {
372         sashForm.setFocus();
373     }
374
375     public void currentTest(Resource test) {
376         treeViewer.setInput(test);
377         refreshCounters();
378     }
379     
380     private void refreshCounters() {
381         // TODO: Inefficient. Either
382        // - keep a boolean fHasTestRun and update only on changes, or
383        // - improve components to only redraw on changes (once!).
384
385        int startedCount;
386        int ignoredCount;
387        int totalCount;
388        int errorCount;
389        int failureCount;
390        int assumptionFailureCount;
391        boolean hasErrorsOrFailures;
392        boolean stopped;
393
394        STSTestSuiteModel model = provider.getModel();
395        if (model != null) {
396            startedCount= model.getStartedCount();
397            ignoredCount= model.getIgnoredCount();
398            totalCount= model.getTotalCount();
399            errorCount= model.getErrorCount();
400            failureCount= model.getFailureCount();
401            assumptionFailureCount = model.getAssumptionFailureCount();
402            hasErrorsOrFailures= errorCount + failureCount > 0;
403            stopped= model.isStopped();
404        } else {
405            startedCount= 0;
406            ignoredCount= 0;
407            totalCount= 0;
408            errorCount= 0;
409            failureCount= 0;
410            assumptionFailureCount = 0;
411            hasErrorsOrFailures= false;
412            stopped= false;
413        }
414
415        counterPanel.setTotal(totalCount);
416        counterPanel.setRunValue(startedCount, ignoredCount, assumptionFailureCount);
417        counterPanel.setIgnoredValue(ignoredCount);
418        counterPanel.setErrorValue(errorCount);
419        counterPanel.setFailureValue(failureCount);
420
421        int ticksDone;
422        if (startedCount == 0)
423            ticksDone= 0;
424        else if (startedCount == totalCount &&  model.isStopped())
425            ticksDone= totalCount;
426        else
427            ticksDone= startedCount - 1;
428
429        progressBar.reset(hasErrorsOrFailures, stopped, ticksDone, totalCount);
430    }
431
432     public void execute() {
433         Executors.newSingleThreadExecutor().submit(new Runnable() {
434
435             @Override
436             public void run() {
437                 provider.getModel().execute();
438             }
439         });
440     }
441     
442     @PreDestroy
443     public void destroy() {
444         provider.dispose();
445     }
446 }