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