diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..d82a6ed --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__junit_junit_4_12.xml b/.idea/libraries/Maven__junit_junit_4_12.xml new file mode 100644 index 0000000..d411041 --- /dev/null +++ b/.idea/libraries/Maven__junit_junit_4_12.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml b/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml new file mode 100644 index 0000000..f58bbc1 --- /dev/null +++ b/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..5755a99 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..1ee38f5 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..f0d2047 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,1316 @@ + + + + + + + + + + + + + + wong.andrew.unitcorn.* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + each + + + + + + + + + + + + + + true + DEFINITION_ORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1493926101051 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + file://$PROJECT_DIR$/src/main/java/wong/andrew/unitcorn/Result.java + 24 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No facets are configured + + + + + + + + + + + + + + + 1.8 + + + + + + + + TypeInformation + + + + + + + + Maven: junit:junit:4.12 + + + + + + + + \ No newline at end of file diff --git a/TypeInformation.iml b/TypeInformation.iml new file mode 100644 index 0000000..5cf6df2 --- /dev/null +++ b/TypeInformation.iml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..a8efbaf --- /dev/null +++ b/pom.xml @@ -0,0 +1,19 @@ + + + 4.0.0 + + wong.andrew + TypeInformation + 1.0-SNAPSHOT + + + + junit + junit + 4.12 + + + + \ No newline at end of file diff --git a/src/main/java/ExampleClass.java b/src/main/java/ExampleClass.java new file mode 100644 index 0000000..6a60de5 --- /dev/null +++ b/src/main/java/ExampleClass.java @@ -0,0 +1,23 @@ +/** + * Created by andrewwong on 5/4/17. + */ +public class ExampleClass { + private int field1; + private int field2; + private String field3; + private int field4; + + public ExampleClass(){} + public ExampleClass(String field3){ + this.field3 = field3; + } + + public ExampleClass(int field2){ + this.field2 = field2; + } + + public int addFields(int field1, int field2){ + int fieldSum = field1 + field2; + return fieldSum; + } +} diff --git a/src/main/java/Main.java b/src/main/java/Main.java new file mode 100644 index 0000000..5d0f18b --- /dev/null +++ b/src/main/java/Main.java @@ -0,0 +1,25 @@ +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; + +/** + * Created by andrewwong on 5/4/17. + */ +public class Main { + public static void main(String[] args) { + PartOne partOne = new PartOne(); + StringBuilder sb = new StringBuilder(); + ExampleClass object = new ExampleClass(); +// System.out.println(partOne.listAllMembers(object)); +// System.out.println(partOne.getClassHierarchy(new Menu())); + ArrayList instances = partOne.instantiateClassHierarchy(new Integer(0)); + for(Object o: instances){ + if(o.getClass().getSimpleName().equals("String")) + { + System.out.println(o.toString()); + } + else + System.out.println(o.getClass().getSimpleName()); + } + } +} diff --git a/src/main/java/PartOne.java b/src/main/java/PartOne.java new file mode 100644 index 0000000..713347d --- /dev/null +++ b/src/main/java/PartOne.java @@ -0,0 +1,143 @@ + +import java.lang.reflect.*; +import java.util.ArrayList; + +/** + * Created by andrewwong on 5/4/17. + */ +public class PartOne { + private final String newLine = "\n"; + private final String space = " "; + private final String doubleSpace = " "; + + public boolean classImplementsInterface(Class aClass, String interfaceName) { + boolean isImplemented = false; + Class[] interfaces = aClass.getInterfaces(); + for (int i = 0; i < interfaces.length; i++) { + if (interfaces[i].getSimpleName().equalsIgnoreCase(interfaceName)) { + isImplemented = true; + break; + } + } + return isImplemented; + } + + public String listAllMembers(Object o) { + StringBuilder sb = new StringBuilder(); + String list; + String fieldList; + String methodList; + String constructorList; + fieldList = listFields(o); + methodList = listMethods(o); + constructorList = listConstructors(o); + sb.append("Fields:\n"); + sb.append(fieldList); + sb.append("Methods:\n"); + + sb.append(methodList); + sb.append("Constructors:\n"); + + sb.append(constructorList); + list = sb.toString(); + return list; + } + + //helper method for listAllMembers + private String listFields(Object o) { + StringBuilder sb = new StringBuilder(); + Field[] fields = o.getClass().getDeclaredFields(); + for (Field field : fields) { + sb.append(o.getClass().getSimpleName()); + sb.append(space); + sb.append(Modifier.toString(field.getModifiers())); + sb.append(space); + sb.append(field.getName()); + sb.append(newLine); + } + return sb.toString(); + } + + //helper method for listAllMembers + private String listMethods(Object o) { + StringBuilder sb = new StringBuilder(); + + Method[] methods = o.getClass().getMethods(); + for (Method method : methods) { + sb.append(method.getDeclaringClass().getSimpleName()); + sb.append(space); + sb.append(Modifier.toString(method.getModifiers())); + sb.append(space); + sb.append(method.getName()); + sb.append(newLine); + } + return sb.toString(); + } + + //helper method for listAllMembers + private String listConstructors(Object o) { + StringBuilder sb = new StringBuilder(); + + Constructor[] constructors = o.getClass().getConstructors(); + for (Constructor constructor : constructors) { + sb.append(constructor.getDeclaringClass().getSimpleName()); + sb.append(space); + sb.append(Modifier.toString(constructor.getModifiers())); + sb.append(space); + sb.append(constructor.getName()); + sb.append(newLine); + } + return sb.toString(); + } + + public String getClassHierarchy(Object o) { + StringBuilder sb = new StringBuilder(); + String hierarchy; + Class currentClass = o.getClass(); + ArrayList listOfClasses = new ArrayList<>(); + + for (int i = 0; currentClass != null; i++) { + listOfClasses.add(currentClass); + currentClass = currentClass.getSuperclass(); + } + + for (int i = listOfClasses.size(); i > 0; i--) { + sb.append(listOfClasses.get(i - 1) + "\n"); + for (int k = listOfClasses.size(), topClass = listOfClasses.size() - 1; k >= i; k--) { + sb.append(doubleSpace); + } + } + + hierarchy = sb.toString(); + return hierarchy; + } + + public ArrayList instantiateClassHierarchy(Object o) { + ArrayList listOfInstances = new ArrayList<>(); + ArrayList listOfClasses = new ArrayList<>(); + Class currentClass = o.getClass(); + for (int i = 0; currentClass != null; i++) { + listOfClasses.add(currentClass); + currentClass = currentClass.getSuperclass(); + } + for (Class aClass : listOfClasses) { + try { + listOfInstances.add(aClass.getConstructor().newInstance()); + } catch (NoSuchMethodException e) { + String errorMessage = "Not instantiated, no default constructor for the class" + aClass.getSimpleName(); + listOfInstances.add(errorMessage); + } catch (InstantiationException e) { + String errorMessage = "Not instantiated, the class " + aClass.getSimpleName() + " is abstract"; + listOfInstances.add(errorMessage); + } catch (IllegalAccessException e) { + String errorMessage = "Not instantiated, constructor for the class " + aClass.getSimpleName() + " is inaccessible"; + listOfInstances.add(errorMessage); + } catch (InvocationTargetException e) { + String errorMessage = "Not instantiated, the class " + aClass.getSimpleName() + "has underlying constructor that throws exception"; + listOfInstances.add(errorMessage); + } + } + return listOfInstances; + } + +} diff --git a/src/main/java/wong/andrew/unitcorn/DummyClass.java b/src/main/java/wong/andrew/unitcorn/DummyClass.java new file mode 100644 index 0000000..9c30233 --- /dev/null +++ b/src/main/java/wong/andrew/unitcorn/DummyClass.java @@ -0,0 +1,15 @@ +package wong.andrew.unitcorn; + +/** + * Created by andrewwong on 5/5/17. + */ +public class DummyClass { + public boolean dummyMethodOne(){ + boolean dummyBoolean = true; + return dummyBoolean; + } + public int dummyMethodTwo(){ + int dummyInt = 0; + return dummyInt; + } +} diff --git a/src/main/java/wong/andrew/unitcorn/Main.java b/src/main/java/wong/andrew/unitcorn/Main.java new file mode 100644 index 0000000..4005d40 --- /dev/null +++ b/src/main/java/wong/andrew/unitcorn/Main.java @@ -0,0 +1,10 @@ +package wong.andrew.unitcorn; + +/** + * Created by andrewwong on 5/5/17. + */ +public class Main { + public static void main(String[] args) { + UnitCornTestRunner unitCorn = new UnitCornTestRunner(); + } +} diff --git a/src/main/java/wong/andrew/unitcorn/Result.java b/src/main/java/wong/andrew/unitcorn/Result.java new file mode 100644 index 0000000..014bb3c --- /dev/null +++ b/src/main/java/wong/andrew/unitcorn/Result.java @@ -0,0 +1,27 @@ +package wong.andrew.unitcorn; + +import java.util.ArrayList; + +/** + * Created by andrewwong on 5/5/17. + */ +public class Result { + private boolean testHasPassed; + private ArrayList exceptionList = new ArrayList<>(); + + public boolean isTestHasPassed() { + return testHasPassed; + } + + public void setTestHasPassed(boolean testHasPassed) { + this.testHasPassed = testHasPassed; + } + + public ArrayList getExceptionList() { + return exceptionList; + } + + public void addToExceptionList(Exception e) { + this.exceptionList.add(e); + } +} diff --git a/src/main/java/wong/andrew/unitcorn/UnitCornTestRunner.java b/src/main/java/wong/andrew/unitcorn/UnitCornTestRunner.java new file mode 100644 index 0000000..e4b5aca --- /dev/null +++ b/src/main/java/wong/andrew/unitcorn/UnitCornTestRunner.java @@ -0,0 +1,94 @@ +package wong.andrew.unitcorn; + +import org.junit.Test; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; + +/** + * Created by andrewwong on 5/5/17. + */ +public class UnitCornTestRunner { + + public String runTests(Class testClass){ + StringBuilder sb = new StringBuilder(); + Method[] allMethods = testClass.getMethods(); + ArrayList testMethods; + ArrayList testMethodNames; + ArrayList results = new ArrayList<>(); + + testMethods = findAllMethodsWithTestAnnotation(allMethods); + testMethodNames = findNamesOfAllMethods(testMethods); + + int i = 0; + for (Method method: testMethods){ + results.add(runTest(testClass, testMethodNames.get(i))); + i++; + } + i = 0; + + for (Result result: results){ + sb.append(testMethodNames.get(i) + ": "); + if (result.isTestHasPassed() == true) + sb.append("pass"); + if (result.isTestHasPassed() == false){ + sb.append("fail," + result.getExceptionList()); + } + sb.append("\n"); + i++; + } + String report = sb.toString(); + return report; + } + + private ArrayList findAllMethodsWithTestAnnotation(Method[] allMethods){ + ArrayList testMethods= new ArrayList<>(); + + for (int i = 0; i < allMethods.length; i ++){ + if (allMethods[i].isAnnotationPresent(Test.class)){ + testMethods.add(allMethods[i]); + } + } + return testMethods; + } + + private ArrayList findNamesOfAllMethods(ArrayList methods){ + ArrayList methodNames = new ArrayList<>(); + for (Method method: methods){ + methodNames.add(method.getName()); + } + return methodNames; + } + + public Result runTest(Class testClass, String methodName){ + Result result = new Result(); + Method method = getMethod(testClass, methodName); + try{ + method.invoke(testClass.newInstance()); + result.setTestHasPassed(true); + } + catch(InstantiationException e){ + result.addToExceptionList(e); + } + catch(IllegalAccessException e){ + result.addToExceptionList(e); + } + catch(InvocationTargetException e){ + result.addToExceptionList(e); + } + catch (NullPointerException e){ + result.addToExceptionList(e); + } + return result; + } + public Method getMethod(Class c, String methodName){ + Method method = null; + try{ + method = c.getMethod(methodName); + }catch(NoSuchMethodException e){ + System.out.println(e); + } + return method; + } +} diff --git a/src/test/java/TestPartOne.java b/src/test/java/TestPartOne.java new file mode 100644 index 0000000..87a79d3 --- /dev/null +++ b/src/test/java/TestPartOne.java @@ -0,0 +1,75 @@ +import org.junit.Test; + +import java.awt.*; +import java.io.Serializable; +import java.util.ArrayList; + +import static org.junit.Assert.*; + +/** + * Created by andrewwong on 5/4/17. + */ +public class TestPartOne { + @Test + public void classImplementsInterface_ClassIsDimensionInterfaceIsSerializable_DimensionImplementsSerializableIsTrue() { + //Arrange + Class aClass; + aClass = Dimension.class; + PartOne partOne = new PartOne(); + String interfaceName = Serializable.class.getSimpleName(); + + //Act + boolean isImplemented = partOne.classImplementsInterface(aClass, interfaceName); + + //Assert + assertTrue(isImplemented); + } + @Test + public void listAllMembers_ObjectHasMembers_ListOfMembersIsReturned(){ + //Arrange + PartOne partOne = new PartOne(); + ExampleClass o = new ExampleClass(); + String expectedList = "Fields:\nExampleClass private field1\nExampleClass private field2\nExampleClass private field3\nExampleClass private field4\n"+ + "Methods:\nExampleClass public addFields\nObject public final wait\nObject public final native wait\nObject public final wait\nObject public equals\nObject public toString\nObject public native hashCode\nObject public final native getClass\nObject public final native notify\nObject public final native notifyAll\n"+ + "Constructors:\nExampleClass public ExampleClass\nExampleClass public ExampleClass\nExampleClass public ExampleClass\n"; + + //Act + String actualList = partOne.listAllMembers(o); + + //Assert + assertEquals(expectedList,actualList); + } + @Test + public void getClassHierarchy_ClassIsInteger_HierarchyWithObjectAndNumberIsReturned(){ + //Arrange + String expectedHierarchy = "class java.lang.Object\n class java.lang.Number\n class java.lang.Integer\n"; + PartOne partOne = new PartOne(); + //Act + String actualHierarchy = partOne.getClassHierarchy(new Integer(0)); + + //Assert + assertEquals(expectedHierarchy.trim(), actualHierarchy.trim()); + } + @Test + public void instantiateClassHierarchy_ClassIsExampleClass_returnsListOfInstancesOfAllConcreteClasses(){ + //Arrange + PartOne partOne = new PartOne(); + Class exampleClassClass = new ExampleClass().getClass(); + Class objectClass = new Object().getClass(); + ArrayList expectedClassesOfInstances = new ArrayList<>(); + expectedClassesOfInstances.add(exampleClassClass); + expectedClassesOfInstances.add(objectClass); + + //Act + ArrayList actualInstances = partOne.instantiateClassHierarchy(new ExampleClass()); + ArrayList actualClassesOfInstances = new ArrayList<>(); + for(Object instance: actualInstances){ + actualClassesOfInstances.add(instance.getClass()); + } + + //Assert + assertTrue(expectedClassesOfInstances.equals(actualClassesOfInstances)); + //assert that the class of the each instance in the instances array is different + } + +} diff --git a/src/test/java/wong/andrew/unitcorn/TestDummyClass.java b/src/test/java/wong/andrew/unitcorn/TestDummyClass.java new file mode 100644 index 0000000..2fb279e --- /dev/null +++ b/src/test/java/wong/andrew/unitcorn/TestDummyClass.java @@ -0,0 +1,33 @@ +package wong.andrew.unitcorn; + +import org.junit.Test; +import static org.junit.Assert.*; + + +/** + * Created by andrewwong on 5/5/17. + */ +public class TestDummyClass { + @Test + public void dummyMethodOne_True_ReturnsTrue(){ + //Arrange + DummyClass dummyClass; + dummyClass = new DummyClass(); + //Act + boolean actualBoolean = dummyClass.dummyMethodOne(); + + //Assert + assertTrue(actualBoolean); + } + @Test + public void dummyMethodTwo_Zero_ReturnsZero(){ + //Arrange + DummyClass dummyClass; + dummyClass = new DummyClass(); + int expectedInt = 0; + //Act + int actualInt = dummyClass.dummyMethodTwo(); + //Assert + assertEquals(expectedInt, actualInt); + } +} diff --git a/src/test/java/wong/andrew/unitcorn/TestUnitCornTestRunner.java b/src/test/java/wong/andrew/unitcorn/TestUnitCornTestRunner.java new file mode 100644 index 0000000..4848a42 --- /dev/null +++ b/src/test/java/wong/andrew/unitcorn/TestUnitCornTestRunner.java @@ -0,0 +1,78 @@ +package wong.andrew.unitcorn; + +import org.junit.Before; +import org.junit.Test; + +import java.lang.reflect.Method; + +import static org.junit.Assert.*; + +/** + * Created by andrewwong on 5/5/17. + */ +public class TestUnitCornTestRunner { +// @Before +// public void initializeUnitCorn(){ +// UnitCornTestRunner unitCorn = new UnitCornTestRunner(); +// } + @Test + public void runTest_RunDummyMethodTest_CorrectResultReturned(){ + //Arrange + UnitCornTestRunner unitCorn = new UnitCornTestRunner(); + Result result; + + Class c = TestDummyClass.class; + String methodName = "dummyMethodOne_True_ReturnsTrue"; + + //Act + result = unitCorn.runTest(c, methodName); + //Assert + assertTrue(result.isTestHasPassed()); + assertTrue(result.getExceptionList().size()==0); + + } + @Test + public void runTest_RunNonexistentTest_CorrectResultReturned(){ + //Arrange + UnitCornTestRunner unitCorn = new UnitCornTestRunner(); + Result result; + + Class c = TestDummyClass.class; + String nonexistentMethodName = "dummyMethodOne_True_ReturnsTr"; + + //Act + result = unitCorn.runTest(c, nonexistentMethodName); + + //Assert + assertFalse(result.isTestHasPassed()); + assertFalse(result.getExceptionList().size()==0); + + } + @Test + public void getMethodFromClass_MethodExists_MethodReturned(){ + //Arrange + UnitCornTestRunner unitCorn = new UnitCornTestRunner(); + Class c = TestDummyClass.class; + String methodName = "dummyMethod_True_ReturnsTrue"; + String expectedMethodName = "dummyMethod_True_ReturnsTrue"; + //Act + Method actualMethod = unitCorn.getMethod(c, methodName); + String actualMethodName = actualMethod.getName(); + //Assert + assertEquals(expectedMethodName, actualMethodName); + } + @Test + public void runTests_ClassExists_ReportReturned(){ + //Arrange + UnitCornTestRunner unitCorn = new UnitCornTestRunner(); + Class c = TestDummyClass.class; + String expectedReport; + expectedReport = "dummyMethodOne_True_ReturnsTrue: pass\ndummyMethodTwo_Zero_ReturnsZero: pass\n"; + + //Act + String actualReport = unitCorn.runTests(c); + + //Assert + assertEquals(expectedReport.trim(), actualReport.trim()); + } +}