From e733ee88f9ba5cd36b83efe58a410c832c5fa7d6 Mon Sep 17 00:00:00 2001 From: Christian Gram Kalhauge <chrg@dtu.dk> Date: Tue, 9 Apr 2024 09:29:16 +0200 Subject: [PATCH] Working examples --- src/main/java/jpamb/Runtime.java | 6 +-- src/main/java/jpamb/cases/Simple.java | 33 +++++++++++++ src/main/java/jpamb/utils/Case.java | 1 - src/main/java/jpamb/utils/CaseContent.java | 57 +++++++++++++++++++--- src/main/java/jpamb/utils/Tag.java | 16 ++++++ 5 files changed, 103 insertions(+), 10 deletions(-) create mode 100644 src/main/java/jpamb/utils/Tag.java diff --git a/src/main/java/jpamb/Runtime.java b/src/main/java/jpamb/Runtime.java index 3c15a6e..130f566 100644 --- a/src/main/java/jpamb/Runtime.java +++ b/src/main/java/jpamb/Runtime.java @@ -31,10 +31,10 @@ public class Runtime { e.printStackTrace(); } catch (InvocationTargetException e) { Class<? extends Throwable> clazz = e.getCause().getClass(); - if (clazz.equals(content.raises())) { + if (content.result().expectThrows(clazz)) { message = "success"; } else { - message = e.toString(); + message = e.getCause().toString(); } } @@ -42,7 +42,7 @@ public class Runtime { message = "did not produce error"; } - System.out.println(cls.getName() + "." + m.getName() + ": " + message); + System.out.println(cls.getName() + "." + m.getName() + content + ": " + message); } } diff --git a/src/main/java/jpamb/cases/Simple.java b/src/main/java/jpamb/cases/Simple.java index 8c25fc0..f0742ca 100644 --- a/src/main/java/jpamb/cases/Simple.java +++ b/src/main/java/jpamb/cases/Simple.java @@ -14,4 +14,37 @@ public class Simple { assert shouldFail; } + @Case("(0) -> assertion error") + public static void assertInteger(int n) { + assert n != 0; + } + + @Case("(-1) -> assertion error") + public static void assertPositive(int num) { + assert num > 0; + } + + @Case("() -> divide by zero") + public static int divideByZero() { + return 1 / 0; + } + + @Case("(0) -> divide by zero") + public static int divideByN(int n) { + return 1 / n; + } + + @Case("(0, 0) -> divide by zero") + public static double divideZeroByZero(int a, int b) { + return a / b; + } + + @Case("(true) -> divide by zero") + public static int divideByZeroIf(boolean b) { + if (b) { + return 1 / 0; + } + return 0; + } + } diff --git a/src/main/java/jpamb/utils/Case.java b/src/main/java/jpamb/utils/Case.java index 4a2f3fd..e610bad 100644 --- a/src/main/java/jpamb/utils/Case.java +++ b/src/main/java/jpamb/utils/Case.java @@ -6,5 +6,4 @@ import java.lang.annotation.*; @Target(ElementType.METHOD) public @interface Case { String value(); - } diff --git a/src/main/java/jpamb/utils/CaseContent.java b/src/main/java/jpamb/utils/CaseContent.java index d88d07c..4a59beb 100644 --- a/src/main/java/jpamb/utils/CaseContent.java +++ b/src/main/java/jpamb/utils/CaseContent.java @@ -1,14 +1,22 @@ package jpamb.utils; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Locale; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; public record CaseContent( Object[] params, - Class<? extends Throwable> raises) { + ResultType result) { + + public String toString() { + List<String> sparams = Arrays.asList(params).stream().map(a -> a.toString()).toList(); + + return "(" + String.join(", ", sparams) + ") -> " + result.toString(); + } public static CaseContent parse(String string) { Pattern pattern = Pattern.compile("\\(([^)]*)\\)\\s*->\\s*(.+)"); @@ -20,9 +28,13 @@ public record CaseContent( String result = matcher.group(2); ArrayList<Object> list = new ArrayList<>(); try (Scanner sc = new Scanner(args)) { + sc.useLocale(Locale.US); + sc.useDelimiter(" *, *"); while (sc.hasNext()) { if (sc.hasNextBoolean()) { list.add(sc.nextBoolean()); + } else if (sc.hasNextInt()) { + list.add(sc.nextInt()); } else { String var = sc.next(); if (!var.equals(",")) { @@ -31,13 +43,46 @@ public record CaseContent( } } } - if (result.equals("assertion error")) { - return new CaseContent(list.toArray(), AssertionError.class); - } else { - throw new RuntimeException("Invalid case: " + string); - } + return new CaseContent(list.toArray(), ResultType.parse(result)); } else { throw new RuntimeException("Invalid case: " + string); } } + + public static enum ResultType { + DIVIDE_BY_ZERO, + ASSERTION_ERROR; + + public static ResultType parse(String string) { + if (string.equals("assertion error")) { + return ASSERTION_ERROR; + } else if (string.equals("divide by zero")) { + return DIVIDE_BY_ZERO; + } else { + throw new RuntimeException("Invalid result type: " + string); + } + } + + public String toString() { + switch (this) { + case DIVIDE_BY_ZERO: + return "divide by zero"; + case ASSERTION_ERROR: + return "assertion error"; + default: + throw new RuntimeException("Unexpected"); + } + } + + public boolean expectThrows(Class<? extends Throwable> clazz) { + switch (this) { + case DIVIDE_BY_ZERO: + return clazz.equals(ArithmeticException.class); + case ASSERTION_ERROR: + return clazz.equals(AssertionError.class); + default: + throw new RuntimeException("Unexpected"); + } + } + } } diff --git a/src/main/java/jpamb/utils/Tag.java b/src/main/java/jpamb/utils/Tag.java new file mode 100644 index 0000000..9c0e093 --- /dev/null +++ b/src/main/java/jpamb/utils/Tag.java @@ -0,0 +1,16 @@ +package jpamb.utils; + +import java.lang.annotation.*; + +// Annotation for tagging methods +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Tag { + TagType[] value(); + + public static enum TagType { + CONDITIONAL, + LOOP, + CALL + } +} -- GitLab