From 71b12899d649b702b8668586f56c010a46b78d43 Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Sun, 30 Aug 2020 23:14:29 +0300 Subject: [PATCH] terminal: replace BaseShellTerminalIntegrationTest with TestShellSession * Ensures that terminal is not instantiated on Windows * Allows to add a terminal test even if the test must inherit from a particular class due to requirement of a subsystem. GitOrigin-RevId: 5b665f122fea206c0fc850cdce87c3e7875902d3 --- .../BaseShellTerminalIntegrationTest.java | 129 ------------------ .../BasicShellTerminalIntegrationTest.java | 16 ++- .../terminal/fixture/TestShellSession.java | 45 ++++++ .../fixture/TestTerminalBufferWatcher.java | 94 +++++++++++++ 4 files changed, 149 insertions(+), 135 deletions(-) delete mode 100644 plugins/terminal/tests/org/jetbrains/plugins/terminal/BaseShellTerminalIntegrationTest.java create mode 100644 plugins/terminal/tests/org/jetbrains/plugins/terminal/fixture/TestShellSession.java create mode 100644 plugins/terminal/tests/org/jetbrains/plugins/terminal/fixture/TestTerminalBufferWatcher.java diff --git a/plugins/terminal/tests/org/jetbrains/plugins/terminal/BaseShellTerminalIntegrationTest.java b/plugins/terminal/tests/org/jetbrains/plugins/terminal/BaseShellTerminalIntegrationTest.java deleted file mode 100644 index 18b699c5b5aa..000000000000 --- a/plugins/terminal/tests/org/jetbrains/plugins/terminal/BaseShellTerminalIntegrationTest.java +++ /dev/null @@ -1,129 +0,0 @@ -// 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 org.jetbrains.plugins.terminal; - -import com.intellij.testFramework.fixtures.BasePlatformTestCase; -import com.jediterm.pty.PtyProcessTtyConnector; -import com.jediterm.terminal.Terminal; -import com.jediterm.terminal.TtyConnector; -import com.jediterm.terminal.model.TerminalLine; -import com.jediterm.terminal.model.TerminalModelListener; -import com.jediterm.terminal.model.TerminalTextBuffer; -import com.pty4j.PtyProcess; -import org.jetbrains.annotations.NotNull; -import org.junit.Assert; - -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.BooleanSupplier; - -public abstract class BaseShellTerminalIntegrationTest extends BasePlatformTestCase { - - public ShellTerminalWidget myWidget; - public TerminalBufferWatcher myWatcher; - - @Override - public void setUp() throws Exception { - super.setUp(); - LocalTerminalDirectRunner runner = LocalTerminalDirectRunner.createTerminalRunner(getProject()); - PtyProcess process = runner.createProcess(getProject().getBasePath()); - TtyConnector connector = new PtyProcessTtyConnector(process, StandardCharsets.UTF_8); - myWidget = new ShellTerminalWidget(getProject(), new JBTerminalSystemSettingsProvider(), getTestRootDisposable()); - myWidget.start(connector); - myWatcher = new TerminalBufferWatcher(myWidget.getTerminalTextBuffer(), myWidget.getTerminal()); - } - - @Override - public void tearDown() throws Exception { - try { - myWidget.close(); - } - catch (Throwable e) { - addSuppressedException(e); - } - finally { - super.tearDown(); - } - } - - public static class TerminalBufferWatcher { - private final TerminalTextBuffer myBuffer; - private final Terminal myTerminal; - - TerminalBufferWatcher(@NotNull TerminalTextBuffer buffer, @NotNull Terminal terminal) { - myBuffer = buffer; - myTerminal = terminal; - } - - @SuppressWarnings("SameParameterValue") - private @NotNull List getScreenLines(boolean aboveCursorLine) { - List screenLines = new ArrayList<>(); - myBuffer.lock(); - try { - int cursorLineInd = myTerminal.getCursorY() - 1; - for (int row = 0; row < myBuffer.getHeight(); row++) { - if (!aboveCursorLine || row < cursorLineInd) { - TerminalLine line = myBuffer.getLine(row); - screenLines.add(line.getText()); - } - } - } - finally { - myBuffer.unlock(); - } - return screenLines; - } - - public void awaitScreenLinesAre(@NotNull List expectedScreenLines, long timeoutMillis) { - boolean ok = awaitBuffer(() -> expectedScreenLines.equals(getScreenLines(true)), timeoutMillis); - if (!ok) { - Assert.assertEquals(expectedScreenLines, getScreenLines(true)); - Assert.fail("Unexpected failure"); - } - } - - public void awaitScreenLinesEndWith(@NotNull List expectedScreenLines, long timeoutMillis) { - boolean ok = awaitBuffer(() -> checkScreenLinesEndWith(expectedScreenLines), timeoutMillis); - if (!ok) { - Assert.assertEquals(expectedScreenLines, getScreenLines(true)); - Assert.fail("Unexpected failure"); - } - } - - public boolean awaitBuffer(@NotNull BooleanSupplier awaitCondition, long timeoutMillis) { - if (awaitCondition.getAsBoolean()) return true; - CountDownLatch latch = new CountDownLatch(1); - AtomicBoolean ok = new AtomicBoolean(false); - TerminalModelListener listener = new TerminalModelListener() { - @Override - public void modelChanged() { - if (awaitCondition.getAsBoolean()) { - ok.set(true); - latch.countDown(); - } - } - }; - myBuffer.addModelListener(listener); - try { - latch.await(timeoutMillis, TimeUnit.MILLISECONDS); - } - catch (InterruptedException e) { - throw new AssertionError(e); - } - finally { - myBuffer.removeModelListener(listener); - } - return ok.get(); - } - - public boolean checkScreenLinesEndWith(@NotNull List expectedScreenLines) { - List actualLines = getScreenLines(true); - if (actualLines.size() < expectedScreenLines.size()) return false; - List lastActualLines = actualLines.subList(actualLines.size() - expectedScreenLines.size(), actualLines.size()); - return expectedScreenLines.equals(lastActualLines); - } - } -} diff --git a/plugins/terminal/tests/org/jetbrains/plugins/terminal/BasicShellTerminalIntegrationTest.java b/plugins/terminal/tests/org/jetbrains/plugins/terminal/BasicShellTerminalIntegrationTest.java index 410b8effd8e9..98c71cba2be6 100644 --- a/plugins/terminal/tests/org/jetbrains/plugins/terminal/BasicShellTerminalIntegrationTest.java +++ b/plugins/terminal/tests/org/jetbrains/plugins/terminal/BasicShellTerminalIntegrationTest.java @@ -2,20 +2,24 @@ package org.jetbrains.plugins.terminal; import com.intellij.openapi.util.SystemInfo; +import com.intellij.testFramework.fixtures.BasePlatformTestCase; import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.plugins.terminal.fixture.TestShellSession; import java.io.IOException; import java.util.Collections; +import java.util.concurrent.ExecutionException; -public class BasicShellTerminalIntegrationTest extends BaseShellTerminalIntegrationTest { +public class BasicShellTerminalIntegrationTest extends BasePlatformTestCase { - public void testEchoAndClear() throws IOException { + public void testEchoAndClear() throws IOException, ExecutionException { if (!SystemInfo.isUnix) { return; } - myWidget.executeCommand("_MY_FOO=test; echo -e \"1\n2\n3\n$_MY_FOO\""); - myWatcher.awaitScreenLinesEndWith(ContainerUtil.newArrayList("1", "2", "3", "test"), 10000); - myWidget.executeCommand("clear"); - myWatcher.awaitScreenLinesAre(Collections.emptyList(), 10000); + TestShellSession session = new TestShellSession(getProject(), getTestRootDisposable()); + session.executeCommand("_MY_FOO=test; echo -e \"1\n2\n3\n$_MY_FOO\""); + session.awaitScreenLinesEndWith(ContainerUtil.newArrayList("1", "2", "3", "test"), 10000); + session.executeCommand("clear"); + session.awaitScreenLinesAre(Collections.emptyList(), 10000); } } diff --git a/plugins/terminal/tests/org/jetbrains/plugins/terminal/fixture/TestShellSession.java b/plugins/terminal/tests/org/jetbrains/plugins/terminal/fixture/TestShellSession.java new file mode 100644 index 000000000000..575bc2455630 --- /dev/null +++ b/plugins/terminal/tests/org/jetbrains/plugins/terminal/fixture/TestShellSession.java @@ -0,0 +1,45 @@ +// 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 org.jetbrains.plugins.terminal.fixture; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.project.Project; +import com.jediterm.pty.PtyProcessTtyConnector; +import com.jediterm.terminal.TtyConnector; +import com.pty4j.PtyProcess; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.terminal.JBTerminalSystemSettingsProvider; +import org.jetbrains.plugins.terminal.LocalTerminalDirectRunner; +import org.jetbrains.plugins.terminal.ShellTerminalWidget; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.concurrent.ExecutionException; + +public class TestShellSession { + + public final ShellTerminalWidget myWidget; + public final TestTerminalBufferWatcher myWatcher; + + public TestShellSession(@NotNull Project project, @NotNull Disposable parentDisposable) throws ExecutionException { + LocalTerminalDirectRunner runner = LocalTerminalDirectRunner.createTerminalRunner(project); + PtyProcess process = runner.createProcess(project.getBasePath()); + TtyConnector connector = new PtyProcessTtyConnector(process, StandardCharsets.UTF_8); + myWidget = new ShellTerminalWidget(project, new JBTerminalSystemSettingsProvider(), parentDisposable); + myWidget.start(connector); + myWatcher = new TestTerminalBufferWatcher(myWidget.getTerminalTextBuffer(), myWidget.getTerminal()); + } + + public void executeCommand(@NotNull @NonNls String shellCommand) throws IOException { + myWidget.executeCommand(shellCommand); + } + + public void awaitScreenLinesEndWith(@NonNls List expectedScreenLines, int timeoutMillis) { + myWatcher.awaitScreenLinesEndWith(expectedScreenLines, timeoutMillis); + } + + public void awaitScreenLinesAre(@NonNls List expectedScreenLines, int timeoutMillis) { + myWatcher.awaitScreenLinesAre(expectedScreenLines, timeoutMillis); + } +} diff --git a/plugins/terminal/tests/org/jetbrains/plugins/terminal/fixture/TestTerminalBufferWatcher.java b/plugins/terminal/tests/org/jetbrains/plugins/terminal/fixture/TestTerminalBufferWatcher.java new file mode 100644 index 000000000000..a425ef2b3bd1 --- /dev/null +++ b/plugins/terminal/tests/org/jetbrains/plugins/terminal/fixture/TestTerminalBufferWatcher.java @@ -0,0 +1,94 @@ +// 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 org.jetbrains.plugins.terminal.fixture; + +import com.jediterm.terminal.Terminal; +import com.jediterm.terminal.model.TerminalLine; +import com.jediterm.terminal.model.TerminalModelListener; +import com.jediterm.terminal.model.TerminalTextBuffer; +import org.jetbrains.annotations.NotNull; +import org.junit.Assert; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.BooleanSupplier; + +public class TestTerminalBufferWatcher { + private final TerminalTextBuffer myBuffer; + private final Terminal myTerminal; + + TestTerminalBufferWatcher(@NotNull TerminalTextBuffer buffer, @NotNull Terminal terminal) { + myBuffer = buffer; + myTerminal = terminal; + } + + @SuppressWarnings("SameParameterValue") + private @NotNull List getScreenLines(boolean aboveCursorLine) { + List screenLines = new ArrayList<>(); + myBuffer.lock(); + try { + int cursorLineInd = myTerminal.getCursorY() - 1; + for (int row = 0; row < myBuffer.getHeight(); row++) { + if (!aboveCursorLine || row < cursorLineInd) { + TerminalLine line = myBuffer.getLine(row); + screenLines.add(line.getText()); + } + } + } + finally { + myBuffer.unlock(); + } + return screenLines; + } + + public void awaitScreenLinesAre(@NotNull List expectedScreenLines, long timeoutMillis) { + boolean ok = awaitBuffer(() -> expectedScreenLines.equals(getScreenLines(true)), timeoutMillis); + if (!ok) { + Assert.assertEquals(expectedScreenLines, getScreenLines(true)); + Assert.fail("Unexpected failure"); + } + } + + public void awaitScreenLinesEndWith(@NotNull List expectedScreenLines, long timeoutMillis) { + boolean ok = awaitBuffer(() -> checkScreenLinesEndWith(expectedScreenLines), timeoutMillis); + if (!ok) { + Assert.assertEquals(expectedScreenLines, getScreenLines(true)); + Assert.fail("Unexpected failure"); + } + } + + public boolean awaitBuffer(@NotNull BooleanSupplier awaitCondition, long timeoutMillis) { + if (awaitCondition.getAsBoolean()) return true; + CountDownLatch latch = new CountDownLatch(1); + AtomicBoolean ok = new AtomicBoolean(false); + TerminalModelListener listener = new TerminalModelListener() { + @Override + public void modelChanged() { + if (awaitCondition.getAsBoolean()) { + ok.set(true); + latch.countDown(); + } + } + }; + myBuffer.addModelListener(listener); + try { + latch.await(timeoutMillis, TimeUnit.MILLISECONDS); + } + catch (InterruptedException e) { + throw new AssertionError(e); + } + finally { + myBuffer.removeModelListener(listener); + } + return ok.get(); + } + + public boolean checkScreenLinesEndWith(@NotNull List expectedScreenLines) { + List actualLines = getScreenLines(true); + if (actualLines.size() < expectedScreenLines.size()) return false; + List lastActualLines = actualLines.subList(actualLines.size() - expectedScreenLines.size(), actualLines.size()); + return expectedScreenLines.equals(lastActualLines); + } +}