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