/*******************************************************************************
* Copyright (c) 2012-2015 Codenvy, S.A.
* 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
*
* Contributors:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.ide.ext.java.client.core.quickfix;
import org.eclipse.che.ide.ext.java.jdt.codeassistant.api.CompletionProposal;
import org.eclipse.che.ide.ext.java.jdt.codeassistant.api.IProblemLocation;
import org.eclipse.che.ide.ext.java.jdt.core.compiler.IProblem;
import org.eclipse.che.ide.ext.java.jdt.core.dom.AST;
import org.eclipse.che.ide.ext.java.jdt.core.dom.ASTParser;
import org.eclipse.che.ide.ext.java.jdt.core.dom.CompilationUnit;
import org.eclipse.che.ide.ext.java.jdt.internal.text.correction.AssistContext;
import org.eclipse.che.ide.ext.java.jdt.internal.text.correction.ICommandAccess;
import org.eclipse.che.ide.ext.java.jdt.internal.text.correction.ProblemLocation;
import org.eclipse.che.ide.ext.java.jdt.internal.text.correction.proposals.CUCorrectionProposal;
import org.eclipse.che.ide.ext.java.jdt.quickassist.api.InvocationContext;
import org.eclipse.che.ide.ext.java.worker.WorkerCorrectionProcessor;
import org.eclipse.che.ide.ext.java.worker.WorkerMessageHandler;
import org.eclipse.che.ide.ext.java.jdt.text.Document;
import org.eclipse.che.ide.runtime.CoreException;
import org.eclipse.che.ide.runtime.IStatus;
import org.eclipse.che.ide.api.text.BadLocationException;
import com.googlecode.gwt.test.GwtModule;
import com.googlecode.gwt.test.GwtTestWithMockito;
import org.junit.Assert;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
/**
* @author <a href="mailto:evidolob@exoplatform.com">Evgen Vidolob</a>
* @version $Id:
*/
@GwtModule("org.eclipse.che.ide.ext.java.Java")
public abstract class QuickFixTest extends GwtTestWithMockito {
public static AssistContext getCorrectionContext(Document document, int offset, int length, String name) {
AssistContext context = new AssistContext(document, offset, length);
context.setASTRoot(getASTRoot(document, name));
return context;
}
protected static final ArrayList collectAssists(InvocationContext context, boolean includeLinkedRename)
throws CoreException {
Class[] filteredTypes = includeLinkedRename ? null : new Class[0];
return collectAssists(context, filteredTypes);
}
public static void assertStatusOk(IStatus status) throws CoreException {
if (!status.isOK()) {
if (status.getException() == null) { // find a status with an exception
IStatus[] children = status.getChildren();
for (int i = 0; i < children.length; i++) {
IStatus child = children[i];
if (child.getException() != null) {
throw new CoreException(child);
}
}
}
}
}
protected static void assertNumberOfProposals(List proposals, int expectedProposals) {
if (proposals.size() != expectedProposals) {
StringBuffer buf = new StringBuffer();
buf.append("Wrong number of proposals, is: ").append(proposals.size()).append(", expected: ")
.append(expectedProposals).append('\n');
for (int i = 0; i < proposals.size(); i++) {
CompletionProposal curr = (CompletionProposal)proposals.get(i);
buf.append(" - ").append(curr.getDisplayString()).append('\n');
if (curr instanceof CUCorrectionProposal) {
appendSource(((CUCorrectionProposal)curr), buf);
}
}
Assert.assertTrue(buf.toString(), false);
}
}
private static void appendSource(CUCorrectionProposal proposal, StringBuffer buf) {
try {
buf.append(proposal.getPreviewContent());
} catch (CoreException e) {
// ignore
}
}
public static void assertCorrectLabels(List proposals) {
for (int i = 0; i < proposals.size(); i++) {
CompletionProposal proposal = (CompletionProposal)proposals.get(i);
String name = proposal.getDisplayString();
if (name == null || name.length() == 0 || name.charAt(0) == '!' || name.indexOf("{0}") != -1
|| name.indexOf("{1}") != -1) {
Assert.assertTrue("wrong proposal label: " + name, false);
}
if (proposal.getImage() == null) {
Assert.assertTrue("wrong proposal image", false);
}
}
}
protected static String getPreviewContent(CUCorrectionProposal proposal) throws CoreException {
return proposal.getPreviewContent();
}
public static void assertEqualStringsIgnoreOrder(String[] actuals, String[] expecteds) {
StringAsserts.assertEqualStringsIgnoreOrder(actuals, expecteds);
}
public static void addPreviewAndExpected(List proposals, StringBuffer expected, ArrayList expecteds,
ArrayList previews) throws CoreException {
CUCorrectionProposal proposal = (CUCorrectionProposal)proposals.get(expecteds.size());
previews.add(getPreviewContent(proposal));
expecteds.add(expected.toString());
}
public static void assertEqualStringsIgnoreOrder(Collection actuals, Collection expecteds) {
String[] act = (String[])actuals.toArray(new String[actuals.size()]);
String[] exp = (String[])expecteds.toArray(new String[actuals.size()]);
StringAsserts.assertEqualStringsIgnoreOrder(act, exp);
}
public static void assertExpectedExistInProposals(List actualProposals, String[] expecteds) throws CoreException,
BadLocationException {
StringAsserts.assertExpectedExistInProposals(getPreviewContents(actualProposals), expecteds);
}
protected static String[] getPreviewContents(List proposals) throws CoreException, BadLocationException {
String[] res = new String[proposals.size()];
for (int i = 0; i < proposals.size(); i++) {
Object curr = proposals.get(i);
// if (curr instanceof ReorgCorrectionsSubProcessor.ClasspathFixCorrectionProposal) {
// // ignore
// } else
if (curr instanceof CUCorrectionProposal) {
res[i] = getPreviewContent((CUCorrectionProposal)curr);
}
// else if (curr instanceof NewCUUsingWizardProposal) {
// res[i]= getWizardPreviewContent((NewCUUsingWizardProposal) curr);
// } else if (curr instanceof SurroundWithTemplateProposal) {
// res[i]= getTemplatePreviewContent((SurroundWithTemplateProposal) curr);
// } else if (curr instanceof SelfEncapsulateFieldProposal) {
// res[i]= getSEFPreviewContent((SelfEncapsulateFieldProposal) curr);
// }
}
return res;
}
public static void assertEqualString(String actual, String expected) {
StringAsserts.assertEqualString(actual, expected);
}
protected static final ArrayList collectAssists(InvocationContext context, Class[] filteredTypes)
throws CoreException {
ArrayList proposals = new ArrayList();
IStatus status = WorkerCorrectionProcessor.collectAssists(context, new IProblemLocation[0], proposals);
assertStatusOk(status);
if (!proposals.isEmpty()) {
Assert.assertTrue("should be marked as 'has assist'", WorkerCorrectionProcessor.hasAssists(context));
}
if (filteredTypes != null && filteredTypes.length > 0) {
for (Iterator iter = proposals.iterator(); iter.hasNext(); ) {
if (isFiltered(iter.next(), filteredTypes)) {
iter.remove();
}
}
}
return proposals;
}
private static boolean isFiltered(Object curr, Class[] filteredTypes) {
for (int k = 0; k < filteredTypes.length; k++) {
if (filteredTypes[k].isInstance(curr)) {
return true;
}
}
return false;
}
public static void assertProposalDoesNotExist(List actualProposals, String proposalName) {
Assert.assertTrue(findProposalByName(proposalName, actualProposals) == null);
}
protected static CompletionProposal findProposalByName(String name, List proposals) {
for (int i = 0; i < proposals.size(); i++) {
Object curr = proposals.get(i);
if (curr instanceof CompletionProposal && name.equals(((CompletionProposal)curr).getDisplayString())) {
return (CompletionProposal)curr;
}
}
return null;
}
public static void assertCommandIdDoesNotExist(List actualProposals, String commandId) {
Assert.assertTrue(findProposalByCommandId(commandId, actualProposals) == null);
}
protected static ICommandAccess findProposalByCommandId(String commandId, List proposals) {
for (int i = 0; i < proposals.size(); i++) {
Object curr = proposals.get(i);
if (curr instanceof ICommandAccess) {
if (commandId.equals(((ICommandAccess)curr).getCommandId())) {
return (ICommandAccess)curr;
}
}
}
return null;
}
protected static CompilationUnit getASTRoot(Document cu, String name) {
ASTParser astParser = ASTParser.newParser(AST.JLS4);
astParser.setSource(cu.get().toCharArray());
astParser.setResolveBindings(true);
astParser.setStatementsRecovery(true);
astParser.setBindingsRecovery(true);
astParser.setNameEnvironment(WorkerMessageHandler.get().getNameEnvironment());
astParser.setUnitName(name);
return (CompilationUnit)astParser.createAST();
}
protected static final ArrayList collectCorrections(Document cu, CompilationUnit astRoot) throws CoreException {
return collectCorrections(cu, astRoot, 1, null);
}
protected static final ArrayList collectCorrections(Document cu, CompilationUnit astRoot, int nProblems)
throws CoreException {
return collectCorrections(cu, astRoot, nProblems, null);
}
protected static final ArrayList collectCorrections(Document cu, CompilationUnit astRoot, int nProblems, int problem)
throws CoreException {
return collectCorrections(cu, astRoot, nProblems, problem, null);
}
protected static final ArrayList collectCorrections(Document cu, CompilationUnit astRoot, int nProblems,
AssistContext context) throws CoreException {
return collectCorrections(cu, astRoot, nProblems, 0, context);
}
protected static final ArrayList collectCorrections(Document cu, CompilationUnit astRoot, int nProblems,
int problem, AssistContext context) throws CoreException {
IProblem[] problems = astRoot.getProblems();
assertNumberOfProblems(nProblems, problems);
return collectCorrections(cu, problems[problem], context);
}
protected static ArrayList collectCorrections(InvocationContext context, IProblemLocation problem)
throws CoreException {
ArrayList proposals = new ArrayList();
IStatus status = WorkerCorrectionProcessor.collectCorrections(context, new IProblemLocation[]{problem}, proposals);
assertStatusOk(status);
return proposals;
}
protected static void assertNumberOfProblems(int nProblems, IProblem[] problems) {
if (problems.length != nProblems) {
StringBuffer buf = new StringBuffer("Wrong number of problems, is: ");
buf.append(problems.length).append(", expected: ").append(nProblems).append('\n');
for (int i = 0; i < problems.length; i++) {
buf.append(problems[i]);
buf.append('[').append(problems[i].getSourceStart()).append(" ,").append(problems[i].getSourceEnd())
.append(']');
buf.append('\n');
}
Assert.assertTrue(buf.toString(), false);
}
}
protected static final ArrayList collectCorrections(Document cu, IProblem curr, InvocationContext context)
throws CoreException {
int offset = curr.getSourceStart();
int length = curr.getSourceEnd() + 1 - offset;
if (context == null) {
context = new AssistContext(cu, offset, length);
}
ProblemLocation problem = new ProblemLocation(curr);
ArrayList proposals = collectCorrections(context, problem);
if (!proposals.isEmpty()) {
assertCorrectContext(context, problem);
}
return proposals;
}
public static void assertCorrectContext(InvocationContext context, ProblemLocation problem) {
if (problem.getProblemId() != 0) {
if (!WorkerCorrectionProcessor.hasCorrections(problem)) {
Assert.assertTrue("Problem type not marked with light bulb: " + problem, false);
}
}
}
protected static void assertNoErrors(InvocationContext context) {
IProblem[] problems = context.getASTRoot().getProblems();
for (int i = 0; i < problems.length; i++) {
if (problems[i].isError()) {
Assert.assertTrue("source has error: " + problems[i].getMessage(), false);
}
}
}
}