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.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;
45 public class STSTestRunnerView {
47 public static final String ID = "org.simantics.tests.modelled.ui.stsTestRunnerView";
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;
61 void createView(MPart part, Composite parent) {
63 GridLayout gridLayout= new GridLayout();
64 gridLayout.marginWidth= 0;
65 gridLayout.marginHeight= 0;
66 parent.setLayout(gridLayout);
68 counterComposite = createProgressCountPanel(parent);
69 counterComposite.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
70 counterComposite.pack();
72 SashForm sashForm = createSashForm(parent);
73 sashForm.setLayoutData(new GridData(GridData.FILL_BOTH));
75 // IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager();
78 private SashForm createSashForm(Composite parent) {
79 sashForm = new SashForm(parent, SWT.VERTICAL);
81 ViewForm top = new ViewForm(sashForm, SWT.NONE);
83 Composite empty = new Composite(top, SWT.NONE);
84 empty.setLayout(new Layout() {
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
90 protected void layout(Composite composite, boolean flushCache) {
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);
99 ViewForm bottom = new ViewForm(sashForm, SWT.NONE);
101 CTabFolder folder = new CTabFolder(bottom, SWT.BORDER);
102 folder.setLayoutData(new GridData(GridData.FILL_BOTH));
104 CTabItem item1 = new CTabItem(folder, SWT.NONE);
105 item1.setText("Execution");
106 // PageBook fViewerbook2= new PageBook(bottom, SWT.NULL);
108 output = new StyledText(folder, SWT.MULTI | SWT.READ_ONLY | SWT.V_SCROLL | SWT.H_SCROLL);
109 // output.setFont(textFont);
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);
118 item1.setControl(output);
119 // fViewerbook2.showPage(output);
120 bottom.setContent(folder);
121 folder.setSelection(0);
123 CTabItem item2 = new CTabItem(folder, SWT.NONE);
124 item2.setText("Coverage");
126 Composite treeComposite = new Composite(folder, SWT.NONE);
128 TreeViewer viewer = createCoverageViewer(treeComposite);
129 item2.setControl(treeComposite);
131 treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
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());
139 viewer.setInput(sel.getFirstElement());
141 StringBuilder sb = new StringBuilder();
142 for (String o : testOutput) {
145 output.setText(sb.toString());
149 sashForm.setWeights(new int[] {50, 50});
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;
159 private TreeViewer createCoverageViewer(Composite parent) {
160 // Composite treeViewerComposite = new Composite(parent, SWT.NONE);
162 TreeColumnLayout layout = new TreeColumnLayout();
163 parent.setLayout(layout);
165 Tree tree = new Tree(parent, SWT.MULTI | SWT.FULL_SELECTION);
166 tree.setHeaderVisible(true);
167 tree.setLinesVisible(true);
169 STSCoverageProvider provider = new STSCoverageProvider();
171 TreeViewer viewer = new TreeViewer(tree);
173 CoverageViewSorter sorter = new CoverageViewSorter(viewer);
175 final TreeViewerColumn column0 = new TreeViewerColumn(viewer, SWT.LEFT);
177 column0.setLabelProvider(new CellLabelProvider() {
181 public void update(ViewerCell cell) {
182 cell.setText(provider.getText(cell.getElement()));
183 cell.setImage(provider.getImage(cell.getElement()));
186 sorter.addColumn(column0, COLUMN_ELEMENT);
188 final TreeViewerColumn column1 = new TreeViewerColumn(viewer, SWT.RIGHT);
189 column1.setLabelProvider(new OwnerDrawLabelProvider() {
192 public void update(ViewerCell cell) {
193 cell.setText(provider.getRatio(cell.getElement()));
197 protected void erase(Event event, Object element) {
201 protected void measure(Event event, Object element) {
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);
212 sorter.addColumn(column1, COLUMN_RATIO);
214 final TreeViewerColumn column2 = new TreeViewerColumn(viewer, SWT.RIGHT);
215 column2.setLabelProvider(new CellLabelProvider() {
218 public void update(ViewerCell cell) {
219 cell.setText(provider.getCovered(cell.getElement()));
222 sorter.addColumn(column2, COLUMN_COVERED);
224 final TreeViewerColumn column3 = new TreeViewerColumn(viewer, SWT.RIGHT);
225 column3.setLabelProvider(new CellLabelProvider() {
228 public void update(ViewerCell cell) {
229 cell.setText(provider.getMissed(cell.getElement()));
232 sorter.addColumn(column3, COLUMN_MISSED);
234 final TreeViewerColumn column4 = new TreeViewerColumn(viewer, SWT.RIGHT);
235 column4.setLabelProvider(new CellLabelProvider() {
238 public void update(ViewerCell cell) {
239 cell.setText(provider.getTotal(cell.getElement()));
242 sorter.addColumn(column4, COLUMN_TOTAL);
244 // viewer.addFilter(new ViewerFilter() {
245 // public boolean select(Viewer viewer, Object parentElement, Object element) {
246 // if (element == LOADING_ELEMENT) {
249 // final ICoverageNode c = CoverageTools.getCoverageInfo(element);
253 // final ICounter instructions = c.getInstructionCounter();
254 // if (instructions.getTotalCount() == 0) {
257 // if (settings.getHideUnusedElements() && instructions.getCoveredCount() == 0) {
264 viewer.setComparator(sorter);
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));
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]);
277 restoreColumnWidth(viewer);
278 viewer.setContentProvider(provider);
281 // viewer.addOpenListener(new IOpenListener() {
282 // public void open(OpenEvent event) {
283 // openAction.run((IStructuredSelection) event.getSelection());
287 // MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
288 // menuMgr.setRemoveAllWhenShown(true);
289 // tree.setMenu(menuMgr.createContextMenu(tree));
290 // getSite().registerContextMenu(menuMgr, viewer);
292 // CoverageTools.getSessionManager().addSessionListener(descriptionUpdater);
293 // CoverageTools.addJavaCoverageListener(coverageListener);
296 private static final int[] DEFAULT_COLUMNWIDTH = new int[] { 200, 100, 120,
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]);
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;
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));
321 private void createTestViewers(Composite parent) {
322 viewerbook = new PageBook(parent, SWT.NULL);
324 treeViewer = new TreeViewer(viewerbook, SWT.V_SCROLL | SWT.SINGLE);
325 treeViewer.setUseHashlookup(true);
327 STSTestSuiteModel model = new STSTestSuiteModel();
328 model.addListener(new STSExecutionListener() {
331 public void testExecuted() {
332 treeViewer.getControl().getDisplay().syncExec(() -> {
334 treeViewer.refresh();
339 provider = new STSTestSuiteProvider(model);
341 treeViewer.setContentProvider(provider);
342 treeViewer.setLabelProvider(provider);
345 Menu menu = new Menu(treeViewer.getControl());
347 MenuItem item1 = new MenuItem(menu, SWT.PUSH);
348 item1.setText("Stop");
349 item1.addListener(SWT.Selection, new Listener() {
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();
362 treeViewer.getControl().setMenu(menu);
365 viewerbook.showPage(treeViewer.getTree());
375 public void currentTest(Resource test) {
376 treeViewer.setInput(test);
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!).
390 int assumptionFailureCount;
391 boolean hasErrorsOrFailures;
394 STSTestSuiteModel model = provider.getModel();
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();
410 assumptionFailureCount = 0;
411 hasErrorsOrFailures= false;
415 counterPanel.setTotal(totalCount);
416 counterPanel.setRunValue(startedCount, ignoredCount, assumptionFailureCount);
417 counterPanel.setIgnoredValue(ignoredCount);
418 counterPanel.setErrorValue(errorCount);
419 counterPanel.setFailureValue(failureCount);
422 if (startedCount == 0)
424 else if (startedCount == totalCount && model.isStopped())
425 ticksDone= totalCount;
427 ticksDone= startedCount - 1;
429 progressBar.reset(hasErrorsOrFailures, stopped, ticksDone, totalCount);
432 public void execute() {
433 Executors.newSingleThreadExecutor().submit(new Runnable() {
437 provider.getModel().execute();
443 public void destroy() {