Commit 3a03c166 authored by Stein Eldar Johnsen's avatar Stein Eldar Johnsen 💬

ConsoleWatcher: fix reset mode.

And make sure the 'default' mode is consistently 'COOKED' when each test
starts, otherwise the 'hasSwitchedMode()' method STTYModeSwitcher cause
some unexpected changed in test output based on *other* tests. Bad.
parent bcb1b95b
package net.morimekta.testing.rules; package net.morimekta.testing.rules;
import net.morimekta.console.terminal.Terminal;
import net.morimekta.console.chr.CharUtil; import net.morimekta.console.chr.CharUtil;
import net.morimekta.console.chr.Color; import net.morimekta.console.chr.Color;
import net.morimekta.console.util.STTY; import net.morimekta.console.util.STTY;
...@@ -15,6 +14,7 @@ import java.io.ByteArrayInputStream; ...@@ -15,6 +14,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.UncheckedIOException; import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
...@@ -44,13 +44,13 @@ public class ConsoleWatcher extends TestWatcher implements AutoCloseable { ...@@ -44,13 +44,13 @@ public class ConsoleWatcher extends TestWatcher implements AutoCloseable {
private final InputStream originalIn; private final InputStream originalIn;
private final STTY tty; private final STTY tty;
private final InputStream in; private final InputStream in;
private final PrintStream out;
private final PrintStream err;
private ByteArrayOutputStream outStream = null; private ByteArrayOutputStream outStream = null;
private ByteArrayOutputStream errStream = null; private ByteArrayOutputStream errStream = null;
private ByteArrayInputStream inStream = null; private ByteArrayInputStream inStream = null;
private PrintStream out;
private PrintStream err;
private TerminalSize terminalSize = DEFAULT_TERMINAL_SIZE; private TerminalSize terminalSize = DEFAULT_TERMINAL_SIZE;
private TerminalSize defaultTerminalSize = DEFAULT_TERMINAL_SIZE; private TerminalSize defaultTerminalSize = DEFAULT_TERMINAL_SIZE;
private boolean interactive = true; private boolean interactive = true;
...@@ -60,6 +60,7 @@ public class ConsoleWatcher extends TestWatcher implements AutoCloseable { ...@@ -60,6 +60,7 @@ public class ConsoleWatcher extends TestWatcher implements AutoCloseable {
private boolean defaultDumpOutputOnFailure = false; private boolean defaultDumpOutputOnFailure = false;
private boolean defaultDumpErrorOnFailure = false; private boolean defaultDumpErrorOnFailure = false;
private boolean started = false; private boolean started = false;
private STTYModeSwitcher switcher;
public ConsoleWatcher() { public ConsoleWatcher() {
originalErr = System.err; originalErr = System.err;
...@@ -67,6 +68,8 @@ public class ConsoleWatcher extends TestWatcher implements AutoCloseable { ...@@ -67,6 +68,8 @@ public class ConsoleWatcher extends TestWatcher implements AutoCloseable {
originalIn = System.in; originalIn = System.in;
in = new WrappedInputStream(); in = new WrappedInputStream();
out = new PrintStream(new WrappedOutputStream());
err = new PrintStream(new WrappedErrorStream());
tty = new STTY() { tty = new STTY() {
@Override @Override
...@@ -176,17 +179,10 @@ public class ConsoleWatcher extends TestWatcher implements AutoCloseable { ...@@ -176,17 +179,10 @@ public class ConsoleWatcher extends TestWatcher implements AutoCloseable {
} }
/** /**
* Reset stream console. * Reset all the streams for the console.
*/ */
public void reset() { public void reset() {
if (!started) {
throw new AssertionError("Resetting a non-started console watcher.");
}
setUpStreams(); setUpStreams();
System.setIn(in);
System.setErr(err);
System.setOut(out);
} }
/** /**
...@@ -203,66 +199,56 @@ public class ConsoleWatcher extends TestWatcher implements AutoCloseable { ...@@ -203,66 +199,56 @@ public class ConsoleWatcher extends TestWatcher implements AutoCloseable {
return new String(errStream.toByteArray(), StandardCharsets.UTF_8); return new String(errStream.toByteArray(), StandardCharsets.UTF_8);
} }
/**
* Set input with dynamic content.
* @param in The input values.
*/
public ConsoleWatcher setInput(Object... in) {
assert in.length > 0 : "Require at least one input item";
return setInput(CharUtil.inputBytes(in));
}
/**
* Set input to return the given string content.
* @param in The string input.
*/
public ConsoleWatcher setInput(@Nonnull String in) {
return setInput(in.getBytes(StandardCharsets.UTF_8));
}
/** /**
* Set input to return the given bytes. * Set input to return the given bytes.
* @param in The bytes for input. * @param in The bytes for input.
*/ */
public ConsoleWatcher setInput(@Nonnull byte[] in) { public ConsoleWatcher setInput(@Nonnull byte[] in) {
assert started : "Setting input on a non-started console";
inStream = new ByteArrayInputStream(in); inStream = new ByteArrayInputStream(in);
return this; return this;
} }
/** /**
* @return The testing TTY * Set input with dynamic content.
* @param in The input values.
*/ */
public STTY tty() { public ConsoleWatcher setInput(Object... in) {
return tty; assert in.length > 0 : "Require at least one input item";
return setInput(CharUtil.inputBytes(in));
} }
/** /**
* Make a terminal for testing. * @return The testing TTY
* @param mode The output mode of the terminal.
* @return The testing terminal
*/ */
public Terminal terminal(STTYMode mode) { public STTY tty() {
try { return tty;
return new Terminal(tty,
in,
outStream,
null,
makeSttyModeSwitcher(mode));
} catch (IOException e) {
throw new AssertionError(e.getMessage(), e);
}
} }
@Override @Override
public void close() { public void close() {
System.setErr(originalErr); try {
System.setOut(originalOut); if (switcher != null) {
System.setIn(originalIn); switcher.close();
}
} catch (IOException e) {
// OOPS. But *should* be impossible.
throw new AssertionError(e.getMessage());
} finally {
switcher = null;
System.setErr(originalErr);
System.setOut(originalOut);
System.setIn(originalIn);
}
} }
@Override @Override
protected void starting(Description description) { protected void starting(Description description) {
try {
switcher = makeSttyModeSwitcher(STTYMode.COOKED);
} catch (IOException e) {
// OOPS. But *should* be impossible.
throw new AssertionError(e.getMessage());
}
setUpStreams(); setUpStreams();
started = true; started = true;
...@@ -302,9 +288,6 @@ public class ConsoleWatcher extends TestWatcher implements AutoCloseable { ...@@ -302,9 +288,6 @@ public class ConsoleWatcher extends TestWatcher implements AutoCloseable {
outStream = new ByteArrayOutputStream(); outStream = new ByteArrayOutputStream();
errStream = new ByteArrayOutputStream(); errStream = new ByteArrayOutputStream();
inStream = new ByteArrayInputStream(new byte[0]); inStream = new ByteArrayInputStream(new byte[0]);
out = new PrintStream(outStream);
err = new PrintStream(errStream);
} }
private STTYModeSwitcher makeSttyModeSwitcher(STTYMode mode) throws IOException { private STTYModeSwitcher makeSttyModeSwitcher(STTYMode mode) throws IOException {
...@@ -316,6 +299,30 @@ public class ConsoleWatcher extends TestWatcher implements AutoCloseable { ...@@ -316,6 +299,30 @@ public class ConsoleWatcher extends TestWatcher implements AutoCloseable {
}; };
} }
private class WrappedOutputStream extends OutputStream {
@Override
public void write(int i) throws IOException {
outStream.write(i);
}
@Override
public void write(@Nonnull byte[] bytes, int off, int len) throws IOException {
outStream.write(bytes, off, len);
}
}
private class WrappedErrorStream extends OutputStream {
@Override
public void write(int i) throws IOException {
errStream.write(i);
}
@Override
public void write(@Nonnull byte[] bytes, int off, int len) throws IOException {
errStream.write(bytes, off, len);
}
}
private class WrappedInputStream extends InputStream { private class WrappedInputStream extends InputStream {
@Override @Override
public int read() throws IOException { public int read() throws IOException {
...@@ -332,29 +339,19 @@ public class ConsoleWatcher extends TestWatcher implements AutoCloseable { ...@@ -332,29 +339,19 @@ public class ConsoleWatcher extends TestWatcher implements AutoCloseable {
return inStream.read(bytes, i, i1); return inStream.read(bytes, i, i1);
} }
@Override
public boolean markSupported() {
return inStream.markSupported();
}
@Override @Override
public long skip(long l) throws IOException { public long skip(long l) throws IOException {
return inStream.skip(l); return inStream.skip(l);
} }
@Override @Override
public void mark(int i) { public void close() throws IOException {
inStream.mark(i); inStream = new ByteArrayInputStream(new byte[0]);
}
@Override
public void reset() throws IOException {
inStream.reset();
} }
@Override @Override
public void close() throws IOException { public int available() throws IOException {
inStream.close(); return inStream.available();
} }
} }
} }
package net.morimekta.testing.rules; package net.morimekta.testing.rules;
import net.morimekta.console.terminal.Terminal;
import net.morimekta.console.chr.Char; import net.morimekta.console.chr.Char;
import net.morimekta.console.terminal.Terminal;
import net.morimekta.console.util.STTYMode; import net.morimekta.console.util.STTYMode;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
...@@ -21,7 +21,8 @@ import static org.junit.Assert.fail; ...@@ -21,7 +21,8 @@ import static org.junit.Assert.fail;
public class ConsoleWatcherTest { public class ConsoleWatcherTest {
@Rule @Rule
public ConsoleWatcher console = new ConsoleWatcher() public ConsoleWatcher console = new ConsoleWatcher()
.withTerminalSize(20, 80); .withTerminalSize(20, 80)
.dumpOnFailure();
@Test @Test
public void testConsole() { public void testConsole() {
...@@ -60,7 +61,7 @@ public class ConsoleWatcherTest { ...@@ -60,7 +61,7 @@ public class ConsoleWatcherTest {
@Test @Test
public void testTerminal() { public void testTerminal() {
Terminal terminal = console.terminal(STTYMode.RAW); Terminal terminal = new Terminal(console.tty());
console.setInput("y"); console.setInput("y");
...@@ -87,7 +88,7 @@ public class ConsoleWatcherTest { ...@@ -87,7 +88,7 @@ public class ConsoleWatcherTest {
assertThat(console.output(), assertThat(console.output(),
is("Do ya? [Y/n]: Yes.\r\n" + is("Do ya? [Y/n]: Yes.\r\n" +
"O'Really? [Y/n]: No.")); "O'Really? [Y/n]: No.\r\n"));
} }
@Test @Test
...@@ -133,7 +134,7 @@ public class ConsoleWatcherTest { ...@@ -133,7 +134,7 @@ public class ConsoleWatcherTest {
@Test @Test
public void testTTY() { public void testTTY() {
Terminal terminal = console.terminal(STTYMode.COOKED); Terminal terminal = new Terminal(console.tty(), STTYMode.COOKED);
assertThat(terminal.getTTY(), sameInstance(console.tty())); assertThat(terminal.getTTY(), sameInstance(console.tty()));
assertThat(terminal.getTTY().getTerminalSize().rows, is(20)); assertThat(terminal.getTTY().getTerminalSize().rows, is(20));
...@@ -143,4 +144,39 @@ public class ConsoleWatcherTest { ...@@ -143,4 +144,39 @@ public class ConsoleWatcherTest {
assertThat(terminal.getTTY().getTerminalSize().rows, is(55)); assertThat(terminal.getTTY().getTerminalSize().rows, is(55));
assertThat(terminal.getTTY().getTerminalSize().cols, is(123)); assertThat(terminal.getTTY().getTerminalSize().cols, is(123));
} }
@Test
public void testInputStream() throws IOException {
console.setInput("abcdef");
byte[] arr = new byte[10];
assertThat(System.in.read(arr), is(6));
assertThat(arr, is(new byte[]{'a', 'b', 'c', 'd', 'e', 'f', 0, 0, 0, 0}));
console.setInput("abcdef");
arr = new byte[10];
System.in.skip(2);
assertThat(System.in.read(arr, 2, 8), is(4));
assertThat(arr, is(new byte[]{0, 0, 'c', 'd', 'e', 'f', 0, 0, 0, 0}));
System.in.close();
}
@Test
public void testErrorStream() throws IOException {
byte[] bytes = new byte[]{'a', 'c', 'e'};
System.err.write('b');
System.err.write(bytes);
System.err.write(bytes, 1, 1);
assertThat(console.error(), is("bacec"));
}
@Test
public void testOutputStream() throws IOException {
byte[] bytes = new byte[]{'a', 'c', 'e'};
System.out.write('b');
System.out.write(bytes);
System.out.write(bytes, 1, 1);
assertThat(console.output(), is("bacec"));
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment