/*******************************************************************************
* Copyright (c) 2012 VMWare, Inc.
* 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:
* VMWare, Inc. - initial API and implementation
*******************************************************************************/
package org.grails.ide.eclipse.test.gsp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.codehaus.jdt.groovy.model.GroovyCompilationUnit;
import org.eclipse.core.resources.IFile;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.SourceRange;
import org.grails.ide.eclipse.editor.gsp.search.IGSPSearchRequestor;
import org.grails.ide.eclipse.editor.gsp.search.SearchInGSPs;
/**
* @author Andrew Eisenberg
* @since 2.7.0
*/
public class GSPSearchTests extends AbstractGSPTagsTest {
public void testSearchForListType() throws Exception {
String gspContent = "${List\nList f\nClass<List> t}";
IType type = testProject.getJavaProject().findType("java.util.List");
assertMatchesInGSP(gspContent, type, findInContents(gspContent, type.getElementName()));
}
public void testSearchForListIteratorMethod() throws Exception {
String gspContent = "${List f\nf.iterator\n[].iterator}";
IType type = testProject.getJavaProject().findType("java.util.List");
IMember member = type.getMethod("iterator", new String[0]);
assertMatchesInGSP(gspContent, member, findInContents(gspContent, member.getElementName()));
}
// Standard tag not being found because there is no source attachment
public void _testSearchForStandardTag() throws Exception {
String gspContent = "<g:form><g:form a=\"\"/></g:form>\n" +
"<g:form a=\"\" ><g:form /></g:form>";
IType type = testProject.getJavaProject().findType("org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib");
IMember member = type.getField("form");
assertMatchesInGSP(gspContent, member, findInContents(gspContent, member.getElementName()));
}
// Standard tag not being found because there is no source attachment
public void _testSearchForStandardTag2() throws Exception {
String gspContent = "<kkk:form /><g:form><g:form a=\"\"/></g:form>\n" +
"<g:form a=\"\" ><g:form /></g:form>";
IType type = testProject.getJavaProject().findType("org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib");
IMember member = type.getField("form");
List<ISourceRange> findInContents = findInContents(gspContent, member.getElementName());
findInContents.remove(0);
assertMatchesInGSP(gspContent, member, findInContents);
}
public void testSearchForCustomTag() throws Exception {
GroovyCompilationUnit unit = createTagLib("def myTag = { }");
String gspContent = "<g:myTag><g:myTag a=\"\"/></g:myTag>\n" +
"<g:myTag a=\"\" ><g:myTag /></g:myTag>";
IMember member = unit.getTypes()[0].getField("myTag");
assertMatchesInGSP(gspContent, member, findInContents(gspContent, member.getElementName()));
}
public void testSearchForCustomTag2() throws Exception {
GroovyCompilationUnit unit = createTagLib("def myTag = { }");
String gspContent = "<kkk:myTag /><g:myTag><g:myTag a=\"\"/></g:myTag>\n" +
"<g:myTag a=\"\" ><g:myTag /></g:myTag>";
IMember member = unit.getTypes()[0].getField("myTag");
List<ISourceRange> findInContents = findInContents(gspContent, member.getElementName());
findInContents.remove(0); // first location isn't a match
assertMatchesInGSP(gspContent, member, findInContents);
}
private List<ISourceRange> findInContents(String gspContent, String toFind) {
List<ISourceRange> matches = new ArrayList<ISourceRange>();
int from = 0;
while (from < gspContent.length()) {
int nextMatch = gspContent.indexOf(toFind, from);
if (nextMatch > 0) {
matches.add(new SourceRange(nextMatch, toFind.length()));
from = nextMatch +1;
} else {
break;
}
}
return matches;
}
class TestGSPRequestor implements IGSPSearchRequestor {
final IFile fileToSearch;
final IJavaElement elementToSearchFor;
Set<ISourceRange> matches = new TreeSet<ISourceRange>(new Comparator<ISourceRange>() {
public int compare(ISourceRange o1, ISourceRange o2) {
return o1.getOffset() - o2.getOffset();
}
});
public TestGSPRequestor(IFile fileToSearch, IJavaElement elementToSearchFor) {
this.fileToSearch = fileToSearch;
this.elementToSearchFor = elementToSearchFor;
}
public boolean searchForTags() {
return true;
}
public void acceptMatch(IFile file, int start, int length) {
matches.add(new SourceRange(start, length));
}
public int limitTo() {
return IJavaSearchConstants.REFERENCES;
}
public IJavaElement elementToSearchFor() {
return elementToSearchFor;
}
public List<IFile> getGSPsToSearch() {
return Collections.singletonList(fileToSearch);
}
}
private void assertMatchesInGSP(String gspContent, IJavaElement elementToSearchFor, List<ISourceRange> expectedMatches) throws Exception {
assertTrue("Element to search for does not exits: " + elementToSearchFor, elementToSearchFor.exists());
IFile file = testProject.createFile("grails-app/views/some.gsp", gspContent);
TestGSPRequestor requestor = new TestGSPRequestor(file, elementToSearchFor);
SearchInGSPs search = new SearchInGSPs();
search.performSearch(requestor, null);
assertEquals(expectedMatches, new ArrayList<ISourceRange>(requestor.matches));
}
}