<commit_before>(ns codewars.runner
  (:require [codewars.runner :refer [run]]
            [clojure.java.io :as io]
            [codewars.util :refer [write-code!]])
  (:import [codewars.java TempDir]
           [java.net URLClassLoader]
           [javax.tools ToolProvider]
           [org.junit.runner JUnitCore]
           [codewars.java CwRunListener]
           [java.io IOException]))

(defn- compile! [& files]
  (let [compilation-result
        (-> (ToolProvider/getSystemJavaCompiler)
            ;; TODO: write compilation errors somewhere?
            (.run nil nil nil (into-array (map str files))))]
    (if (zero? compilation-result)
      0
      (throw (IOException. "Java compilation error")))))

(defn- load-class [dir class-name]
  "Load a java class in a specified directory"
  (let [class-loader
        (URLClassLoader/newInstance
         (into-array [(-> dir .toURI .toURL)]))]
    (Class/forName (name class-name) true class-loader)))

(defn- run-junit-tests [fixture-class]
  (let [runner (JUnitCore.)]
    (.addListener runner (CwRunListener.))
    (.run runner (into-array [fixture-class]))))

(defn- file-names [files]
  (for [{:keys [:file-name]} files
        :when (not (nil? file-name))]
    file-name))

(defmethod solution-only "java"
  [{:keys [:setup :solution]}]
  (let [dir (TempDir/create "java")
        setup (when (not (empty? setup)) (write-code! "java" dir setup))
        solution (write-code! "java" dir solution)
        files (file-names [setup solution])]
    (apply compile! files)
    (-> solution
        :class-name
        (->> (load-class dir))
        (.getMethod "main" nil)
        (.invoke nil nil))))

(defmethod full-project "java"
  [{:keys [:fixture :setup :solution]}]
  (let [dir (TempDir/create "java")
        fixture (write-code! "java" dir fixture)
        setup (when (not (empty? setup)) (write-code! "java" dir setup))
        solution (write-code! "java" dir solution)
        files (file-names [fixture setup solution])]
    (apply compile! files)
    (->> fixture :class-name (load-class dir) run-junit-tests)))<commit_msg>Adding timing for JUnit tests<commit_after>(ns codewars.runner
  (:require [codewars.runner :refer [run]]
            [codewars.clojure.test]
            [clojure.java.io :as io]
            [codewars.util :refer [write-code!]])
  (:import [codewars.java TempDir]
           [java.net URLClassLoader]
           [javax.tools ToolProvider]
           [org.junit.runner JUnitCore]
           [codewars.java CwRunListener]
           [java.io IOException]))

(defn- compile!
  "Compile files using the java compiler"
  [& files]
  (let [compilation-result
        (-> (ToolProvider/getSystemJavaCompiler)
            ;; TODO: write compilation errors somewhere?
            (.run nil nil nil (into-array (map str files))))]
    (if (zero? compilation-result)
      0
      (throw (IOException. "Java compilation error")))))

(defn- load-class
  "Load a java class in a specified directory"
  [dir class-name]
  (let [class-loader
        (URLClassLoader/newInstance
         (into-array [(-> dir .toURI .toURL)]))]
    (Class/forName (name class-name) true class-loader)))

(defn- run-junit-tests
  "Run a JUnit test using the Codewars Formatter for a given fixture-class"
  [fixture-class]
  (let [runner (JUnitCore.)]
    (.addListener runner (CwRunListener.))
    (codewars.clojure.test/time
     (.run runner (into-array [fixture-class])))))

(defn- file-names
  "Filter a sequence of files writen by write-code! and output their names"
  [& files]
  (for [{:keys [:file-name]} files
        :when (not (nil? file-name))]
    file-name))

(defmethod solution-only "java"
  [{:keys [:setup :solution]}]
  (let [dir (TempDir/create "java")
        setup (when (not (empty? setup)) (write-code! "java" dir setup))
        solution (write-code! "java" dir solution)
        files (file-names setup solution)]
    (apply compile! files)
    (-> solution
        :class-name
        (->> (load-class dir))
        (.getMethod "main" nil)
        (.invoke nil nil))))

(defmethod full-project "java"
  [{:keys [:fixture :setup :solution]}]
  (let [dir (TempDir/create "java")
        fixture (write-code! "java" dir fixture)
        setup (when (not (empty? setup)) (write-code! "java" dir setup))
        solution (write-code! "java" dir solution)
        files (file-names fixture setup solution)]
    (apply compile! files)
    (->> fixture :class-name (load-class dir) run-junit-tests)))
{'fraction_non_alphanumeric': 0.1483050847457627, 'fraction_numerical': 0.00044603033006244426, 'mean_word_length': 2.7375, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5518707', 'n_tokens_mistral': 1441, 'n_tokens_neox': 1426, 'n_words': 407}