diff options
-rw-r--r-- | src/org/connectbot/bean/HostBean.java | 35 | ||||
-rw-r--r-- | tests/build.xml | 2 | ||||
-rw-r--r-- | tests/src/org/connectbot/BeanTestCase.java | 229 | ||||
-rw-r--r-- | tests/src/org/connectbot/HostBeanTest.java | 93 | ||||
-rw-r--r-- | tests/src/org/connectbot/HostListActivityTest.java | 42 |
5 files changed, 386 insertions, 15 deletions
diff --git a/src/org/connectbot/bean/HostBean.java b/src/org/connectbot/bean/HostBean.java index fbde26f..3e06986 100644 --- a/src/org/connectbot/bean/HostBean.java +++ b/src/org/connectbot/bean/HostBean.java @@ -49,6 +49,7 @@ public class HostBean extends AbstractBean { } + @Override public String getBeanName() { return BEAN_NAME; } @@ -168,6 +169,7 @@ public class HostBean extends AbstractBean { return description; } + @Override public ContentValues getValues() { ContentValues values = new ContentValues(); @@ -196,19 +198,40 @@ public class HostBean extends AbstractBean { HostBean host = (HostBean)o; - if (host.getNickname().equals(nickname) - && host.getUsername().equals(username) - && host.getHostname().equals(hostname) - && host.getPort() == port) - return true; + if (id != -1 && host.getId() != -1) + return host.getId() == id; + + if (nickname == null) { + if (host.getNickname() != null) + return false; + } else if (!nickname.equals(host.getNickname())) + return false; + + if (username == null) { + if (host.getUsername() != null) + return false; + } else if (!username.equals(host.getUsername())) + return false; - return false; + if (hostname == null) { + if (host.getHostname() != null) + return false; + } else if (!hostname.equals(host.getHostname())) + return false; + + if (port != host.getPort()) + return false; + + return true; } @Override public int hashCode() { int hash = 7; + if (id != -1) + return (int)id; + hash = 31 * hash + (null == nickname ? 0 : nickname.hashCode()); hash = 31 * hash + (null == username ? 0 : username.hashCode()); hash = 31 * hash + (null == hostname ? 0 : hostname.hashCode()); diff --git a/tests/build.xml b/tests/build.xml index 7047b5e..1998d9c 100644 --- a/tests/build.xml +++ b/tests/build.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<project name="HostListActivity" default="help"> +<project name="ConnectBotTests" default="help"> <!-- The local.properties file is created and updated by the 'android' tool. It contain the path to the SDK. It should *NOT* be checked in in Version diff --git a/tests/src/org/connectbot/BeanTestCase.java b/tests/src/org/connectbot/BeanTestCase.java new file mode 100644 index 0000000..442bb6d --- /dev/null +++ b/tests/src/org/connectbot/BeanTestCase.java @@ -0,0 +1,229 @@ +/** + * 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 new file mode 100644 index 0000000..274acca --- /dev/null +++ b/tests/src/org/connectbot/HostBeanTest.java @@ -0,0 +1,93 @@ +/* + 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 <http://www.gnu.org/licenses/>. +*/ +package org.connectbot; + +import org.connectbot.bean.HostBean; + +import android.test.AndroidTestCase; + +/** + * @author Kenny Root + * + */ +public class HostBeanTest extends AndroidTestCase { + private static final String[] FIELDS = { "nickname", "username", + "hostname", "port" }; + + HostBean host1; + HostBean host2; + + @Override + protected void setUp() throws Exception { + host1 = new HostBean(); + host1.setNickname("Home"); + host1.setUsername("bob"); + host1.setHostname("server.example.com"); + host1.setPort(22); + + host2 = new HostBean(); + host2.setNickname("Home"); + host2.setUsername("bob"); + host2.setHostname("server.example.com"); + host2.setPort(22); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + public void testIdEquality() { + host1.setId(1); + host2.setId(1); + assertTrue(host1.equals(host2)); + assertTrue(host1.hashCode() == host2.hashCode()); + } + + public void testIdInequality() { + host1.setId(1); + host2.setId(2); + // HostBeans shouldn't be equal when their IDs are not the same + assertFalse("HostBeans are equal when their ID is different", host1 + .equals(host2)); + assertFalse("HostBean hash codes are equal when their ID is different", + host1.hashCode() == host2.hashCode()); + } + + public void testIdEquality2() { + host1.setId(1); + host2.setId(1); + host2.setNickname("Work"); + host2.setUsername("alice"); + host2.setHostname("client.example.com"); + assertTrue( + "HostBeans are not equal when their ID is the same but other fields are different!", + host1.equals(host2)); + assertTrue( + "HostBeans hashCodes are not equal when their ID is the same but other fields are different!", + host1.hashCode() == host2.hashCode()); + } + + public void testBeanMeetsEqualsContract() { + BeanTestCase.assertMeetsEqualsContract(HostBean.class, FIELDS); + } + + public void testBeanMeetsHashCodeContract() { + BeanTestCase.assertMeetsHashCodeContract(HostBean.class, FIELDS); + } +} diff --git a/tests/src/org/connectbot/HostListActivityTest.java b/tests/src/org/connectbot/HostListActivityTest.java index b6ece44..d61c7a7 100644 --- a/tests/src/org/connectbot/HostListActivityTest.java +++ b/tests/src/org/connectbot/HostListActivityTest.java @@ -1,21 +1,47 @@ +/* + 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 <http://www.gnu.org/licenses/>. +*/ package org.connectbot; -import android.test.ActivityInstrumentationTestCase; +import android.test.ActivityInstrumentationTestCase2; /** - * This is a simple framework for a test of an Application. See - * {@link android.test.ApplicationTestCase ApplicationTestCase} for more information on - * how to write and extend Application tests. + * This is a simple framework for a test of an Application. See + * {@link android.test.ApplicationTestCase ApplicationTestCase} for more + * information on how to write and extend Application tests. * <p/> * To run this test, you can type: * adb shell am instrument -w \ * -e class org.connectbot.HostListActivityTest \ * org.connectbot.tests/android.test.InstrumentationTestRunner */ -public class HostListActivityTest extends ActivityInstrumentationTestCase<HostListActivity> { +public class HostListActivityTest extends + ActivityInstrumentationTestCase2<HostListActivity> { + + public HostListActivityTest() { + super("org.connectbot", HostListActivity.class); + } + + public void testOpenMenu() { + HostListActivity a = getActivity(); + + a.openOptionsMenu(); - public HostListActivityTest() { - super("org.connectbot", HostListActivity.class); - } + a.closeOptionsMenu(); + } } |