blob: 5deabbd30fd80d8050fd0ab99f8a1b5d0700d455 [file] [log] [blame]
package com.intellij.navigation
import com.intellij.ide.util.gotoByName.ChooseByNameBase
import com.intellij.ide.util.gotoByName.ChooseByNameModel
import com.intellij.ide.util.gotoByName.ChooseByNamePopup
import com.intellij.ide.util.gotoByName.GotoClassModel2
import com.intellij.ide.util.gotoByName.GotoFileModel
import com.intellij.ide.util.gotoByName.GotoSymbolModel2
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.util.Disposer
import com.intellij.psi.PsiElement
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import com.intellij.util.Consumer
import com.intellij.util.concurrency.Semaphore
/**
* @author peter
*/
class ChooseByNameTest extends LightCodeInsightFixtureTestCase {
ChooseByNamePopup myPopup
@Override
protected void tearDown() throws Exception {
myPopup = null
super.tearDown()
}
public void "test goto class order by matching degree"() {
def startMatch = myFixture.addClass("class UiUtil {}")
def wordSkipMatch = myFixture.addClass("class UiAbstractUtil {}")
def camelMatch = myFixture.addClass("class UberInstructionUxTopicInterface {}")
def middleMatch = myFixture.addClass("class BaseUiUtil {}")
def elements = getPopupElements(new GotoClassModel2(project), "uiuti")
assert elements == [startMatch, wordSkipMatch, camelMatch, ChooseByNameBase.NON_PREFIX_SEPARATOR, middleMatch]
}
public void "test annotation syntax"() {
def match = myFixture.addClass("@interface Anno1 {}")
myFixture.addClass("class Anno2 {}")
def elements = getPopupElements(new GotoClassModel2(project), "@Anno")
assert elements == [match]
}
public void "test no result for empty patterns"() {
myFixture.addClass("@interface Anno1 {}")
myFixture.addClass("class Anno2 {}")
def popup = createPopup(new GotoClassModel2(project))
assert getPopupElements(popup, "") == []
popup.close(false)
popup = createPopup(new GotoClassModel2(project))
assert getPopupElements(popup, "@") == []
popup.close(false)
popup = createPopup(new GotoFileModel(project))
assert getPopupElements(popup, "foo/") == []
popup.close(false)
}
public void "test filter overridden methods from goto symbol"() {
def intf = myFixture.addClass("""
class Intf {
void xxx1() {}
void xxx2() {}
}""")
def impl = myFixture.addClass("""
class Impl extends Intf {
void xxx1() {}
void xxx3() {}
}
""")
def elements = getPopupElements(new GotoSymbolModel2(project), "xxx")
assert intf.findMethodsByName('xxx1', false)[0] in elements
assert intf.findMethodsByName('xxx2', false)[0] in elements
assert impl.findMethodsByName('xxx3', false)[0] in elements
assert !(impl.findMethodsByName('xxx1', false)[0] in elements)
}
public void "test disprefer underscore"() {
def intf = myFixture.addClass("""
class Intf {
void _xxx1() {}
void xxx2() {}
}""")
def elements = getPopupElements(new GotoSymbolModel2(project), "xxx")
assert elements == [intf.findMethodsByName('xxx2', false), ChooseByNameBase.NON_PREFIX_SEPARATOR, intf.findMethodsByName('_xxx1', false)]
}
public void "test prefer exact extension matches"() {
def m = myFixture.addFileToProject("relaunch.m", "")
def mod = myFixture.addFileToProject("reference.mod", "")
def elements = getPopupElements(new GotoFileModel(project), "re*.m")
assert elements == [m, mod]
}
public void "test prefer better path matches"() {
def fooIndex = myFixture.addFileToProject("foo/index.html", "foo")
def fooBarIndex = myFixture.addFileToProject("foo/bar/index.html", "foo bar")
def barFooIndex = myFixture.addFileToProject("bar/foo/index.html", "bar foo")
def elements = getPopupElements(new GotoFileModel(project), "foo/index")
assert elements == [fooIndex, barFooIndex, fooBarIndex]
}
public void "test sort same-named items by path"() {
def files = (30..10).collect { i -> myFixture.addFileToProject("foo$i/index.html", "foo$i") }.reverse()
def elements = getPopupElements(new GotoFileModel(project), "index")
assert elements == files
}
public void "test middle matching for directories"() {
def fooIndex = myFixture.addFileToProject("foo/index.html", "foo")
def ooIndex = myFixture.addFileToProject("oo/index.html", "oo")
def fooBarIndex = myFixture.addFileToProject("foo/bar/index.html", "foo bar")
def elements = getPopupElements(new GotoFileModel(project), "oo/index")
assert elements == [ooIndex, fooIndex, fooBarIndex]
}
public void "test prefer files from current directory"() {
def fooIndex = myFixture.addFileToProject("foo/index.html", "foo")
def barIndex = myFixture.addFileToProject("bar/index.html", "bar")
def fooContext = myFixture.addFileToProject("foo/context.html", "")
def barContext = myFixture.addFileToProject("bar/context.html", "")
def popup = createPopup(new GotoFileModel(project), fooContext)
assert getPopupElements(popup, "index") == [fooIndex, barIndex]
popup.close(false)
popup = createPopup(new GotoFileModel(project), barContext)
assert getPopupElements(popup, "index") == [barIndex, fooIndex]
}
public void "test goto file can go to dir"() {
def fooIndex = myFixture.addFileToProject("foo/index.html", "foo")
def barIndex = myFixture.addFileToProject("bar.txt/bar.txt", "foo")
def popup = createPopup(new GotoFileModel(project), fooIndex)
assert getPopupElements(popup, "foo/") == [fooIndex.containingDirectory]
assert getPopupElements(popup, "foo\\") == [fooIndex.containingDirectory]
assert getPopupElements(popup, "/foo") == [fooIndex.containingDirectory]
assert getPopupElements(popup, "\\foo") == [fooIndex.containingDirectory]
assert getPopupElements(popup, "foo") == []
assert getPopupElements(popup, "/index.html") == [fooIndex]
assert getPopupElements(popup, "\\index.html") == [fooIndex]
assert getPopupElements(popup, "index.html/") == [fooIndex]
assert getPopupElements(popup, "index.html\\") == [fooIndex]
assert getPopupElements(popup, "bar.txt/") == [barIndex.containingDirectory]
assert getPopupElements(popup, "bar.txt\\") == [barIndex.containingDirectory]
assert getPopupElements(popup, "/bar.txt") == [barIndex.containingDirectory]
assert getPopupElements(popup, "\\bar.txt") == [barIndex.containingDirectory]
assert getPopupElements(popup, "bar.txt") == [barIndex]
popup.close(false)
}
public void "test find method by qualified name"() {
def method = myFixture.addClass("package foo.bar; class Goo { void zzzZzz() {} }").methods[0]
assert getPopupElements(new GotoSymbolModel2(project), 'zzzZzz') == [method]
assert getPopupElements(new GotoSymbolModel2(project), 'goo.zzzZzz') == [method]
assert getPopupElements(new GotoSymbolModel2(project), 'foo.bar.goo.zzzZzz') == [method]
assert getPopupElements(new GotoSymbolModel2(project), 'foo.zzzZzz') == [method]
assert getPopupElements(new GotoSymbolModel2(project), 'bar.zzzZzz') == [method]
assert getPopupElements(new GotoSymbolModel2(project), 'bar.goo.zzzZzz') == [method]
}
public void "test line and column suffix"() {
def c = myFixture.addClass("package foo; class Bar {}")
assert getPopupElements(new GotoClassModel2(project), 'Bar') == [c]
assert getPopupElements(new GotoClassModel2(project), 'Bar:2') == [c]
assert getPopupElements(new GotoClassModel2(project), 'Bar:2:3') == [c]
assert getPopupElements(new GotoClassModel2(project), 'Bar:[2:3]') == [c]
assert getPopupElements(new GotoClassModel2(project), 'Bar:[2,3]') == [c]
}
private List<Object> getPopupElements(ChooseByNameModel model, String text) {
return getPopupElements(createPopup(model), text)
}
private static ArrayList<String> getPopupElements(ChooseByNamePopup popup, String text) {
List<Object> elements = ['empty']
def semaphore = new Semaphore()
semaphore.down()
popup.scheduleCalcElements(text, false, false, ModalityState.NON_MODAL, { set ->
elements = set as List
semaphore.up()
} as Consumer<Set<?>>)
if (!semaphore.waitFor(10000)) {
printThreadDump()
fail()
}
return elements
}
private ChooseByNamePopup createPopup(ChooseByNameModel model, PsiElement context = null) {
if (myPopup) {
myPopup.close(false)
}
def popup = myPopup = ChooseByNamePopup.createPopup(project, model, (PsiElement)context, "")
Disposer.register(testRootDisposable, { popup.close(false) } as Disposable)
popup
}
@Override
protected boolean runInDispatchThread() {
return false
}
@Override
protected void invokeTestRunnable(Runnable runnable) throws Exception {
runnable.run()
}
}