[Build] Add integration tests for Build tw presentation of JPS builds IDEA-206108 IJBTS-71

GitOrigin-RevId: deb31f36337ad3ef625deebd739fa774d5c4add9
This commit is contained in:
Vladislav.Soroka
2020-03-19 11:14:52 +03:00
committed by intellij-monorepo-bot
parent 3db5c6e475
commit b2ec51271d
14 changed files with 592 additions and 190 deletions

View File

@@ -119,11 +119,11 @@ public class BuildViewServiceImpl implements BuildViewService {
public void onEnd(Object sessionId, ExitStatus exitStatus, long endBuildStamp) {
String message;
if (exitStatus == ExitStatus.ERRORS) {
message = JavaCompilerBundle.message("compiler.build.messages.failed", wordsToBeginFromLowerCase(myContentName));
message = BuildBundle.message("build.messages.failed", wordsToBeginFromLowerCase(myContentName));
myBuildProgress.fail(endBuildStamp, message);
}
else if (exitStatus == ExitStatus.CANCELLED) {
message = JavaCompilerBundle.message("compiler.build.messages.cancelled", wordsToBeginFromLowerCase(myContentName));
message = BuildBundle.message("build.messages.cancelled", wordsToBeginFromLowerCase(myContentName));
myBuildProgress.cancel(endBuildStamp, message);
}
else {
@@ -136,7 +136,8 @@ public class BuildViewServiceImpl implements BuildViewService {
myBuildProgress.output(JavaCompilerBundle.message("compiler.build.messages.classes.check.outdated"), true);
}
}
myBuildProgress.finish(endBuildStamp, isUpToDate);
message = BuildBundle.message("build.messages.finished", wordsToBeginFromLowerCase(myContentName));
myBuildProgress.finish(endBuildStamp, isUpToDate, message);
}
}

View File

@@ -22,8 +22,6 @@ compiler.error.exception=Error: {0}
status.compilation.aborted=Compilation aborted
status.all.up.to.date=All files are up-to-date
compiler.error.failed.to.delete=Failed to delete {0}
compiler.build.messages.failed={0} failed
compiler.build.messages.cancelled={0} cancelled
compiler.build.messages.classes.check.uptodate=Build results are up-to-date for requested compile scope.\nSubsequent incremental build wouldn't do anything.
compiler.build.messages.classes.check.outdated=Build results are outdated for requested compile scope.\nSubsequent incremental build will compile files for changed sources and remove obsolete results of the previous build.
progress.updating.caches=Updating caches...

View File

@@ -0,0 +1,114 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.compiler.progress
import com.intellij.compiler.BaseCompilerTestCase
import com.intellij.openapi.Disposable
import com.intellij.openapi.compiler.CompileStatusNotification
import com.intellij.openapi.module.Module
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.registry.Registry
import com.intellij.testFramework.RunAll
import com.intellij.testFramework.fixtures.BuildViewTestFixture
import com.intellij.util.ThrowableRunnable
class CompilerBuildViewTest : BaseCompilerTestCase() {
private lateinit var buildViewTestFixture: BuildViewTestFixture
private val testDisposable: Disposable = object : Disposable {
override fun dispose() {
}
}
@Throws(Exception::class)
public override fun setUp() {
super.setUp()
buildViewTestFixture = BuildViewTestFixture(project)
buildViewTestFixture.setUp()
val registryValue = Registry.get("ide.jps.use.build.tool.window")
registryValue.setValue(true, testDisposable)
}
public override fun tearDown() {
RunAll()
.append(ThrowableRunnable { if (::buildViewTestFixture.isInitialized) buildViewTestFixture.tearDown() })
.append(ThrowableRunnable { Disposer.dispose(testDisposable) })
.append(ThrowableRunnable { super.tearDown() })
.run()
}
fun `test empty build`() {
make(compilerManager.createProjectCompileScope(myProject))
buildViewTestFixture.assertBuildViewTreeEquals("-\n build finished")
buildViewTestFixture.assertBuildViewSelectedNode("build finished", "", false)
rebuildProject(false)
buildViewTestFixture.assertBuildViewTreeEquals("-\n rebuild finished")
buildViewTestFixture.assertBuildViewSelectedNode("rebuild finished", "", false)
compile(compilerManager.createProjectCompileScope(myProject), true)
buildViewTestFixture.assertBuildViewTreeEquals("-\n recompile finished")
buildViewTestFixture.assertBuildViewSelectedNode("recompile finished", "", false)
}
fun `test successful build`() {
val file = createFile("src/A.java", "public class A {}")
val srcRoot = file.parent
val module = addModule("a", srcRoot)
build(module)
buildViewTestFixture.assertBuildViewTreeEquals("-\n build finished")
rebuildProject()
buildViewTestFixture.assertBuildViewTreeEquals("-\n rebuild finished")
rebuild(module)
buildViewTestFixture.assertBuildViewTreeEquals("-\n recompile finished")
}
fun `test build with compile error`() {
val file = createFile("src/A.java", "public class A a{}foo")
val srcRoot = file.parent
val module = addModule("a", srcRoot)
build(module, true)
buildViewTestFixture.assertBuildViewTreeEquals(
"-\n" +
" -build failed\n" +
" -src/A.java\n" +
" '{' expected\n" +
" reached end of file while parsing"
)
rebuildProject(true)
buildViewTestFixture.assertBuildViewTreeEquals(
"-\n" +
" -rebuild failed\n" +
" -src/A.java\n" +
" '{' expected\n" +
" reached end of file while parsing"
)
rebuild(module, true)
buildViewTestFixture.assertBuildViewTreeEquals(
"-\n" +
" -recompile failed\n" +
" -src/A.java\n" +
" '{' expected\n" +
" reached end of file while parsing"
)
}
private fun build(module: Module, errorsExpected: Boolean = false): CompilationLog? {
val compileScope = compilerManager.createModuleCompileScope(module, false)
return compile(compileScope, false, errorsExpected)
}
private fun rebuild(module: Module, errorsExpected: Boolean = false): CompilationLog? {
val compileScope = compilerManager.createModuleCompileScope(module, false)
return compile(compileScope, true, errorsExpected)
}
private fun rebuildProject(errorsExpected: Boolean = false): CompilationLog? {
return compile(errorsExpected) { compileStatusNotification: CompileStatusNotification? ->
compilerManager.rebuild(compileStatusNotification)
}
}
}

View File

@@ -0,0 +1,7 @@
build.status.finished=finished
build.status.failed=failed
build.status.cancelled=cancelled
build.status.running=running...
build.messages.finished={0} finished
build.messages.failed={0} failed
build.messages.cancelled={0} cancelled

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2000-2013 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.build;
import com.intellij.DynamicBundle;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.PropertyKey;
import java.util.function.Supplier;
public class BuildBundle extends DynamicBundle {
@NonNls private static final String BUNDLE = "messages.BuildBundle";
private static final BuildBundle INSTANCE = new BuildBundle();
private BuildBundle() {
super(BUNDLE);
}
@NotNull
public static String message(@NotNull @PropertyKey(resourceBundle = BUNDLE) String key, Object @NotNull ... params) {
return INSTANCE.getMessage(key, params);
}
@NotNull
public static Supplier<String> messagePointer(@NotNull @PropertyKey(resourceBundle = BUNDLE) String key, Object @NotNull ... params) {
return INSTANCE.getLazyMessage(key, params);
}
}

View File

@@ -152,10 +152,11 @@ public class BuildView extends CompositeView<ExecutionConsole>
Disposer.register(this, runContentDescriptor);
}
}
if (myExecutionConsole != null) {
myExecutionConsole.getComponent(); //create editor to be able to add console editor actions
ExecutionConsole executionConsole = myExecutionConsole;
if (executionConsole != null) {
executionConsole.getComponent(); //create editor to be able to add console editor actions
if (myViewSettingsProvider.isExecutionViewHidden() || !myViewSettingsProvider.isSideBySideView()) {
addViewAndShowIfNeeded(myExecutionConsole, CONSOLE_VIEW_NAME, myViewManager.isConsoleEnabledByDefault());
addViewAndShowIfNeeded(executionConsole, CONSOLE_VIEW_NAME, myViewManager.isConsoleEnabledByDefault());
}
}

View File

@@ -280,7 +280,12 @@ public class MultipleBuildsView implements BuildProgressListener, Disposable {
consoleComponent.add(tb.getComponent(), BorderLayout.WEST);
myContent = new ContentImpl(consoleComponent, myViewManager.getViewName(), true);
Disposer.register(myContent, this);
Disposer.register(myContent, new Disposable() {
@Override
public void dispose() {
Disposer.dispose(MultipleBuildsView.this);
}
});
Disposer.register(myContent, new Disposable() {
@Override
public void dispose() {

View File

@@ -34,7 +34,7 @@ public interface BuildProgress<T extends BuildProgressDescriptor> {
@NotNull BuildProgress<? extends BuildProgressDescriptor> finish(boolean isUpToDate);
@NotNull BuildProgress<? extends BuildProgressDescriptor> finish(long timeStamp, boolean isUpToDate);
@NotNull BuildProgress<? extends BuildProgressDescriptor> finish(long timeStamp, boolean isUpToDate, @NotNull String message);
@NotNull BuildProgress<? extends BuildProgressDescriptor> fail();

View File

@@ -125,28 +125,28 @@ class BuildProgressImpl<T extends BuildProgressDescriptor> implements BuildProgr
@NotNull
@Override
public BuildProgress<? extends BuildProgressDescriptor> finish() {
return finish(System.currentTimeMillis(), false);
return finish(false);
}
@NotNull
@Override
public BuildProgress<? extends BuildProgressDescriptor> finish(boolean isUpToDate) {
return finish(System.currentTimeMillis(), isUpToDate);
return finish(System.currentTimeMillis(), isUpToDate, myDescriptor.getTitle());
}
@NotNull
@Override
public BuildProgress<? extends BuildProgressDescriptor> finish(long timeStamp) {
return finish(timeStamp, false);
return finish(timeStamp, false, myDescriptor.getTitle());
}
@NotNull
@Override
public BuildProgress<? extends BuildProgressDescriptor> finish(long timeStamp, boolean isUpToDate) {
public BuildProgress<? extends BuildProgressDescriptor> finish(long timeStamp, boolean isUpToDate, @NotNull String message) {
assertStarted();
assert myParentProgress != null;
EventResult result = new SuccessResultImpl(isUpToDate);
FinishEvent event = new FinishEventImpl(getId(), myParentProgress.getId(), timeStamp, myDescriptor.getTitle(), result);
FinishEvent event = new FinishEventImpl(getId(), myParentProgress.getId(), timeStamp, message, result);
myListener.onEvent(getBuildId(), event);
return myParentProgress;
}

View File

@@ -1,6 +1,7 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.build.progress;
import com.intellij.build.BuildBundle;
import com.intellij.build.BuildProgressListener;
import com.intellij.build.events.FinishBuildEvent;
import com.intellij.build.events.FinishEvent;
@@ -27,14 +28,19 @@ public class BuildRootProgressImpl extends BuildProgressImpl<BuildProgressDescri
@Override
@NotNull
protected StartEvent createStartEvent(BuildProgressDescriptor descriptor) {
return new StartBuildEventImpl(descriptor.getBuildDescriptor(), "running...");
return new StartBuildEventImpl(descriptor.getBuildDescriptor(), BuildBundle.message("build.status.running"));
}
@Override
public @NotNull BuildProgress<? extends BuildProgressDescriptor> finish() {
return finish(System.currentTimeMillis(), false, BuildBundle.message("build.status.finished"));
}
@NotNull
@Override
public BuildProgress<? extends BuildProgressDescriptor> finish(long timeStamp, boolean isUpToDate) {
public BuildProgress<? extends BuildProgressDescriptor> finish(long timeStamp, boolean isUpToDate, @NotNull String message) {
assertStarted();
FinishEvent event = new FinishBuildEventImpl(getId(), null, timeStamp, "finished", new SuccessResultImpl(isUpToDate));
FinishEvent event = new FinishBuildEventImpl(getId(), null, timeStamp, message, new SuccessResultImpl(isUpToDate));
myListener.onEvent(getBuildId(), event);
return this;
}
@@ -42,10 +48,9 @@ public class BuildRootProgressImpl extends BuildProgressImpl<BuildProgressDescri
@NotNull
@Override
public BuildProgress<BuildProgressDescriptor> fail() {
return fail(System.currentTimeMillis(), "failed");
return fail(System.currentTimeMillis(), BuildBundle.message("build.status.failed"));
}
@NotNull
@Override
public BuildRootProgressImpl fail(long timeStamp, @NotNull String message) {
@@ -58,7 +63,7 @@ public class BuildRootProgressImpl extends BuildProgressImpl<BuildProgressDescri
@NotNull
@Override
public BuildProgress<BuildProgressDescriptor> cancel() {
return cancel(System.currentTimeMillis(), "cancelled");
return cancel(System.currentTimeMillis(), BuildBundle.message("build.status.cancelled"));
}
@NotNull

View File

@@ -0,0 +1,155 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.build
import com.intellij.build.events.MessageEvent.Kind.ERROR
import com.intellij.build.events.MessageEvent.Kind.INFO
import com.intellij.build.progress.BuildProgressDescriptor
import com.intellij.testFramework.LightPlatformTestCase
import com.intellij.testFramework.RunAll
import com.intellij.testFramework.fixtures.BuildViewTestFixture
import com.intellij.util.ThrowableRunnable
import org.junit.After
import org.junit.Before
import org.junit.Test
import java.io.File
class BuildViewTest : LightPlatformTestCase() {
private lateinit var buildViewTestFixture: BuildViewTestFixture
@Before
override fun setUp() {
super.setUp()
buildViewTestFixture = BuildViewTestFixture(project)
buildViewTestFixture.setUp()
}
@After
override fun tearDown() {
RunAll()
.append(ThrowableRunnable { if (::buildViewTestFixture.isInitialized) buildViewTestFixture.tearDown() })
.append(ThrowableRunnable { super.tearDown() })
.run()
}
@Test
fun `test successful build`() {
val title = "A build"
val buildDescriptor = DefaultBuildDescriptor(Object(), title, "", System.currentTimeMillis())
val progressDescriptor = object : BuildProgressDescriptor {
override fun getBuildDescriptor(): BuildDescriptor = buildDescriptor
override fun getTitle(): String = title
}
// @formatter:off
BuildViewManager
.newBuildProgress(project)
.start(progressDescriptor)
.message("Root message", "Tex of the root message console", INFO, null)
.progress("Running ...")
.startChildProgress("Inner progress")
.fileMessage("File message1", "message1 descriptive text", INFO, FilePosition(File("aFile.java"), 0, 0))
.fileMessage("File message2", "message2 descriptive text", INFO, FilePosition(File("aFile.java"), 0, 0))
.finish()
.finish()
// @formatter:on
buildViewTestFixture.assertBuildViewTreeEquals(
"""
-
-finished
Root message
-Inner progress
-aFile.java
File message1
File message2
""".trimIndent()
)
buildViewTestFixture.assertBuildViewSelectedNode("finished", "", false)
buildViewTestFixture.assertBuildViewSelectedNode("Root message", "Tex of the root message console\n", false)
buildViewTestFixture.assertBuildViewSelectedNode(
"File message1",
"aFile.java\n" +
"message1 descriptive text",
false
)
}
@Test
fun `test build with errors`() {
val title = "A build"
val buildDescriptor = DefaultBuildDescriptor(Object(), title, "", System.currentTimeMillis())
val progressDescriptor = object : BuildProgressDescriptor {
override fun getBuildDescriptor(): BuildDescriptor = buildDescriptor
override fun getTitle(): String = title
}
// @formatter:off
BuildViewManager
.newBuildProgress(project)
.start(progressDescriptor)
.message("Root message", "Tex of the root message console", INFO, null)
.progress("Running ...")
.startChildProgress("Inner progress")
.fileMessage("File message1", "message1 descriptive text", ERROR, FilePosition(File("aFile.java"), 0, 0))
.fileMessage("File message2", "message2 descriptive text", ERROR, FilePosition(File("aFile.java"), 0, 0))
.fail()
.fail()
// @formatter:on
buildViewTestFixture.assertBuildViewTreeEquals(
"""
-
-failed
Root message
-Inner progress
-aFile.java
File message1
File message2
""".trimIndent()
)
buildViewTestFixture.assertBuildViewSelectedNode(
"File message1",
"aFile.java\n" +
"message1 descriptive text"
)
buildViewTestFixture.assertBuildViewSelectedNode("failed", "", false)
buildViewTestFixture.assertBuildViewSelectedNode("Root message", "Tex of the root message console\n", false)
}
@Test
fun `test cancelled build`() {
val title = "A build"
val buildDescriptor = DefaultBuildDescriptor(Object(), title, "", System.currentTimeMillis())
val progressDescriptor = object : BuildProgressDescriptor {
override fun getBuildDescriptor(): BuildDescriptor = buildDescriptor
override fun getTitle(): String = title
}
// @formatter:off
BuildViewManager
.newBuildProgress(project)
.start(progressDescriptor)
.message("Root message", "Tex of the root message console", INFO, null)
.progress("Running ...")
.startChildProgress("Inner progress")
.cancel()
.cancel()
// @formatter:on
buildViewTestFixture.assertBuildViewTreeEquals(
"""
-
-cancelled
Root message
Inner progress
""".trimIndent()
)
buildViewTestFixture.assertBuildViewSelectedNode("cancelled", "", false)
buildViewTestFixture.assertBuildViewSelectedNode("Root message", "Tex of the root message console\n", false)
buildViewTestFixture.assertBuildViewSelectedNode("Inner progress", "", false)
}
}

View File

@@ -0,0 +1,226 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.testFramework.fixtures
import com.intellij.build.*
import com.intellij.openapi.Disposable
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.testFramework.*
import com.intellij.testFramework.UsefulTestCase.assertSameElements
import com.intellij.util.ThrowableRunnable
import com.intellij.util.concurrency.Semaphore
import com.intellij.util.ui.tree.TreeUtil
import junit.framework.TestCase
import junit.framework.TestCase.assertEquals
import javax.swing.tree.DefaultMutableTreeNode
class BuildViewTestFixture(private val myProject: Project) : IdeaTestFixture {
private val fixtureDisposable: Disposable = object : Disposable {
override fun dispose() {
}
}
private lateinit var syncViewManager: TestSyncViewManager
private lateinit var buildViewManager: TestBuildViewManager
@Throws(Exception::class)
override fun setUp() {
myProject.replaceService(
BuildContentManager::class.java,
BuildContentManagerImpl(myProject), fixtureDisposable)
syncViewManager = TestSyncViewManager(myProject)
myProject.replaceService(SyncViewManager::class.java, syncViewManager, fixtureDisposable)
buildViewManager = TestBuildViewManager(myProject)
myProject.replaceService(BuildViewManager::class.java, buildViewManager, fixtureDisposable)
}
@Throws(Exception::class)
override fun tearDown() = RunAll()
.append(ThrowableRunnable { if (::syncViewManager.isInitialized) syncViewManager.waitForPendingBuilds() })
.append(ThrowableRunnable { if (::buildViewManager.isInitialized) buildViewManager.waitForPendingBuilds() })
.append(ThrowableRunnable { Disposer.dispose(fixtureDisposable) })
.run()
fun assertSyncViewTreeEquals(executionTreeText: String) {
assertExecutionTree(syncViewManager, executionTreeText, false)
}
fun assertSyncViewTreeSame(executionTreeText: String) {
assertExecutionTree(syncViewManager, executionTreeText, true)
}
fun assertBuildViewTreeEquals(executionTree: String) {
assertExecutionTree(buildViewManager, executionTree, false)
}
fun assertBuildViewTreeSame(executionTree: String) {
assertExecutionTree(buildViewManager, executionTree, true)
}
fun assertSyncViewSelectedNode(nodeText: String, consoleText: String) {
assertExecutionTreeNode(syncViewManager, nodeText, { assertEquals(consoleText, it) }, true)
}
fun assertSyncViewSelectedNode(nodeText: String, assertSelected: Boolean, consoleTextChecker: (String?) -> Unit) {
assertExecutionTreeNode(syncViewManager, nodeText, consoleTextChecker, assertSelected)
}
fun getSyncViewRerunActions(): List<AnAction> {
val buildView = syncViewManager.buildsMap[syncViewManager.getRecentBuild()]
return BuildView.RESTART_ACTIONS.getData(buildView!!)!!
}
fun getBuildViewRerunActions(): List<AnAction> {
val buildView = buildViewManager.buildsMap[syncViewManager.getRecentBuild()]
return BuildView.RESTART_ACTIONS.getData(buildView!!)!!
}
fun assertBuildViewSelectedNode(nodeText: String, consoleText: String, assertSelected: Boolean = true) {
assertExecutionTreeNode(buildViewManager, nodeText, { assertEquals(consoleText, it) }, assertSelected)
}
private fun assertExecutionTree(viewManager: TestViewManager, expected: String, ignoreTasksOrder: Boolean) {
viewManager.waitForPendingBuilds()
val recentBuild = viewManager.getRecentBuild()
val buildView = viewManager.getBuildsMap()[recentBuild]
assertExecutionTree(buildView!!, expected, ignoreTasksOrder)
}
private fun assertExecutionTreeNode(
viewManager: TestViewManager,
nodeText: String,
consoleTextChecker: (String?) -> Unit,
assertSelected: Boolean
) {
viewManager.waitForPendingBuilds()
val recentBuild = viewManager.getRecentBuild()
val buildView = viewManager.getBuildsMap()[recentBuild]
assertExecutionTreeNode(buildView!!, nodeText,
consoleTextChecker,
assertSelected)
}
companion object {
fun assertExecutionTree(buildView: BuildView, expected: String, ignoreTasksOrder: Boolean) {
val eventView = buildView.getView(BuildTreeConsoleView::class.java.name, BuildTreeConsoleView::class.java)
eventView!!.addFilter { true }
val treeStringPresentation = runInEdtAndGet {
val tree = eventView.tree
PlatformTestUtil.dispatchAllEventsInIdeEventQueue()
PlatformTestUtil.waitWhileBusy(tree)
return@runInEdtAndGet PlatformTestUtil.print(tree, false)
}
if (ignoreTasksOrder) {
assertSameElements(
buildTasksNodesAsList(
treeStringPresentation.trim()),
buildTasksNodesAsList(expected.trim())
)
}
else {
assertEquals(expected.trim(), treeStringPresentation.trim())
}
}
fun assertExecutionTreeNode(
buildView: BuildView,
nodeText: String,
consoleTextChecker: (String?) -> Unit,
assertSelected: Boolean
) {
val eventView = buildView.getView(BuildTreeConsoleView::class.java.name, BuildTreeConsoleView::class.java)
eventView!!.addFilter { true }
val tree = eventView.tree
val node = runInEdtAndGet {
PlatformTestUtil.dispatchAllEventsInIdeEventQueue()
PlatformTestUtil.waitWhileBusy(tree)
TreeUtil.findNode(tree.model.root as DefaultMutableTreeNode) {
val userObject = it.userObject
userObject is ExecutionNode && userObject.name == nodeText
}
}
val selectedPathComponent =
if (!assertSelected && node != tree.selectionPath?.lastPathComponent) {
runInEdtAndGet {
TreeUtil.selectNode(tree, node)
PlatformTestUtil.dispatchAllEventsInIdeEventQueue()
PlatformTestUtil.waitWhileBusy(tree)
tree.selectionPath!!.lastPathComponent
}
}
else {
tree.selectionPath!!.lastPathComponent
}
if (node != selectedPathComponent) {
assertEquals(node.toString(), selectedPathComponent.toString())
}
val selectedNodeConsoleText = runInEdtAndGet { eventView.selectedNodeConsoleText }
consoleTextChecker.invoke(selectedNodeConsoleText)
}
private fun buildTasksNodesAsList(treeStringPresentation: String): List<String> {
val list = mutableListOf<String>()
val buffer = StringBuilder()
for (line in treeStringPresentation.lineSequence()) {
if (line.startsWith(" -") || line.startsWith(" :") || line.startsWith(" -")) {
list.add(buffer.toString())
buffer.clear()
}
buffer.appendln(line)
}
if (buffer.isNotEmpty()) {
list.add(buffer.toString())
}
return list
}
}
private interface TestViewManager : ViewManager {
fun getBuildsMap(): MutableMap<BuildDescriptor, BuildView>
fun waitForPendingBuilds()
fun getRecentBuild(): BuildDescriptor
}
private class TestSyncViewManager(project: Project) : SyncViewManager(project), TestViewManager {
private val semaphore = Semaphore()
private lateinit var recentBuild: BuildDescriptor
override fun waitForPendingBuilds() = TestCase.assertTrue(semaphore.waitFor(1000))
override fun getRecentBuild(): BuildDescriptor = recentBuild
override fun getBuildsMap(): MutableMap<BuildDescriptor, BuildView> = super.getBuildsMap()
override fun onBuildStart(buildDescriptor: BuildDescriptor) {
super.onBuildStart(buildDescriptor)
recentBuild = buildDescriptor
semaphore.down()
}
override fun onBuildFinish(buildDescriptor: BuildDescriptor) {
super.onBuildFinish(buildDescriptor)
semaphore.up()
}
}
private class TestBuildViewManager(project: Project) : BuildViewManager(project), TestViewManager {
private val semaphore = Semaphore()
private lateinit var recentBuild: BuildDescriptor
override fun waitForPendingBuilds() {
TestCase.assertTrue(semaphore.waitFor(1000))
runInEdtAndWait { PlatformTestUtil.dispatchAllEventsInIdeEventQueue() }
}
override fun getRecentBuild(): BuildDescriptor = recentBuild
override fun getBuildsMap(): MutableMap<BuildDescriptor, BuildView> = super.getBuildsMap()
override fun onBuildStart(buildDescriptor: BuildDescriptor) {
super.onBuildStart(buildDescriptor)
recentBuild = buildDescriptor
semaphore.down()
}
override fun onBuildFinish(buildDescriptor: BuildDescriptor?) {
super.onBuildFinish(buildDescriptor)
semaphore.up()
}
}
}

View File

@@ -19,11 +19,11 @@ import com.intellij.openapi.util.Ref
import com.intellij.openapi.util.text.StringUtil
import com.intellij.testFramework.PlatformTestUtil.dispatchAllEventsInIdeEventQueue
import com.intellij.testFramework.PlatformTestUtil.waitWhileBusy
import com.intellij.testFramework.fixtures.BuildViewTestFixture
import com.intellij.util.TimeoutUtil
import com.intellij.util.concurrency.Semaphore
import groovyjarjarcommonscli.Option
import org.assertj.core.api.Assertions.assertThat
import org.jetbrains.plugins.gradle.importing.BuildViewMessagesImportingTestCase
import org.jetbrains.plugins.gradle.importing.GradleImportingTestCase
import org.jetbrains.plugins.gradle.service.execution.cmd.GradleCommandLineOptionsProvider
import org.junit.Assert
@@ -170,11 +170,11 @@ abstract class GradleRunAnythingProviderTestCase : GradleImportingTestCase() {
}
fun BuildView.assertExecutionTree(expected: String): BuildView {
BuildViewMessagesImportingTestCase.assertExecutionTree(this, expected, false)
BuildViewTestFixture.assertExecutionTree(this, expected, false)
return this
}
fun BuildView.assertExecutionTreeNode(nodeText: String, consoleTextChecker: (String?) -> Unit, assertSelected: Boolean = false): BuildView {
BuildViewMessagesImportingTestCase.assertExecutionTreeNode(this, nodeText, consoleTextChecker, assertSelected)
BuildViewTestFixture.assertExecutionTreeNode(this, nodeText, consoleTextChecker, assertSelected)
return this
}

View File

@@ -1,219 +1,66 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.gradle.importing
import com.intellij.build.*
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle
import com.intellij.openapi.project.Project
import com.intellij.testFramework.PlatformTestUtil
import com.intellij.testFramework.RunAll
import com.intellij.testFramework.replaceService
import com.intellij.testFramework.runInEdtAndGet
import com.intellij.testFramework.fixtures.BuildViewTestFixture
import com.intellij.util.ThrowableRunnable
import com.intellij.util.concurrency.Semaphore
import com.intellij.util.ui.tree.TreeUtil
import junit.framework.TestCase
import org.jetbrains.plugins.gradle.util.GradleConstants
import javax.swing.tree.DefaultMutableTreeNode
abstract class BuildViewMessagesImportingTestCase : GradleImportingTestCase() {
private lateinit var syncViewManager: TestSyncViewManager
private lateinit var buildViewManager: TestBuildViewManager
private lateinit var buildViewTestFixture: BuildViewTestFixture
@Throws(Exception::class)
override fun setUp() {
super.setUp()
currentExternalProjectSettings.delegatedBuild = true
useProjectTaskManager = true
myProject.replaceService(BuildContentManager::class.java, BuildContentManagerImpl(myProject), testRootDisposable)
syncViewManager = TestSyncViewManager(myProject)
myProject.replaceService(SyncViewManager::class.java, syncViewManager, testRootDisposable)
buildViewManager = TestBuildViewManager(myProject)
myProject.replaceService(BuildViewManager::class.java, buildViewManager, testRootDisposable)
buildViewTestFixture = BuildViewTestFixture(myProject)
buildViewTestFixture.setUp()
}
override fun tearDown() = RunAll()
.append(ThrowableRunnable { if (::syncViewManager.isInitialized) syncViewManager.waitForPendingBuilds() })
.append(ThrowableRunnable { if (::buildViewManager.isInitialized) buildViewManager.waitForPendingBuilds() })
.append(ThrowableRunnable { if (::buildViewTestFixture.isInitialized) buildViewTestFixture.tearDown() })
.append(ThrowableRunnable { super.tearDown() })
.run()
protected fun assertSyncViewTreeEquals(executionTreeText: String) {
assertExecutionTree(syncViewManager, executionTreeText, false)
buildViewTestFixture.assertSyncViewTreeEquals(executionTreeText)
}
protected fun assertSyncViewTreeSame(executionTreeText: String) {
assertExecutionTree(syncViewManager, executionTreeText, true)
buildViewTestFixture.assertSyncViewTreeSame(executionTreeText)
}
protected fun assertBuildViewTreeEquals(executionTree: String) {
assertExecutionTree(buildViewManager, executionTree, false)
buildViewTestFixture.assertBuildViewTreeEquals(executionTree)
}
protected fun assertBuildViewTreeSame(executionTree: String) {
assertExecutionTree(buildViewManager, executionTree, true)
buildViewTestFixture.assertBuildViewTreeSame(executionTree)
}
protected fun assertSyncViewSelectedNode(nodeText: String, consoleText: String) {
assertExecutionTreeNode(syncViewManager, nodeText, { assertEquals(consoleText, it) }, true)
buildViewTestFixture.assertSyncViewSelectedNode(nodeText, consoleText)
}
protected fun assertSyncViewSelectedNode(nodeText: String, assertSelected: Boolean, consoleTextChecker: (String?) -> Unit) {
assertExecutionTreeNode(syncViewManager, nodeText, consoleTextChecker, assertSelected)
buildViewTestFixture.assertSyncViewSelectedNode(nodeText, assertSelected, consoleTextChecker)
}
protected fun assertSyncViewRerunActions() {
val buildView = syncViewManager.buildsMap[syncViewManager.getRecentBuild()]
val rerunActions = BuildView.RESTART_ACTIONS.getData(buildView!!)!!
val rerunActions = buildViewTestFixture.getSyncViewRerunActions()
assertSize(1, rerunActions)
val reimportActionText = ExternalSystemBundle.message("action.refresh.project.text", GradleConstants.SYSTEM_ID.readableName)
assertEquals(reimportActionText, rerunActions[0].templateText)
}
protected fun assertBuildViewSelectedNode(nodeText: String, consoleText: String) {
assertExecutionTreeNode(buildViewManager, nodeText, { assertEquals(consoleText, it) }, true)
}
private fun assertExecutionTree(viewManager: TestViewManager, expected: String, ignoreTasksOrder: Boolean) {
viewManager.waitForPendingBuilds()
val recentBuild = viewManager.getRecentBuild()
val buildView = viewManager.getBuildsMap()[recentBuild]
assertExecutionTree(buildView!!, expected, ignoreTasksOrder)
}
private fun assertExecutionTreeNode(
viewManager: TestViewManager,
nodeText: String,
consoleTextChecker: (String?) -> Unit,
assertSelected: Boolean
) {
viewManager.waitForPendingBuilds()
val recentBuild = viewManager.getRecentBuild()
val buildView = viewManager.getBuildsMap()[recentBuild]
assertExecutionTreeNode(buildView!!, nodeText, consoleTextChecker, assertSelected)
}
interface TestViewManager : ViewManager {
fun getBuildsMap(): MutableMap<BuildDescriptor, BuildView>
fun waitForPendingBuilds()
fun getRecentBuild(): BuildDescriptor
}
protected class TestSyncViewManager(project: Project) :
SyncViewManager(project), TestViewManager {
private val semaphore = Semaphore()
private lateinit var recentBuild: BuildDescriptor
override fun waitForPendingBuilds() = TestCase.assertTrue(semaphore.waitFor(1000))
override fun getRecentBuild(): BuildDescriptor = recentBuild
override fun getBuildsMap(): MutableMap<BuildDescriptor, BuildView> = super.getBuildsMap()
override fun onBuildStart(buildDescriptor: BuildDescriptor) {
super.onBuildStart(buildDescriptor)
recentBuild = buildDescriptor
semaphore.down()
}
override fun onBuildFinish(buildDescriptor: BuildDescriptor) {
super.onBuildFinish(buildDescriptor)
semaphore.up()
}
}
protected class TestBuildViewManager(project: Project) :
BuildViewManager(project), TestViewManager {
private val semaphore = Semaphore()
private lateinit var recentBuild: BuildDescriptor
override fun waitForPendingBuilds() = TestCase.assertTrue(semaphore.waitFor(1000))
override fun getRecentBuild(): BuildDescriptor = recentBuild
override fun getBuildsMap(): MutableMap<BuildDescriptor, BuildView> = super.getBuildsMap()
override fun onBuildStart(buildDescriptor: BuildDescriptor) {
super.onBuildStart(buildDescriptor)
recentBuild = buildDescriptor
semaphore.down()
}
override fun onBuildFinish(buildDescriptor: BuildDescriptor?) {
super.onBuildFinish(buildDescriptor)
semaphore.up()
}
buildViewTestFixture.assertBuildViewSelectedNode(nodeText, consoleText)
}
override fun handleImportFailure(errorMessage: String, errorDetails: String?) {
// do not fail tests with failed builds
}
companion object {
fun assertExecutionTree(buildView: BuildView, expected: String, ignoreTasksOrder: Boolean) {
val eventView = buildView.getView(BuildTreeConsoleView::class.java.name, BuildTreeConsoleView::class.java)
eventView!!.addFilter { true }
val treeStringPresentation = runInEdtAndGet {
val tree = eventView.tree
PlatformTestUtil.dispatchAllEventsInIdeEventQueue()
PlatformTestUtil.waitWhileBusy(tree)
return@runInEdtAndGet PlatformTestUtil.print(tree, false)
}
if (ignoreTasksOrder) {
assertSameElements(
buildTasksNodesAsList(treeStringPresentation.trim()),
buildTasksNodesAsList(expected.trim())
)
}
else {
assertEquals(expected.trim(), treeStringPresentation.trim())
}
}
fun assertExecutionTreeNode(
buildView: BuildView,
nodeText: String,
consoleTextChecker: (String?) -> Unit,
assertSelected: Boolean
) {
val eventView = buildView.getView(BuildTreeConsoleView::class.java.name, BuildTreeConsoleView::class.java)
eventView!!.addFilter { true }
val tree = eventView.tree
val node = runInEdtAndGet {
PlatformTestUtil.dispatchAllEventsInIdeEventQueue()
PlatformTestUtil.waitWhileBusy(tree)
TreeUtil.findNode(tree.model.root as DefaultMutableTreeNode) {
val userObject = it.userObject
userObject is ExecutionNode && userObject.name == nodeText
}
}
val selectedPathComponent =
if (!assertSelected && node != tree.selectionPath?.lastPathComponent) {
runInEdtAndGet {
TreeUtil.selectNode(tree, node)
PlatformTestUtil.dispatchAllEventsInIdeEventQueue()
PlatformTestUtil.waitWhileBusy(tree)
tree.selectionPath!!.lastPathComponent
}
}
else {
tree.selectionPath!!.lastPathComponent
}
if (node != selectedPathComponent) {
assertEquals(node.toString(), selectedPathComponent.toString())
}
val selectedNodeConsoleText = runInEdtAndGet { eventView.selectedNodeConsoleText }
consoleTextChecker.invoke(selectedNodeConsoleText)
}
private fun buildTasksNodesAsList(treeStringPresentation: String): List<String> {
val list = mutableListOf<String>()
val buffer = StringBuilder()
for (line in treeStringPresentation.lineSequence()) {
if (line.startsWith(" -") || line.startsWith(" :") || line.startsWith(" -")) {
list.add(buffer.toString())
buffer.clear()
}
buffer.appendln(line)
}
if (buffer.isNotEmpty()) {
list.add(buffer.toString())
}
return list
}
}
}