From 9a0a4db7fd18ccfefc97da4bca11ec2f149d4092 Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Fri, 9 Aug 2019 23:08:49 +0200 Subject: [PATCH] add tests --- README.md | 18 +++++++++-- src/babashka/interpreter.clj | 59 ++++++++++++++++++++++-------------- src/babashka/main.clj | 2 +- test/babashka/main_test.clj | 28 +++++++++++++++-- test/babashka/test_utils.clj | 2 +- 5 files changed, 80 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 05ab1b60..bc91b8a5 100644 --- a/README.md +++ b/README.md @@ -81,17 +81,31 @@ Functions are written using the reader tag `#f`. Currently up to three arguments are supported. ``` shellsession -$ echo '3' | bb '(#f (+ %1 %2 %3) 1 2 *in*)' +$ echo '3' | bb '(#f(+ %1 %2 %3) 1 2 *in*)' 6 ``` Regexes are written using the reader tag `#r`. ``` shellsession -$ ls | bb --raw '(filterv #f (re-find #r "reflection" %) *in*)' +$ ls | bb --raw '(filterv #f(re-find #r "reflection" %) *in*)' ["reflection.json"] ``` +Find the line numbers where the word Clojure occurs using a case insensitive regex: + +``` shellsession +$ cat /tmp/test.txt +foo +Clojure is nice +bar +when you're nice to clojure + +$ cat /tmp/test.txt | bb --raw '(map-indexed #f[%1 %2] *in*))' | \ +bb '(keep #f(when (re-find #r"(?i)clojure" (second %)) (first %)) *in*)' +(1 3) +``` + ## Test Test on the JVM: diff --git a/src/babashka/interpreter.clj b/src/babashka/interpreter.clj index 15be74b7..900dfa20 100644 --- a/src/babashka/interpreter.clj +++ b/src/babashka/interpreter.clj @@ -1,19 +1,16 @@ (ns babashka.interpreter {:no-doc true} (:refer-clojure :exclude [comparator]) - (:require [clojure.walk :refer [postwalk]])) - -(defn safe-nth [x n] - (try (nth x n) - (catch Exception _e - nil))) + (:require [clojure.walk :refer [postwalk]] + [clojure.string :as str] + [clojure.set :as set])) (def syms '(= < <= >= + +' - * / aget alength apply assoc assoc-in bit-set bit-shift-left bit-shift-right bit-xor boolean boolean? booleans boolean-array butlast char char? conj cons contains? count dec dec' decimal? dedupe dissoc distinct disj drop - eduction every? + eduction even? every? get first float? floats fnil identity inc int-array iterate @@ -21,18 +18,22 @@ filter filterv find last line-seq keep keep-indexed keys - map map-indexed mapcat merge merge-with munge + map mapv map-indexed mapcat merge merge-with munge name newline not= num neg? nth nthrest + odd? peek pos? re-seq re-find re-pattern rest reverse - safe-nth set? sequential? some? str + set? sequential? some? str take take-last take-nth tree-seq type unchecked-inc-int unchecked-long unchecked-negate unchecked-remainder-int unchecked-subtract-int unsigned-bit-shift-right unchecked-float vals vec vector? rand-int rand-nth range reduce reduced? remove - set seq seq? shuffle simple-symbol? sort sort-by subs)) + second set seq seq? shuffle simple-symbol? sort sort-by subs + set/difference set/join + str/join str/starts-with? str/ends-with? + zero?)) ;; TODO: #_(def all-syms @@ -59,29 +60,41 @@ (if-let [f (first expr)] (if-let [v (var-lookup f)] (apply-fn v in (rest expr)) - (if (ifn? f) + (cond + (or (= 'if f) (= 'when f)) + (let [[_if cond then else] expr] + (if (interpret cond in) + (interpret then in) + (interpret else in))) + ;; bb/fn passed as higher order fn, still needs input + (-> f meta :bb/fn) + (apply-fn (f in) in (rest expr)) + (ifn? f) (apply-fn f in (rest expr)) - nil)) + :else nil)) expr) - :else - expr)) + ;; bb/fn passed as higher order fn, still needs input + (-> expr meta :bb/fn) + (expr in) + :else expr)) (defn read-fn [form] ^:bb/fn - (fn [& [x y z]] - (postwalk (fn [elt] - (case elt - % x - %1 x - %2 y - %3 z - (interpret elt x))) form))) + (fn [in] + (fn [& [x y z]] + (interpret (postwalk (fn [elt] + (case elt + % x + %1 x + %2 y + %3 z + elt)) form) in)))) (defn read-regex [form] (re-pattern form)) (defn apply-fn [f in args] - (let [args (map #(interpret % in) args)] + (let [args (mapv #(interpret % in) args)] (apply f args))) ;;;; Scratch diff --git a/src/babashka/main.clj b/src/babashka/main.clj index a51ec6ca..5c258c61 100644 --- a/src/babashka/main.clj +++ b/src/babashka/main.clj @@ -42,7 +42,7 @@ expr (read-edn expr) in (slurp *in*) in (if raw - (str/split in #"\s") + (str/split in #"\n") (read-edn (format "[%s]" in))) in (if (= 1 (count in)) (first in) in)] (prn (i/interpret expr in)))))) diff --git a/test/babashka/main_test.clj b/test/babashka/main_test.clj index 2a800985..06d1328a 100644 --- a/test/babashka/main_test.clj +++ b/test/babashka/main_test.clj @@ -1,6 +1,30 @@ (ns babashka.main-test (:require [clojure.test :as test :refer [deftest is testing]] - [babashka.test-utils :refer [bb]])) + [babashka.test-utils :as test-utils] + [clojure.edn :as edn])) -(deftest main-test) +(defn bb [input & args] + (edn/read-string (apply test-utils/bb (str input) (map str args)))) + +(deftest main-test + (testing "if and when" + (is (= 1 (bb 0 '(if (zero? *in*) 1 2)))) + (is (= 2 (bb 1 '(if (zero? *in*) 1 2)))) + (is (= 1 (bb 0 '(when (zero? *in*) 1)))) + (is (nil? (bb 1 '(when (zero? *in*) 1))))) + (testing "fn" + (is (= 2 (bb 1 "(#f(+ 1 %) *in*)"))) + (is (= [1 2 3] (bb nil "(map #f(+ 1 %) [0 1 2])"))) + (is (bb 1 "(#f (when (odd? *in*) *in*) 1)"))) + (testing "map" + (is (= [1 2 3] (bb nil '(map inc [0 1 2]))))) + (testing "keep" + (is (= [false true false] (bb nil '(keep odd? [0 1 2]))))) + (testing "..." + (is (= '(1 3) + (-> + (bb "foo\n Clojure is nice. \nbar\n If you're nice to clojure. " + "--raw" + "(map-indexed #f[%1 %2] *in*)") + (bb "(keep #f(when (re-find #r\"(?i)clojure\" (second %)) (first %)) *in*)")))))) diff --git a/test/babashka/test_utils.clj b/test/babashka/test_utils.clj index 5502be9d..352edfa6 100644 --- a/test/babashka/test_utils.clj +++ b/test/babashka/test_utils.clj @@ -17,7 +17,7 @@ {:in input}))))) (def bb - (case (System/getenv "BB_TEST_ENV") + (case (System/getenv "BABASHKA_TEST_ENV") "jvm" #'bb-jvm "native" #'bb-native #'bb-jvm))