/******************************************************************************* * Copyright (c) 2016 TypeFox GmbH and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.xpect.ui.services; import static org.xpect.runner.TestExecutor.createRootConfiguration; import static org.xpect.runner.TestExecutor.createState; import static org.xpect.runner.TestExecutor.createXpectConfiguration; import static org.xpect.runner.TestExecutor.runTest; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Collections; import java.util.List; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.Platform; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.xtext.resource.XtextResource; import org.eclipse.xtext.ui.resource.ProjectByResourceProvider; import org.eclipse.xtext.util.CancelIndicator; import org.eclipse.xtext.util.CollectionBasedAcceptor; import org.eclipse.xtext.validation.CheckMode; import org.eclipse.xtext.validation.CheckType; import org.eclipse.xtext.validation.Issue; import org.xpect.XjmXpectMethod; import org.xpect.XpectFile; import org.xpect.XpectInvocation; import org.xpect.XpectJavaModel; import org.xpect.runner.Xpect; import org.xpect.state.Configuration; import org.xpect.state.StateContainer; import org.xpect.ui.preferences.XpectRootPreferencePage; import org.xpect.ui.util.XpectFileAccess; import com.google.common.base.Throwables; import com.google.common.collect.Lists; import com.google.inject.Inject; public class LiveTestRunner { @Inject private ProjectByResourceProvider projectByResourceProvider; @Inject private LiveTestIssueFactory issueFactory; protected void configureTests(Resource resource, CheckMode mode, CancelIndicator indicator, Configuration fileConfig) { try { @SuppressWarnings("unchecked") Class<? extends Annotation> thisResource = (Class<? extends Annotation>) Platform.getBundle("org.xpect.xtext.lib").loadClass("org.xpect.xtext.lib.setup.ThisResource"); fileConfig.addValue(thisResource, XtextResource.class, (XtextResource) resource); } catch (ClassNotFoundException e1) { Throwables.propagate(e1); } } public List<Issue> validateTests(Resource resource, CheckMode mode, CancelIndicator indicator, Configuration fileConfig) { IProject project = projectByResourceProvider.getProjectContext(resource); if (project == null || !XpectRootPreferencePage.isLiveTestExecutionEnabled(project)) { return Collections.emptyList(); } XpectFile xpectFile = XpectFileAccess.getXpectFile(resource); if (xpectFile == null || xpectFile.isIgnore()) { return Collections.emptyList(); } List<XpectInvocation> invocations = Lists.newArrayList(); for (XpectInvocation inv : xpectFile.getInvocations()) { if (!inv.isIgnore()) { XjmXpectMethod method = inv.getMethod(); if (method != null && !method.eIsProxy()) { Method javaMethod = method.getJavaMethod(); if (javaMethod != null) { Xpect annotation = javaMethod.getAnnotation(Xpect.class); CheckType checkType = annotation.liveExecution().toCheckType(); if (annotation != null && checkType != null && mode.shouldCheck(checkType)) { invocations.add(inv); } } } } } if (invocations.isEmpty()) { return Collections.emptyList(); } List<Issue> result = Lists.newArrayList(); XpectJavaModel javaModel = xpectFile.getJavaModel(); if (javaModel != null && javaModel.getTestOrSuite() != null && javaModel.getTestOrSuite().getJavaClass() != null) { configureTests(resource, mode, indicator, fileConfig); StateContainer rootState = createState(createRootConfiguration(javaModel)); StateContainer fileState = createState(rootState, fileConfig); for (XpectInvocation inv : invocations) { StateContainer invState = createState(fileState, createXpectConfiguration(inv)); try { runTest(invState, inv); result.add(issueFactory.createSuccessIssue(inv)); } catch (Throwable e) { issueFactory.exceptionToIssues(inv, e, CollectionBasedAcceptor.of(result)); } finally { invState.invalidate(); } } } return result; } }