Recent Tests: show only java tests urls

This commit is contained in:
Yaroslav Lepenkin
2016-02-11 22:50:00 +03:00
parent 8d12c7ba93
commit e012c6811c
6 changed files with 218 additions and 175 deletions
@@ -16,29 +16,21 @@
package com.intellij.testIntegration;
import com.intellij.execution.Location;
import com.intellij.execution.testframework.JavaTestLocator;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public interface RecentTestRunner {
enum Mode { RUN, DEBUG }
enum Mode {
RUN,
DEBUG
}
void setMode(Mode mode);
void run(Location location);
Location getLocation(String url);
boolean isSuite(String url);
}
class RecentTestRunnerImpl implements RecentTestRunner {
@@ -46,12 +38,7 @@ class RecentTestRunnerImpl implements RecentTestRunner {
private static AnAction DEBUG = ActionManager.getInstance().getAction("DebugClass");
protected AnAction myCurrentAction = RUN;
private final Project myProject;
public RecentTestRunnerImpl(Project project) {
myProject = project;
}
public void setMode(Mode mode) {
switch (mode) {
case RUN:
@@ -62,26 +49,6 @@ class RecentTestRunnerImpl implements RecentTestRunner {
break;
}
}
public Location getLocation(String url) {
String protocol = VirtualFileManager.extractProtocol(url);
String path = VirtualFileManager.extractPath(url);
if (protocol != null) {
List<Location> locations = JavaTestLocator.INSTANCE.getLocation(protocol, path, myProject, GlobalSearchScope.allScope(myProject));
if (!locations.isEmpty()) {
return locations.get(0);
}
}
return null;
}
@Override
public boolean isSuite(String url) {
String protocol = VirtualFileManager.extractProtocol(url);
return JavaTestLocator.SUITE_PROTOCOL.equals(protocol);
}
public void run(final Location location) {
DataContext data = new DataContext() {
@@ -15,6 +15,7 @@
*/
package com.intellij.testIntegration;
import com.intellij.execution.TestStateStorage;
import com.intellij.execution.testframework.sm.runner.states.TestStateInfo;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFileManager;
@@ -27,7 +28,40 @@ import java.util.*;
import static com.intellij.execution.testframework.sm.runner.states.TestStateInfo.Magnitude.*;
import static com.intellij.testIntegration.TestInfo.select;
public class RecentTestsData {
public class RecentTestsListProvider {
private final Map<String, TestStateStorage.Record> myRecords;
public RecentTestsListProvider(Map<String, TestStateStorage.Record> records) {
myRecords = records;
}
public List<String> getUrlsToShowFromHistory() {
if (myRecords == null) return ContainerUtil.emptyList();
RecentTestsData data = new RecentTestsData();
for (Map.Entry<String, TestStateStorage.Record> entry : myRecords.entrySet()) {
String url = entry.getKey();
TestStateStorage.Record record = entry.getValue();
if (TestLocator.canLocate(url)) {
data.addTest(url, getMagnitude(record.magnitude), record.date);
}
}
return data.getSortedTestsList();
}
private static TestStateInfo.Magnitude getMagnitude(int magnitude) {
for (TestStateInfo.Magnitude m : values()) {
if (m.getValue() == magnitude) {
return m;
}
}
return null;
}
}
class RecentTestsData {
private static Comparator<TestInfo> BY_PATH_COMPARATOR = new Comparator<TestInfo>() {
@Override
public int compare(TestInfo o1, TestInfo o2) {
@@ -50,18 +84,13 @@ public class RecentTestsData {
return -o1.getRunDate().compareTo(o2.getRunDate());
}
};
private final RecentTestRunner myRunner;
private final Map<String, SuiteInfo> mySuites = ContainerUtil.newHashMap();
private List<TestInfo> myTestsWithoutSuites = ContainerUtil.newArrayList();
public RecentTestsData(RecentTestRunner runner) {
myRunner = runner;
}
public void addTest(String url, TestStateInfo.Magnitude magnitude, Date runDate) {
if (myRunner.isSuite(url)) {
if (TestLocator.isSuite(url)) {
mySuites.put(url, new SuiteInfo(url, magnitude, runDate));
return;
}
@@ -91,7 +120,7 @@ public class RecentTestsData {
return null;
}
public List<String> calculateTestList() {
public List<String> getSortedTestsList() {
distributeUnmatchedTests();
List<String> result = ContainerUtil.newArrayList();
fillWithTests(result, ERROR_INDEX, FAILED_INDEX);
@@ -288,18 +317,4 @@ class TestInfo {
}
});
}
public static <T extends TestInfo> List<T> selectNot(Collection<T> infos, final TestStateInfo.Magnitude... magnitudes) {
return ContainerUtil.filter(infos, new Condition<T>() {
@Override
public boolean value(T t) {
for (TestStateInfo.Magnitude magnitude : magnitudes) {
if (t.getMagnitude() == magnitude) {
return false;
}
}
return true;
}
});
}
}
@@ -16,9 +16,6 @@
package com.intellij.testIntegration;
import com.intellij.execution.Location;
import com.intellij.execution.TestStateStorage;
import com.intellij.execution.testframework.TestIconMapper;
import com.intellij.execution.testframework.sm.runner.states.TestStateInfo;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import com.intellij.openapi.vfs.VirtualFileManager;
@@ -29,34 +26,20 @@ import java.util.List;
import java.util.Map;
public class SelectTestStep extends BaseListPopupStep<String> {
private final Map<String, TestStateStorage.Record> myRecords;
private final RecentTestRunner myRunner;
private final TestLocator myTestLocator;
private final Map<String, Icon> myIcons;
public SelectTestStep(Map<String, TestStateStorage.Record> records, RecentTestRunner runner) {
super("Debug Recent Tests", getUrls(records, runner));
public SelectTestStep(List<String> urls, Map<String, Icon> icons, RecentTestRunner runner, TestLocator locator) {
super("Debug Recent Tests", urls);
myRunner = runner;
myRecords = records;
myIcons = icons;
myTestLocator = locator;
}
private static List<String> getUrls(Map<String, TestStateStorage.Record> records, RecentTestRunner runner) {
RecentTestsData data = new RecentTestsData(runner);
for (Map.Entry<String, TestStateStorage.Record> entry : records.entrySet()) {
String url = entry.getKey();
TestStateStorage.Record record = entry.getValue();
data.addTest(url, getMagnitude(record.magnitude), record.date);
}
return data.calculateTestList();
}
private static TestStateInfo.Magnitude getMagnitude(int magnitude) {
for (TestStateInfo.Magnitude m : TestStateInfo.Magnitude.values()) {
if (m.getValue() == magnitude) {
return m;
}
}
return null;
@Override
public Icon getIconFor(String value) {
return myIcons.get(value);
}
@NotNull
@@ -69,17 +52,10 @@ public class SelectTestStep extends BaseListPopupStep<String> {
public boolean isSpeedSearchEnabled() {
return true;
}
@Override
public Icon getIconFor(String value) {
TestStateStorage.Record record = myRecords.get(value);
TestStateInfo.Magnitude magnitude = TestIconMapper.getMagnitude(record.magnitude);
return TestIconMapper.getIcon(magnitude);
}
@Override
public PopupStep onChosen(String url, boolean finalChoice) {
Location location = myRunner.getLocation(url);
Location location = myTestLocator.getLocation(url);
myRunner.run(location);
return null;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,21 +17,27 @@ package com.intellij.testIntegration;
import com.intellij.execution.Location;
import com.intellij.execution.TestStateStorage;
import com.intellij.execution.testframework.TestIconMapper;
import com.intellij.execution.testframework.sm.runner.states.TestStateInfo;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.keymap.MacKeymapUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.ListPopupStep;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.popup.list.ListPopupImpl;
import com.intellij.util.Function;
import com.intellij.util.PsiNavigateUtil;
import com.intellij.util.Time;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class ShowRecentTests extends AnAction {
@@ -51,21 +57,41 @@ public class ShowRecentTests extends AnAction {
final Project project = e.getProject();
if (project == null) return;
Map<String, TestStateStorage.Record> records = TestStateStorage.getInstance(project).getRecentTests(TEST_LIMIT, getSinceDate());
RecentTestRunner testRunner = new RecentTestRunnerImpl(project);
final TestStateStorage testStorage = TestStateStorage.getInstance(project);
final TestLocator testLocator = new TestLocator(project);
final RecentTestRunnerImpl testRunner = new RecentTestRunnerImpl();
SelectTestStep selectStepTest = new SelectTestStep(records, testRunner);
RecentTestsListPopup popup = new RecentTestsListPopup(selectStepTest, testRunner);
final Map<String, TestStateStorage.Record> records = testStorage.getRecentTests(TEST_LIMIT, getSinceDate());
RecentTestsListProvider listProvider = new RecentTestsListProvider(records);
List<String> urls = listProvider.getUrlsToShowFromHistory();
Map<String, Icon> icons = ContainerUtil.map2Map(urls, new Function<String, Pair<String, Icon>>() {
@Override
public Pair<String, Icon> fun(String url) {
return Pair.create(url, getIconFor(url, records));
}
});
SelectTestStep selectStepTest = new SelectTestStep(urls, icons, testRunner, testLocator);
RecentTestsListPopup popup = new RecentTestsListPopup(selectStepTest, testRunner, testLocator);
popup.showCenteredInCurrentWindow(project);
}
private static Icon getIconFor(String value, Map<String, TestStateStorage.Record> records) {
TestStateStorage.Record record = records.get(value);
TestStateInfo.Magnitude magnitude = TestIconMapper.getMagnitude(record.magnitude);
return TestIconMapper.getIcon(magnitude);
}
}
class RecentTestsListPopup extends ListPopupImpl {
private final RecentTestRunner myTestRunner;
private final TestLocator myLocator;
public RecentTestsListPopup(ListPopupStep<String> popupStep, RecentTestRunner testRunner) {
public RecentTestsListPopup(ListPopupStep<String> popupStep, RecentTestRunner testRunner, TestLocator locator) {
super(popupStep);
myTestRunner = testRunner;
myLocator = locator;
shiftReleased();
registerActions(this);
@@ -97,7 +123,7 @@ class RecentTestsListPopup extends ListPopupImpl {
public void actionPerformed(ActionEvent e) {
Object[] values = getSelectedValues();
if (values.length == 1) {
Location location = myTestRunner.getLocation(values[0].toString());
Location location = myLocator.getLocation(values[0].toString());
if (location != null) {
cancel();
PsiNavigateUtil.navigate(location.getPsiElement());
@@ -0,0 +1,65 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.intellij.testIntegration;
import com.intellij.execution.Location;
import com.intellij.execution.testframework.JavaTestLocator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.psi.search.GlobalSearchScope;
import java.util.List;
public class TestLocator {
private final Project myProject;
public TestLocator(Project project) {
myProject = project;
}
public Location getLocation(String url) {
return getLocation(url, myProject);
}
public static Location getLocation(String url, Project project) {
String protocol = VirtualFileManager.extractProtocol(url);
String path = VirtualFileManager.extractPath(url);
if (protocol != null) {
List<Location> locations = JavaTestLocator.INSTANCE.getLocation(protocol, path, project, GlobalSearchScope.allScope(project));
if (!locations.isEmpty()) {
return locations.get(0);
}
}
return null;
}
public static boolean canLocate(String url) {
return isSuite(url) || isTest(url);
}
public static boolean isSuite(String url) {
String protocol = VirtualFileManager.extractProtocol(url);
return JavaTestLocator.SUITE_PROTOCOL.equals(protocol);
}
public static boolean isTest(String url) {
String protocol = VirtualFileManager.extractProtocol(url);
return JavaTestLocator.TEST_PROTOCOL.equals(protocol);
}
}
@@ -17,14 +17,14 @@ package com.intellij.testIntergration
import com.intellij.execution.Location
import com.intellij.execution.TestStateStorage
import com.intellij.execution.testframework.JavaTestLocator
import com.intellij.execution.testframework.sm.runner.states.TestStateInfo
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.testFramework.LightIdeaTestCase
import com.intellij.testIntegration.RecentTestRunner
import com.intellij.testIntegration.RecentTestsListProvider
import com.intellij.testIntegration.SelectTestStep
import com.intellij.testIntegration.TestLocator
import org.assertj.core.api.Assertions.assertThat
import org.junit.Ignore
import org.junit.Test
import org.mockito.Matchers
import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
@@ -33,8 +33,9 @@ import java.util.*
fun passed(date: Date) = TestStateStorage.Record(TestStateInfo.Magnitude.PASSED_INDEX.value, date)
fun failed(date: Date) = TestStateStorage.Record(TestStateInfo.Magnitude.FAILED_INDEX.value, date)
class RecentTestsStepTest {
val runner = createRunner()
class RecentTestsStepTest: LightIdeaTestCase() {
val runner = mock(RecentTestRunner::class.java)
val testLocator = createLocator()
val passed = passed(Date(0))
val failed = failed(Date(0))
@@ -62,24 +63,32 @@ class RecentTestsStepTest {
addTest(name, magnitude, date)
}
fun addJsSuite(name: String, pass: Boolean, date: Date = Date(0)) {
val magnitude = if (pass) TestStateInfo.Magnitude.PASSED_INDEX else TestStateInfo.Magnitude.FAILED_INDEX
val record = TestStateStorage.Record(magnitude.value, date)
map.put("js:suite://$name", record)
}
fun getMap() = map
fun removeUrl(url: String) {
map.remove(url)
}
}
@Test
fun `show sorted by date`() {
fun `test show sorted by date`() {
val storage = TestStorage()
storage.addSuite("ASTest", true, Date(1000))
storage.addSuite("JSTest", true, Date(1200))
val step = SelectTestStep(storage.getMap(), runner)
val values = step.values.map { VirtualFileManager.extractPath(it) }
val sortedUrlList = getSortedList(storage.getMap())
val values = sortedUrlList.map { VirtualFileManager.extractPath(it) }
assertThat(values).isEqualTo(listOf("JSTest", "ASTest"))
}
@Test
fun `show tests sorted by date`() {
fun `test show tests sorted by date`() {
val storage = TestStorage()
storage.addSuite("ASTest", false, Date(0))
@@ -89,27 +98,25 @@ class RecentTestsStepTest {
storage.addTest("ASTest.cccc", false, Date(20000))
storage.addTest("ASTest.bbbb", false, Date(30000))
val step = SelectTestStep(storage.getMap(), runner)
val values = step.values.map { VirtualFileManager.extractPath(it) }
val sortedUrlList = getSortedList(storage.getMap())
val values = sortedUrlList.map { VirtualFileManager.extractPath(it) }
assertThat(values).isEqualTo(listOf("ASTest", "ASTest.bbbb", "ASTest.cccc", "ASTest.aaaa"))
}
@Test
fun `show ignored`() {
fun `test show ignored`() {
val storage = TestStorage()
storage.addSuite("ASTest", TestStateInfo.Magnitude.IGNORED_INDEX)
storage.addTest("ASTest.ignored", TestStateInfo.Magnitude.IGNORED_INDEX)
storage.addTest("ASTest.passed", pass = true)
val step = SelectTestStep(storage.getMap(), runner)
val values = step.values.map { VirtualFileManager.extractPath(it) }
val sortedUrlList = getSortedList(storage.getMap())
val values = sortedUrlList.map { VirtualFileManager.extractPath(it) }
assertThat(values).isEqualTo(listOf("ASTest"))
}
@Test
fun `when suite passed - show only suite`() {
fun `test when suite passed - show only suite`() {
val map: MutableMap<String, TestStateStorage.Record> = hashMapOf()
map.put("java:suite://JavaFormatterSuperDuperTest", passed)
@@ -121,19 +128,34 @@ class RecentTestsStepTest {
map.put("java:test://Test.textQQQ", passed)
map.put("java:test://JavaFormatterSuperDuperTest.testUnconditionalAlignmentErrorneous", passed)
val step = SelectTestStep(map, runner)
val expected = listOf(
"java:suite://JavaFormatterSuperDuperTest",
"java:suite://Test"
)
assertThat(step.values).isEqualTo(expected)
val list = getSortedList(map)
assertThat(list).isEqualTo(expected)
}
private fun getSortedList(map: MutableMap<String, TestStateStorage.Record>): List<String> {
val provider = RecentTestsListProvider(map)
return provider.urlsToShowFromHistory
}
@Test
fun `show failed first`() {
fun `test show only java tests`() {
val storage = TestStorage()
storage.addSuite("JavaTest1", true)
storage.addSuite("JavaTest2", true)
storage.addJsSuite("JsSuite1", true)
storage.addJsSuite("JsSuite2", true)
storage.addJsSuite("JsSuite3", true)
val values = getSortedList(storage.getMap())
assertThat(values.map { VirtualFileManager.extractPath(it) }).isEqualTo(listOf("JavaTest1", "JavaTest2"))
}
fun `test show failed first`() {
val map: MutableMap<String, TestStateStorage.Record> = hashMapOf()
map.put("java:suite://JavaFormatterSuperDuperTest", failed)
@@ -148,7 +170,7 @@ class RecentTestsStepTest {
map.put("java:test://Test.textQQQ", passed)
map.put("java:test://JavaFormatterSuperDuperTest.testUnconditionalAlignmentErrorneous", passed)
val step = SelectTestStep(map, runner)
val values = getSortedList(map)
val expected = listOf(
"java:test://JavaFormatterFailed.fail",
@@ -158,11 +180,10 @@ class RecentTestsStepTest {
"java:suite://Test"
)
assertThat(step.values).isEqualTo(expected)
assertThat(values).isEqualTo(expected)
}
@Test
fun `if failed more than 2 tests show suite first`() {
fun `test if failed more than 2 tests show suite first`() {
val storage = TestStorage()
storage.addSuite("ASTest", false)
storage.addTest("ASTest.failed1", false, Date(3000))
@@ -170,8 +191,8 @@ class RecentTestsStepTest {
storage.addTest("ASTest.failed3", false, Date(1000))
storage.addTest("ASTest.passed1", true)
val step = SelectTestStep(storage.getMap(), runner)
val values = step.values.map { VirtualFileManager.extractPath(it) }
val sortedUrlList = getSortedList(storage.getMap())
val values = sortedUrlList.map { VirtualFileManager.extractPath(it) }
assertThat(values).isEqualTo(listOf(
"ASTest",
@@ -180,9 +201,8 @@ class RecentTestsStepTest {
"ASTest.failed3"
))
}
@Test
fun `if failed less than 3 tests, show tests first`() {
fun `test if failed less than 3 tests, show tests first`() {
val storage = TestStorage()
storage.addSuite("ASTest", false)
@@ -190,8 +210,8 @@ class RecentTestsStepTest {
storage.addTest("ASTest.failed2", false, Date(2000))
storage.addTest("ASTest.passed1", true)
val step = SelectTestStep(storage.getMap(), runner)
val values = step.values.map { VirtualFileManager.extractPath(it) }
val sortedUrlList = getSortedList(storage.getMap())
val values = sortedUrlList.map { VirtualFileManager.extractPath(it) }
assertThat(values).isEqualTo(listOf(
"ASTest.failed1",
@@ -199,9 +219,8 @@ class RecentTestsStepTest {
"ASTest"
))
}
@Test
fun `if all failed show only suite`() {
fun `test if all failed show only suite`() {
val storage = TestStorage()
storage.addSuite("ASTest", false)
@@ -210,48 +229,23 @@ class RecentTestsStepTest {
storage.addTest("ASTest.failed3", false)
storage.addTest("ASTest.failed4", false)
val step = SelectTestStep(storage.getMap(), runner)
val values = step.values.map { VirtualFileManager.extractPath(it) }
val sortedUrlList = getSortedList(storage.getMap())
val values = sortedUrlList.map { VirtualFileManager.extractPath(it) }
assertThat(values).isEqualTo(listOf("ASTest"))
}
@Ignore
@Test
fun `do not show urls without location`() {
val storage = TestStorage()
storage.addSuite("ASTest", true)
storage.addSuite("BSTest", false)
storage.addTest("BSTest.fff", false)
storage.addTest("BSTest.ppp", true)
storage.addTest("<default package>", false)
storage.addSuite("<default package>", false)
val step = SelectTestStep(storage.getMap(), runner)
val values = step.values.map { VirtualFileManager.extractPath(it) }
assertThat(values).isEqualTo(listOf("BSTest", "BSTest.fff", "ASTest"))
}
private fun createRunner(): RecentTestRunner {
val runner = mock(RecentTestRunner::class.java)
`when`(runner.isSuite(Matchers.anyString())).thenAnswer {
val url = it.arguments[0] as String
val protocol = VirtualFileManager.extractProtocol(url)
JavaTestLocator.SUITE_PROTOCOL.startsWith(protocol.toString())
}
`when`(runner.getLocation(Matchers.anyString())).thenAnswer {
private fun createLocator(): TestLocator {
val locator = mock(TestLocator::class.java)
`when`(locator.getLocation(Matchers.anyString())).thenAnswer {
val url = it.arguments[0] as String
if (url.contains("<")) null else mock(Location::class.java)
}
return runner
return locator
}
@Test
fun `shown value without protocol`() {
val step = SelectTestStep(emptyMap(), runner)
fun `test shown value without protocol`() {
val step = SelectTestStep(emptyList(), emptyMap(), runner, testLocator)
var shownValue = step.getTextFor("java:suite://JavaFormatterSuperDuperTest")
assertThat(shownValue).isEqualTo("JavaFormatterSuperDuperTest")