From c3d015deeeef9c30f8d5814e72687a577b749358 Mon Sep 17 00:00:00 2001 From: Matthew Hague <matthew.hague@rhul.ac.uk> Date: Fri, 22 Oct 2021 19:33:01 +0100 Subject: [PATCH] Add method for checking method declarations Can check static-ness, return type, param types, but not public/private yet. --- .../uk/ac/rhul/cs/javatester/CodeTester.java | 63 +++++++++++++++++++ .../uk/ac/rhul/cs/javatester/UnitTests.java | 49 +++++++++++++++ .../cs/javatester/solution/Assignment.java | 8 +++ 3 files changed, 120 insertions(+) diff --git a/src/main/java/uk/ac/rhul/cs/javatester/CodeTester.java b/src/main/java/uk/ac/rhul/cs/javatester/CodeTester.java index 2ecad55..154d676 100644 --- a/src/main/java/uk/ac/rhul/cs/javatester/CodeTester.java +++ b/src/main/java/uk/ac/rhul/cs/javatester/CodeTester.java @@ -443,6 +443,52 @@ public class CodeTester { params); } + /** + * Checks that the method with the given signature exists + * + * Note, does not check public/private (yet). + * + * @param klass the class the method belongs to + * @param isStatic true if the method should be static + * @param returnType class of return type + * @param methodName name of method + * @param params the class of the method arguments + * @throws failed test or no such method exception if not found + */ + public void checkMethodSignature( + Class<?> klass, + boolean isStatic, + Class<?> returnType, + String methodName, + Class<?>... params + ) throws BaseTester.FailedTestException, NoSuchMethodException { + + String staticString = isStatic ? "static " : ""; + String className = getClassString(klass); + String methodSig = + getClassString(returnType) + " " + + methodName + "(" + getClassParamsString(params) + ") "; + + Method m = invasiveGetMethod(klass, methodName, params); + + if (!m.getReturnType().equals(returnType)) { + throw new BaseTester.FailedTestException( + "Could not find " + staticString + "method in " + className + + " with signature \n\n " + + methodSig + "\n\n" + + "A similar method was found, but the return types do not match." + ); + } + + if (isStatic != Modifier.isStatic(m.getModifiers())) { + throw new BaseTester.FailedTestException( + "Could not find " + staticString + "method in " + className + + " with signature\n\n " + + methodSig + "\n\n" + + "A similar method was found, but check whether it should be static or not." + ); + } + } /** * Convenience for callStaticMsgAcceptNull with acceptNull as true @@ -951,6 +997,23 @@ public class CodeTester { return klass.getSimpleName(); } + /** + * Turns a sequence of classes into a code text representation. + * + * I.e. if an object we've constructed, use our internal variable + * name. Else use toString (or a built in type preset). + */ + private String getClassParamsString(Class<?>... params) { + if (params.length > 0) { + return Stream.of(params) + .map(p -> getClassString(p)) + .reduce((l, r) -> l + ", " + r) + .get(); + } else { + return ""; + } + } + /** * Expand properties such as :LOG: and :LAST_CALL: */ diff --git a/src/test/java/uk/ac/rhul/cs/javatester/UnitTests.java b/src/test/java/uk/ac/rhul/cs/javatester/UnitTests.java index a05098f..f99bf0b 100644 --- a/src/test/java/uk/ac/rhul/cs/javatester/UnitTests.java +++ b/src/test/java/uk/ac/rhul/cs/javatester/UnitTests.java @@ -345,4 +345,53 @@ public class UnitTests { }; assertFalse(tester.runTests()); } + + private void checkMethodBase( + boolean isStatic, + Class<?> returnType, + String methodName, + boolean expectedResult + ) { + BaseTester tester = new BaseTester(ASSIGNMENT) { + @SuppressWarnings("unused") + public boolean testCheckMethod() + throws BaseTester.FailedTestException, NoSuchMethodException { + CodeTester ct = new CodeTester(); + Class<?> klass = ct.loadClass(ASSIGNMENT); + ct.checkMethodSignature( + klass, + isStatic, returnType, + methodName, + int.class, int.class + ); + return true; + } + }; + assertEquals(expectedResult, tester.runTests()); + } + + @Test + public void testCheckMethodGood() { + checkMethodBase(false, int.class, "myFunc", true); + } + + @Test + public void testCheckMethodBadReturn() { + checkMethodBase(false, void.class, "myFunc", false); + } + + @Test + public void testCheckMethodBadStatic() { + checkMethodBase(false, int.class, "myStaticFunc", false); + } + + @Test + public void testCheckStaticMethodGood() { + checkMethodBase(true, int.class, "myStaticFunc", true); + } + + @Test + public void testCheckStaticMethodBad() { + checkMethodBase(true, int.class, "myFunc", false); + } } diff --git a/src/test/java/uk/ac/rhul/cs/javatester/solution/Assignment.java b/src/test/java/uk/ac/rhul/cs/javatester/solution/Assignment.java index 33fc12b..5be3e87 100644 --- a/src/test/java/uk/ac/rhul/cs/javatester/solution/Assignment.java +++ b/src/test/java/uk/ac/rhul/cs/javatester/solution/Assignment.java @@ -15,4 +15,12 @@ public class Assignment { Scanner scanner = new Scanner(System.in); scanner.nextLine().trim(); } + + public static int myStaticFunc(int x, int y) { + return 0; + } + + public int myFunc(int x, int y) { + return 0; + } } -- GitLab