com.google.gwt.eclipse.core.search.JavaQueryParticipantTest.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gwt.eclipse.core.search.JavaQueryParticipantTest.java

Source

/*******************************************************************************
 * Copyright 2011 Google Inc. All Rights Reserved.
 *
 * 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
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package com.google.gwt.eclipse.core.search;

import com.google.gwt.eclipse.core.test.AbstractGWTPluginTestCase;
import com.google.gwt.eclipse.core.test.RegionConverter;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.ui.search.ElementQuerySpecification;
import org.eclipse.jdt.ui.search.ISearchRequestor;
import org.eclipse.jdt.ui.search.PatternQuerySpecification;
import org.eclipse.jdt.ui.search.QuerySpecification;
import org.eclipse.jface.text.IRegion;
import org.eclipse.search.ui.text.Match;

import java.util.ArrayList;
import java.util.List;

/**
 * Test cases for the {@link JavaQueryParticipant} class.
 */
public class JavaQueryParticipantTest extends AbstractGWTPluginTestCase {
    // NOTE: This test is disabled in the pom.xml file.
    // See https://code.google.com/p/google-plugin-for-eclipse/issues/detail?id=329 for details.

    private class TestMatch extends Match {
        public TestMatch(IRegion region) {
            // All matches will be inside JSNI method in test class
            super(getJsniMethod(), region.getOffset(), region.getLength());
        }

        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof Match)) {
                return false;
            }

            // We only care about matching the offset/length; we can ignore the
            // container element (see comment in constructor)
            Match other = (Match) obj;
            return (this.getOffset() == other.getOffset() && this.getLength() == other.getLength());
        }

        @Override
        public int hashCode() {
            return 37 * getOffset() + getLength();
        }
    }

    private static final Match[] NO_MATCHES = new Match[0];

    private static final String[] NO_PARAMS = new String[0];

    private static final IJavaSearchScope WORKSPACE_SCOPE = SearchEngine.createWorkspaceScope();

    private static QuerySpecification createQuery(IJavaElement element) {
        return new ElementQuerySpecification(element, IJavaSearchConstants.REFERENCES, WORKSPACE_SCOPE, "");
    }

    private static QuerySpecification createQuery(String pattern, int searchFor) {
        return new PatternQuerySpecification(pattern, searchFor, false, IJavaSearchConstants.REFERENCES,
                WORKSPACE_SCOPE, "");
    }

    /**
     * Cached references to our test classes.
     */
    private TestClass class1, class2;

    /**
     * Our custom GWT search participant.
     */
    private final JavaQueryParticipant gwtSearchEngine = new JavaQueryParticipant();

    public void testElementSearch() throws CoreException {
        IType cu1Type = getTestType1();
        IJavaElement element;

        // Search for type references
        element = cu1Type;
        Match[] expected = new Match[] { createWindowsTestMatch(665, 41), createWindowsTestMatch(735, 41),
                createWindowsTestMatch(840, 41), createWindowsTestMatch(947, 41), createWindowsTestMatch(1125, 41),
                createWindowsTestMatch(1207, 41), createWindowsTestMatch(1297, 41),
                createWindowsTestMatch(1419, 41), createWindowsTestMatch(1545, 41),
                createWindowsTestMatch(1619, 41) };
        assertSearchMatches(expected, createQuery(element));

        // Search for field references
        element = cu1Type.getField("keith");
        assertSearchMatch(createWindowsTestMatch(990, 5), createQuery(element));

        // Search for method references
        element = cu1Type.getMethod("getNumber", NO_PARAMS);
        assertSearchMatch(createWindowsTestMatch(1588, 9), createQuery(element));

        // Search for constructor references
        element = cu1Type.getType("InnerSub").getMethod("InnerSub", new String[] { "QString;" });
        assertSearchMatch(createWindowsTestMatch(892, 3), createQuery(element));

        // Search for package references (unsupported)
        element = cu1Type.getPackageFragment();
        assertSearchMatches(NO_MATCHES, createQuery(element));
    }

    public void testGetUIParticipant() {
        assertNull(new JavaQueryParticipant().getUIParticipant());
    }

    public void testInheritedMemberSearch() throws CoreException {
        IJavaElement getName = getTestType1().getType("Inner").getMethod("getName", NO_PARAMS);
        assertSearchMatch(createWindowsTestMatch(1471, 7), createQuery(getName));
    }

    public void testLimitTo() throws CoreException {
        IJavaElement element = getTestType1().getField("keith");
        QuerySpecification query;

        // Limit to: references
        query = new ElementQuerySpecification(element, IJavaSearchConstants.REFERENCES, WORKSPACE_SCOPE, "");
        assertSearchMatch(createWindowsTestMatch(990, 5), query);

        // Limit to: all occurrences (declaration and all references, although in
        // this case we're only using our search engine so we'll only have refs)
        query = new ElementQuerySpecification(element, IJavaSearchConstants.ALL_OCCURRENCES, WORKSPACE_SCOPE, "");
        assertSearchMatch(createWindowsTestMatch(990, 5), query);

        // Limit to: read accesses (we don't differentiate between read/write
        // accesses, so this returns all references)
        query = new ElementQuerySpecification(element, IJavaSearchConstants.READ_ACCESSES, WORKSPACE_SCOPE, "");
        assertSearchMatch(createWindowsTestMatch(990, 5), query);

        // Limit to: write accesses (we don't differentiate between read/write
        // accesses, so this returns all references)
        query = new ElementQuerySpecification(element, IJavaSearchConstants.WRITE_ACCESSES, WORKSPACE_SCOPE, "");
        assertSearchMatch(createWindowsTestMatch(990, 5), query);

        // Limit to: declarations (unsupported)
        query = new ElementQuerySpecification(element, IJavaSearchConstants.DECLARATIONS, WORKSPACE_SCOPE, "");
        assertSearchMatches(NO_MATCHES, query);

        // Limit to: implementors (unsupported)
        query = new ElementQuerySpecification(element, IJavaSearchConstants.IMPLEMENTORS, WORKSPACE_SCOPE, "");
        assertSearchMatches(NO_MATCHES, query);
    }

    public void testOverloadedMethodSearch() throws CoreException {
        // Find the overload with one int parameter
        IJavaElement getNumberIntParam = getTestType1().getMethod("getNumber", new String[] { "I" });
        assertSearchMatch(createWindowsTestMatch(1662, 9), createQuery(getNumberIntParam));

        // Find the overload with no parameters
        IJavaElement getNumberNoParams = getTestType1().getMethod("getNumber", NO_PARAMS);
        assertSearchMatch(createWindowsTestMatch(1588, 9), createQuery(getNumberNoParams));
    }

    public void testParamTypeSearch() throws CoreException {
        // Search for JSNI reference param type
        Match[] expected = new Match[] { createWindowsTestMatch(789, 16), createWindowsTestMatch(897, 16) };
        assertSearchMatches(expected, createQuery("java.lang.String", IJavaSearchConstants.TYPE));
    }

    public void testPatternSearch() throws CoreException {
        Match[] expected;

        // Search for type references by simple name
        expected = new Match[] { createWindowsTestMatch(840, 50), createWindowsTestMatch(1207, 50),
                createWindowsTestMatch(1419, 50) };
        assertSearchMatches(expected, createQuery("InnerSub", IJavaSearchConstants.TYPE));

        // Search for type with different casing
        expected = new Match[] { createWindowsTestMatch(840, 50), createWindowsTestMatch(1207, 50),
                createWindowsTestMatch(1419, 50) };
        assertSearchMatches(expected, createQuery("innersub", IJavaSearchConstants.TYPE));

        // Search for type with different casing with case-sensitive enabled
        QuerySpecification query = new PatternQuerySpecification("innersub", IJavaSearchConstants.TYPE, true,
                IJavaSearchConstants.REFERENCES, WORKSPACE_SCOPE, "");
        assertSearchMatches(NO_MATCHES, query);

        // Search for field references
        assertSearchMatch(createWindowsTestMatch(990, 5), createQuery("keith", IJavaSearchConstants.FIELD));

        // Search for method references using * wildcard
        expected = new Match[] { createWindowsTestMatch(1174, 5), createWindowsTestMatch(1259, 5),
                createWindowsTestMatch(1340, 8) };
        assertSearchMatches(expected, createQuery("sayH*", IJavaSearchConstants.METHOD));

        // Search for method references using ? wildcard
        expected = new Match[] { createWindowsTestMatch(1174, 5), createWindowsTestMatch(1259, 5) };
        assertSearchMatches(expected, createQuery("sayH?", IJavaSearchConstants.METHOD));

        // Search for constructor references with qualified type name and parameters
        assertSearchMatch(createWindowsTestMatch(892, 3),
                createQuery("com.hello.client.JavaQueryParticipantTest.InnerSub.InnerSub(String)",
                        IJavaSearchConstants.CONSTRUCTOR));
    }

    public void testScope() throws CoreException {
        IJavaElement element = getType2().getMethod("getNumber", NO_PARAMS);
        QuerySpecification query;
        IJavaSearchScope scope;

        // Scope: workspace
        scope = SearchEngine.createWorkspaceScope();
        query = new ElementQuerySpecification(element, IJavaSearchConstants.REFERENCES, scope, "");
        assertSearchMatch(createWindowsTestMatch(1039, 9), query);

        // Scope: project
        scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { getTestProject() });
        query = new ElementQuerySpecification(element, IJavaSearchConstants.REFERENCES, scope, "");
        assertSearchMatch(createWindowsTestMatch(1039, 9), query);

        // Scope: Compilation unit (the one containing the reference)
        scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { class1.getCompilationUnit() });
        query = new ElementQuerySpecification(element, IJavaSearchConstants.REFERENCES, scope, "");
        assertSearchMatch(createWindowsTestMatch(1039, 9), query);

        // Scope: Compilation unit (the one without any reference)
        scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { class2.getCompilationUnit() });
        query = new ElementQuerySpecification(element, IJavaSearchConstants.REFERENCES, scope, "");
        assertSearchMatches(NO_MATCHES, query);
    }

    @Override
    protected TestClass[] getTestClasses() {
        String[] class1Source = new String[] { "package com.hello.client;", "",
                "public class JavaQueryParticipantTest {", "  private static class Inner {",
                "    private String name;", "", "    public Inner(String name) {", "      this.name = name;",
                "    }", "", "    public void sayHi(int[] args) {", "      System.out.println(name);", "    }", "",
                "    protected String getName() {", "      return name;", "    }", "  }",
                "  private static class InnerSub extends Inner {", "    public InnerSub(String name) {",
                "      super(name);", "    }", "", "    @Override", "    public void sayHi(int[] args) {",
                "      super.sayHi(args);", "    }", "  }", "", "  private static native void jsniMethod()/*-{",
                "   // References to types, fields, methods, and ctors",
                "    var obj = @com.hello.client.JavaQueryParticipantTest::new()();",
                "    var inner = @com.hello.client.JavaQueryParticipantTest$Inner::new(Ljava/lang/String;)('George');",
                "    var innerSub = @com.hello.client.JavaQueryParticipantTest$InnerSub::new(Ljava/lang/String;)('Jetson');",
                "    var val = obj.@com.hello.client.JavaQueryParticipantTest::keith;",
                "    var num = obj.@com.hello.client.A$B::getNumber()();", "    ",
                "    // References to methods that start with 'sayH'",
                "    inner.@com.hello.client.JavaQueryParticipantTest$Inner::sayHi([I)([2,3]);",
                "    innerSub.@com.hello.client.JavaQueryParticipantTest$InnerSub::sayHi([I)([3,4]);",
                "    var msg = obj.@com.hello.client.JavaQueryParticipantTest::sayHello()();", "    ",
                "    // Reference to inherited method",
                "    var name = obj.@com.hello.client.JavaQueryParticipantTest$InnerSub::getName()();", "    ",
                "    // Reference to overloaded method",
                "    num = obj.@com.hello.client.JavaQueryParticipantTest::getNumber()();",
                "    num = obj.@com.hello.client.JavaQueryParticipantTest::getNumber(I)(1);", "  }-*/;", "",
                "  private String keith;", "", "  private String notReferenced;", "", "  private int getNumber() {",
                "    return 777;", "  }", "", "  private int getNumber(int val) {", "    return val;", "  }", "",
                "private int getNumber(long val) {", "  return 1;", "}", "", "  private String sayHello() {",
                "    return \"Hi!\";", "  }", "}" };

        String[] class2Source = new String[] { "package com.hello.client;", "", "public class A {",
                "  public static class B {", "    public static int getNumber() {", "      return 7;", "    }",
                "  }", "}" };

        // Cache references to the added test classes
        class1 = new TestClass(class1Source, "JavaQueryParticipantTest");
        class2 = new TestClass(class2Source, "A");

        return new TestClass[] { class1, class2 };
    }

    @Override
    protected boolean requiresTestProject() {
        return true;
    }

    private void assertSearchMatch(Match expected, QuerySpecification query) throws CoreException {
        assertSearchMatches(new Match[] { expected }, query);
    }

    private void assertSearchMatches(Match[] expected, QuerySpecification query) throws CoreException {
        List<Match> results = search(query);
        assertEquals(expected.length, results.size());

        for (Match expectedMatch : expected) {
            assertTrue(results.contains(expectedMatch));
        }
    }

    private TestMatch createWindowsTestMatch(int offset, int length) {
        return new TestMatch(RegionConverter.convertWindowsRegion(offset, length, class1.getContents()));
    }

    private IMethod getJsniMethod() {
        return getTestType1().getMethod("jsniMethod", NO_PARAMS);
    }

    private IType getTestType1() {
        return class1.getCompilationUnit().getType("JavaQueryParticipantTest");
    }

    private IType getType2() {
        return class2.getCompilationUnit().getType("A").getType("B");
    }

    private List<Match> search(QuerySpecification query) throws CoreException {
        final List<Match> matches = new ArrayList<Match>();

        ISearchRequestor requestor = new ISearchRequestor() {
            @Override
            public void reportMatch(Match match) {
                matches.add(match);
            }
        };

        gwtSearchEngine.search(requestor, query, new NullProgressMonitor());
        return matches;
    }

}