From db208c992937b9a522f0ba50a5356b53de719523 Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Thu, 14 May 2009 12:37:30 +0000 Subject: Added test case for TerminalBridge.onKey and fixed a bug in meta states git-svn-id: https://connectbot.googlecode.com/svn/trunk/connectbot@234 df292f66-193f-0410-a5fc-6d59da041ff2 --- src/org/connectbot/service/TerminalBridge.java | 35 +++- tests/src/org/connectbot/BeanTestCase.java | 229 --------------------- tests/src/org/connectbot/HostBeanTest.java | 1 + tests/src/org/connectbot/TerminalBridgeTest.java | 117 +++++++++++ tests/src/org/connectbot/mock/BeanTestCase.java | 229 +++++++++++++++++++++ .../src/org/connectbot/mock/NullOutputStream.java | 33 +++ 6 files changed, 412 insertions(+), 232 deletions(-) delete mode 100644 tests/src/org/connectbot/BeanTestCase.java create mode 100644 tests/src/org/connectbot/TerminalBridgeTest.java create mode 100644 tests/src/org/connectbot/mock/BeanTestCase.java create mode 100644 tests/src/org/connectbot/mock/NullOutputStream.java diff --git a/src/org/connectbot/service/TerminalBridge.java b/src/org/connectbot/service/TerminalBridge.java index 5477dd4..024c7b6 100644 --- a/src/org/connectbot/service/TerminalBridge.java +++ b/src/org/connectbot/service/TerminalBridge.java @@ -396,6 +396,34 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal } + /** + * Create a new terminal bridge suitable for unit testing. + */ + public TerminalBridge() { + buffer = new vt320() { + @Override + public void write(byte[] b) {} + @Override + public void sendTelnetCommand(byte cmd) {} + @Override + public void setWindowSize(int c, int r) {} + }; + + emulation = null; + manager = null; + + defaultPaint = new Paint(); + + selectionArea = new SelectionArea(); + scrollback = 1; + + localOutput = new LinkedList(); + + fontSizeChangedListeners = new LinkedList(); + + connection = null; + } + /** * Create new terminal bridge with following parameters. We will immediately * launch thread to start SSH connection and handle any hostkey verification @@ -851,7 +879,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal // Ignore all key-up events except for the special keys if (event.getAction() == KeyEvent.ACTION_UP) { // skip keys if we aren't connected yet or have been disconnected - if (disconnected || session == null) + if (disconnected || !sessionOpen) return false; if ("Use right-side keys".equals(keymode)) { @@ -895,7 +923,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal } // skip keys if we aren't connected yet or have been disconnected - if (disconnected || session == null) + if (disconnected || !sessionOpen) return false; // if we're in scrollback, scroll to bottom of window on input @@ -941,7 +969,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal } // handle pressing f-keys - if ((metaState &= META_TAB) != 0) { + if ((metaState & META_TAB) != 0) { switch(key) { case '!': ((vt320)buffer).keyPressed(vt320.KEY_F1, ' ', 0); return true; case '@': ((vt320)buffer).keyPressed(vt320.KEY_F2, ' ', 0); return true; @@ -962,6 +990,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal // TODO write encoding routine that doesn't allocate each time stdin.write(new String(Character.toChars(key)) .getBytes(host.getEncoding())); + return true; } diff --git a/tests/src/org/connectbot/BeanTestCase.java b/tests/src/org/connectbot/BeanTestCase.java deleted file mode 100644 index 442bb6d..0000000 --- a/tests/src/org/connectbot/BeanTestCase.java +++ /dev/null @@ -1,229 +0,0 @@ -/** - * Originally from http://www.cornetdesign.com/files/BeanTestCase.java.txt - */ -package org.connectbot; - -import junit.framework.TestCase; - -import java.lang.reflect.Field; - -public class BeanTestCase extends TestCase { - - private static final String TEST_STRING_VAL1 = "Some Value"; - private static final String TEST_STRING_VAL2 = "Some Other Value"; - - public static void assertMeetsEqualsContract(Class classUnderTest, - String[] fieldNames) { - Object o1; - Object o2; - try { - // Get Instances - o1 = classUnderTest.newInstance(); - o2 = classUnderTest.newInstance(); - - assertTrue( - "Instances with default constructor not equal (o1.equals(o2))", - o1.equals(o2)); - assertTrue( - "Instances with default constructor not equal (o2.equals(o1))", - o2.equals(o1)); - - Field[] fields = getFieldsByNameOrAll(classUnderTest, fieldNames); - - for (int i = 0; i < fields.length; i++) { - - // Reset the instances - o1 = classUnderTest.newInstance(); - o2 = classUnderTest.newInstance(); - - Field field = fields[i]; - field.setAccessible(true); - if (field.getType() == String.class) { - field.set(o1, TEST_STRING_VAL1); - } else if (field.getType() == boolean.class) { - field.setBoolean(o1, true); - } else if (field.getType() == short.class) { - field.setShort(o1, (short) 1); - } else if (field.getType() == long.class) { - field.setLong(o1, (long) 1); - } else if (field.getType() == float.class) { - field.setFloat(o1, (float) 1); - } else if (field.getType() == int.class) { - field.setInt(o1, 1); - } else if (field.getType() == byte.class) { - field.setByte(o1, (byte) 1); - } else if (field.getType() == char.class) { - field.setChar(o1, (char) 1); - } else if (field.getType() == double.class) { - field.setDouble(o1, (double) 1); - } else if (field.getType().isEnum()) { - field.set(o1, field.getType().getEnumConstants()[0]); - } else if (Object.class.isAssignableFrom(field.getType())) { - field.set(o1, field.getType().newInstance()); - } else { - fail("Don't know how to set a " + field.getType().getName()); - } - - assertFalse("Instances with o1 having " + field.getName() - + " set and o2 having it not set are equal", o1 - .equals(o2)); - - field.set(o2, field.get(o1)); - - assertTrue( - "After setting o2 with the value of the object in o1, the two objects in the field are not equal", - field.get(o1).equals(field.get(o2))); - - assertTrue( - "Instances with o1 having " - + field.getName() - + " set and o2 having it set to the same object of type " - + field.get(o2).getClass().getName() - + " are not equal", o1.equals(o2)); - - if (field.getType() == String.class) { - field.set(o2, TEST_STRING_VAL2); - } else if (field.getType() == boolean.class) { - field.setBoolean(o2, false); - } else if (field.getType() == short.class) { - field.setShort(o2, (short) 0); - } else if (field.getType() == long.class) { - field.setLong(o2, (long) 0); - } else if (field.getType() == float.class) { - field.setFloat(o2, (float) 0); - } else if (field.getType() == int.class) { - field.setInt(o2, 0); - } else if (field.getType() == byte.class) { - field.setByte(o2, (byte) 0); - } else if (field.getType() == char.class) { - field.setChar(o2, (char) 0); - } else if (field.getType() == double.class) { - field.setDouble(o2, (double) 1); - } else if (field.getType().isEnum()) { - field.set(o2, field.getType().getEnumConstants()[1]); - } else if (Object.class.isAssignableFrom(field.getType())) { - field.set(o2, field.getType().newInstance()); - } else { - fail("Don't know how to set a " + field.getType().getName()); - } - if (field.get(o1).equals(field.get(o2))) { - // Even though we have different instances, they are equal. - // Let's walk one of them - // to see if we can find a field to set - Field[] paramFields = field.get(o1).getClass() - .getDeclaredFields(); - for (int j = 0; j < paramFields.length; j++) { - paramFields[j].setAccessible(true); - if (paramFields[j].getType() == String.class) { - paramFields[j].set(field.get(o1), TEST_STRING_VAL1); - } - } - } - - assertFalse( - "After setting o2 with a different object than what is in o1, the two objects in the field are equal. " - + "This is after an attempt to walk the fields to make them different", - field.get(o1).equals(field.get(o2))); - assertFalse( - "Instances with o1 having " - + field.getName() - + " set and o2 having it set to a different object are equal", - o1.equals(o2)); - } - - } catch (InstantiationException e) { - e.printStackTrace(); - throw new AssertionError( - "Unable to construct an instance of the class under test"); - } catch (IllegalAccessException e) { - e.printStackTrace(); - throw new AssertionError( - "Unable to construct an instance of the class under test"); - } catch (SecurityException e) { - e.printStackTrace(); - throw new AssertionError( - "Unable to read the field from the class under test"); - } catch (NoSuchFieldException e) { - e.printStackTrace(); - throw new AssertionError( - "Unable to find field in the class under test"); - } - } - - /** - * @param classUnderTest - * @param fieldNames - * @return - * @throws NoSuchFieldException - */ - private static Field[] getFieldsByNameOrAll(Class classUnderTest, - String[] fieldNames) throws NoSuchFieldException { - Field fields[]; - if (fieldNames == null) { - fields = classUnderTest.getDeclaredFields(); - } else { - fields = new Field[fieldNames.length]; - for (int i = 0; i < fieldNames.length; i++) - fields[i] = classUnderTest.getDeclaredField(fieldNames[i]); - } - return fields; - } - - public static void assertMeetsHashCodeContract(Class classUnderTest, - String[] fieldNames) { - try { - Field[] fields = getFieldsByNameOrAll(classUnderTest, fieldNames); - - for (int i = 0; i < fields.length; i++) { - Object o1 = classUnderTest.newInstance(); - int initialHashCode = o1.hashCode(); - - Field field = fields[i]; - field.setAccessible(true); - if (field.getType() == String.class) { - field.set(o1, TEST_STRING_VAL1); - } else if (field.getType() == boolean.class) { - field.setBoolean(o1, true); - } else if (field.getType() == short.class) { - field.setShort(o1, (short) 1); - } else if (field.getType() == long.class) { - field.setLong(o1, (long) 1); - } else if (field.getType() == float.class) { - field.setFloat(o1, (float) 1); - } else if (field.getType() == int.class) { - field.setInt(o1, 1); - } else if (field.getType() == byte.class) { - field.setByte(o1, (byte) 1); - } else if (field.getType() == char.class) { - field.setChar(o1, (char) 1); - } else if (field.getType() == double.class) { - field.setDouble(o1, (double) 1); - } else if (field.getType().isEnum()) { - field.set(o1, field.getType().getEnumConstants()[0]); - } else if (Object.class.isAssignableFrom(field.getType())) { - field.set(o1, field.getType().newInstance()); - } else { - fail("Don't know how to set a " + field.getType().getName()); - } - int updatedHashCode = o1.hashCode(); - assertFalse( - "The field " - + field.getName() - + " was not taken into account for the hashCode contract ", - initialHashCode == updatedHashCode); - } - } catch (InstantiationException e) { - e.printStackTrace(); - throw new AssertionError( - "Unable to construct an instance of the class under test"); - } catch (IllegalAccessException e) { - e.printStackTrace(); - throw new AssertionError( - "Unable to construct an instance of the class under test"); - } catch (NoSuchFieldException e) { - e.printStackTrace(); - throw new AssertionError( - "Unable to find field in the class under test"); - } - } -} diff --git a/tests/src/org/connectbot/HostBeanTest.java b/tests/src/org/connectbot/HostBeanTest.java index d24427e..671d1ce 100644 --- a/tests/src/org/connectbot/HostBeanTest.java +++ b/tests/src/org/connectbot/HostBeanTest.java @@ -18,6 +18,7 @@ package org.connectbot; import org.connectbot.bean.HostBean; +import org.connectbot.mock.BeanTestCase; import android.test.AndroidTestCase; diff --git a/tests/src/org/connectbot/TerminalBridgeTest.java b/tests/src/org/connectbot/TerminalBridgeTest.java new file mode 100644 index 0000000..50a2fdf --- /dev/null +++ b/tests/src/org/connectbot/TerminalBridgeTest.java @@ -0,0 +1,117 @@ +/* + ConnectBot: simple, powerful, open-source SSH client for Android + Copyright (C) 2007-2008 Kenny Root, Jeffrey Sharkey + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ +package org.connectbot; + +import java.io.OutputStream; +import java.lang.reflect.Field; + +import org.connectbot.mock.NullOutputStream; +import org.connectbot.service.TerminalBridge; + +import android.test.AndroidTestCase; +import android.view.KeyEvent; + +/** + * @author Kenny Root + * + */ +public class TerminalBridgeTest extends AndroidTestCase { + public void testShiftLock() throws SecurityException, NoSuchFieldException, + IllegalArgumentException, IllegalAccessException { + TerminalBridge bridge = new TerminalBridge(); + + OutputStream nullStream = new NullOutputStream(); + + // Make sure onKey will work when we call it + Field disconnected = TerminalBridge.class + .getDeclaredField("disconnected"); + Field sessionOpen = TerminalBridge.class + .getDeclaredField("sessionOpen"); + Field keymode = TerminalBridge.class.getDeclaredField("keymode"); + Field stdin = TerminalBridge.class.getDeclaredField("stdin"); + + disconnected.setAccessible(true); + sessionOpen.setAccessible(true); + keymode.setAccessible(true); + stdin.setAccessible(true); + + disconnected.setBoolean(bridge, false); + sessionOpen.setBoolean(bridge, true); + keymode.set(bridge, "Use right-side keys"); + stdin.set(bridge, nullStream); + + // Begin tests + assertTrue("Meta state is " + bridge.getMetaState() + + " when it should be 0", bridge.getMetaState() == 0); + + KeyEvent shiftDown = new KeyEvent(KeyEvent.ACTION_DOWN, + KeyEvent.KEYCODE_SHIFT_LEFT); + bridge.onKey(null, shiftDown.getKeyCode(), shiftDown); + + assertTrue("Shift test: after shift press, meta state is " + + bridge.getMetaState() + " when it should be " + + TerminalBridge.META_SHIFT_ON, + bridge.getMetaState() == TerminalBridge.META_SHIFT_ON); + + KeyEvent shiftUp = KeyEvent.changeAction(shiftDown, KeyEvent.ACTION_UP); + bridge.onKey(null, shiftUp.getKeyCode(), shiftUp); + + assertTrue("Shift test: after shift release, meta state is " + + bridge.getMetaState() + " when it should be " + + TerminalBridge.META_SHIFT_ON, + bridge.getMetaState() == TerminalBridge.META_SHIFT_ON); + + KeyEvent letterAdown = new KeyEvent(KeyEvent.ACTION_DOWN, + KeyEvent.KEYCODE_A); + KeyEvent letterAup = KeyEvent.changeAction(letterAdown, + KeyEvent.ACTION_UP); + + bridge.onKey(null, letterAdown.getKeyCode(), letterAdown); + bridge.onKey(null, letterAup.getKeyCode(), letterAup); + + assertTrue("Shift test: after letter press and release, meta state is " + + bridge.getMetaState() + " when it should be 0", bridge + .getMetaState() == 0); + + bridge.onKey(null, shiftDown.getKeyCode(), shiftDown); + bridge.onKey(null, shiftUp.getKeyCode(), shiftUp); + bridge.onKey(null, shiftDown.getKeyCode(), shiftDown); + bridge.onKey(null, shiftUp.getKeyCode(), shiftUp); + + assertTrue("Shift lock test: after two shift presses, meta state is " + + bridge.getMetaState() + " when it should be " + + TerminalBridge.META_SHIFT_LOCK, + bridge.getMetaState() == TerminalBridge.META_SHIFT_LOCK); + + bridge.onKey(null, letterAdown.getKeyCode(), letterAdown); + + assertTrue( + "Shift lock test: after letter press, meta state is " + + bridge.getMetaState() + " when it should be " + + TerminalBridge.META_SHIFT_LOCK, + bridge.getMetaState() == TerminalBridge.META_SHIFT_LOCK); + + bridge.onKey(null, letterAup.getKeyCode(), letterAup); + + assertTrue( + "Shift lock test: after letter press and release, meta state is " + + bridge.getMetaState() + " when it should be " + + TerminalBridge.META_SHIFT_LOCK, + bridge.getMetaState() == TerminalBridge.META_SHIFT_LOCK); + } +} diff --git a/tests/src/org/connectbot/mock/BeanTestCase.java b/tests/src/org/connectbot/mock/BeanTestCase.java new file mode 100644 index 0000000..5d13d9f --- /dev/null +++ b/tests/src/org/connectbot/mock/BeanTestCase.java @@ -0,0 +1,229 @@ +/** + * Originally from http://www.cornetdesign.com/files/BeanTestCase.java.txt + */ +package org.connectbot.mock; + +import junit.framework.TestCase; + +import java.lang.reflect.Field; + +public class BeanTestCase extends TestCase { + + private static final String TEST_STRING_VAL1 = "Some Value"; + private static final String TEST_STRING_VAL2 = "Some Other Value"; + + public static void assertMeetsEqualsContract(Class classUnderTest, + String[] fieldNames) { + Object o1; + Object o2; + try { + // Get Instances + o1 = classUnderTest.newInstance(); + o2 = classUnderTest.newInstance(); + + assertTrue( + "Instances with default constructor not equal (o1.equals(o2))", + o1.equals(o2)); + assertTrue( + "Instances with default constructor not equal (o2.equals(o1))", + o2.equals(o1)); + + Field[] fields = getFieldsByNameOrAll(classUnderTest, fieldNames); + + for (int i = 0; i < fields.length; i++) { + + // Reset the instances + o1 = classUnderTest.newInstance(); + o2 = classUnderTest.newInstance(); + + Field field = fields[i]; + field.setAccessible(true); + if (field.getType() == String.class) { + field.set(o1, TEST_STRING_VAL1); + } else if (field.getType() == boolean.class) { + field.setBoolean(o1, true); + } else if (field.getType() == short.class) { + field.setShort(o1, (short) 1); + } else if (field.getType() == long.class) { + field.setLong(o1, (long) 1); + } else if (field.getType() == float.class) { + field.setFloat(o1, (float) 1); + } else if (field.getType() == int.class) { + field.setInt(o1, 1); + } else if (field.getType() == byte.class) { + field.setByte(o1, (byte) 1); + } else if (field.getType() == char.class) { + field.setChar(o1, (char) 1); + } else if (field.getType() == double.class) { + field.setDouble(o1, (double) 1); + } else if (field.getType().isEnum()) { + field.set(o1, field.getType().getEnumConstants()[0]); + } else if (Object.class.isAssignableFrom(field.getType())) { + field.set(o1, field.getType().newInstance()); + } else { + fail("Don't know how to set a " + field.getType().getName()); + } + + assertFalse("Instances with o1 having " + field.getName() + + " set and o2 having it not set are equal", o1 + .equals(o2)); + + field.set(o2, field.get(o1)); + + assertTrue( + "After setting o2 with the value of the object in o1, the two objects in the field are not equal", + field.get(o1).equals(field.get(o2))); + + assertTrue( + "Instances with o1 having " + + field.getName() + + " set and o2 having it set to the same object of type " + + field.get(o2).getClass().getName() + + " are not equal", o1.equals(o2)); + + if (field.getType() == String.class) { + field.set(o2, TEST_STRING_VAL2); + } else if (field.getType() == boolean.class) { + field.setBoolean(o2, false); + } else if (field.getType() == short.class) { + field.setShort(o2, (short) 0); + } else if (field.getType() == long.class) { + field.setLong(o2, (long) 0); + } else if (field.getType() == float.class) { + field.setFloat(o2, (float) 0); + } else if (field.getType() == int.class) { + field.setInt(o2, 0); + } else if (field.getType() == byte.class) { + field.setByte(o2, (byte) 0); + } else if (field.getType() == char.class) { + field.setChar(o2, (char) 0); + } else if (field.getType() == double.class) { + field.setDouble(o2, (double) 1); + } else if (field.getType().isEnum()) { + field.set(o2, field.getType().getEnumConstants()[1]); + } else if (Object.class.isAssignableFrom(field.getType())) { + field.set(o2, field.getType().newInstance()); + } else { + fail("Don't know how to set a " + field.getType().getName()); + } + if (field.get(o1).equals(field.get(o2))) { + // Even though we have different instances, they are equal. + // Let's walk one of them + // to see if we can find a field to set + Field[] paramFields = field.get(o1).getClass() + .getDeclaredFields(); + for (int j = 0; j < paramFields.length; j++) { + paramFields[j].setAccessible(true); + if (paramFields[j].getType() == String.class) { + paramFields[j].set(field.get(o1), TEST_STRING_VAL1); + } + } + } + + assertFalse( + "After setting o2 with a different object than what is in o1, the two objects in the field are equal. " + + "This is after an attempt to walk the fields to make them different", + field.get(o1).equals(field.get(o2))); + assertFalse( + "Instances with o1 having " + + field.getName() + + " set and o2 having it set to a different object are equal", + o1.equals(o2)); + } + + } catch (InstantiationException e) { + e.printStackTrace(); + throw new AssertionError( + "Unable to construct an instance of the class under test"); + } catch (IllegalAccessException e) { + e.printStackTrace(); + throw new AssertionError( + "Unable to construct an instance of the class under test"); + } catch (SecurityException e) { + e.printStackTrace(); + throw new AssertionError( + "Unable to read the field from the class under test"); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + throw new AssertionError( + "Unable to find field in the class under test"); + } + } + + /** + * @param classUnderTest + * @param fieldNames + * @return + * @throws NoSuchFieldException + */ + private static Field[] getFieldsByNameOrAll(Class classUnderTest, + String[] fieldNames) throws NoSuchFieldException { + Field fields[]; + if (fieldNames == null) { + fields = classUnderTest.getDeclaredFields(); + } else { + fields = new Field[fieldNames.length]; + for (int i = 0; i < fieldNames.length; i++) + fields[i] = classUnderTest.getDeclaredField(fieldNames[i]); + } + return fields; + } + + public static void assertMeetsHashCodeContract(Class classUnderTest, + String[] fieldNames) { + try { + Field[] fields = getFieldsByNameOrAll(classUnderTest, fieldNames); + + for (int i = 0; i < fields.length; i++) { + Object o1 = classUnderTest.newInstance(); + int initialHashCode = o1.hashCode(); + + Field field = fields[i]; + field.setAccessible(true); + if (field.getType() == String.class) { + field.set(o1, TEST_STRING_VAL1); + } else if (field.getType() == boolean.class) { + field.setBoolean(o1, true); + } else if (field.getType() == short.class) { + field.setShort(o1, (short) 1); + } else if (field.getType() == long.class) { + field.setLong(o1, (long) 1); + } else if (field.getType() == float.class) { + field.setFloat(o1, (float) 1); + } else if (field.getType() == int.class) { + field.setInt(o1, 1); + } else if (field.getType() == byte.class) { + field.setByte(o1, (byte) 1); + } else if (field.getType() == char.class) { + field.setChar(o1, (char) 1); + } else if (field.getType() == double.class) { + field.setDouble(o1, (double) 1); + } else if (field.getType().isEnum()) { + field.set(o1, field.getType().getEnumConstants()[0]); + } else if (Object.class.isAssignableFrom(field.getType())) { + field.set(o1, field.getType().newInstance()); + } else { + fail("Don't know how to set a " + field.getType().getName()); + } + int updatedHashCode = o1.hashCode(); + assertFalse( + "The field " + + field.getName() + + " was not taken into account for the hashCode contract ", + initialHashCode == updatedHashCode); + } + } catch (InstantiationException e) { + e.printStackTrace(); + throw new AssertionError( + "Unable to construct an instance of the class under test"); + } catch (IllegalAccessException e) { + e.printStackTrace(); + throw new AssertionError( + "Unable to construct an instance of the class under test"); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + throw new AssertionError( + "Unable to find field in the class under test"); + } + } +} diff --git a/tests/src/org/connectbot/mock/NullOutputStream.java b/tests/src/org/connectbot/mock/NullOutputStream.java new file mode 100644 index 0000000..38de1e1 --- /dev/null +++ b/tests/src/org/connectbot/mock/NullOutputStream.java @@ -0,0 +1,33 @@ +/* + ConnectBot: simple, powerful, open-source SSH client for Android + Copyright (C) 2007-2008 Kenny Root, Jeffrey Sharkey + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ +package org.connectbot.mock; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * @author Kenny Root + * + */ +public class NullOutputStream extends OutputStream { + @Override + public void write(int arg0) throws IOException { + // do nothing + } + +} -- cgit v1.2.3