Skip to content

Commit

Permalink
Run tests from source, intro bbin integration tests (#6)
Browse files Browse the repository at this point in the history
Also extend test suite to MS-Win.

Co-authored-by: ikappaki <ikappaki@users.noreply.github.com>
  • Loading branch information
ikappaki and ikappaki committed May 15, 2023
1 parent 9b1a7c1 commit fa156db
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 34 deletions.
23 changes: 7 additions & 16 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ jobs:

strategy:
matrix:
os: [ubuntu-latest, macos-latest]
emacs_version: ["27.2", "28.1"]
os: [macos-latest, ubuntu-latest, windows-latest]
emacs_version: ["27.2", "28.2"]
include:
- os: ubuntu-latest
emacs_version: "snapshot"
Expand All @@ -27,6 +27,10 @@ jobs:
cli: latest
bb: latest

- name: Prime babashka
run: |
bb clojure --help
- name: Set up Emacs
if: "!startsWith (matrix.os, 'windows')"
uses: purcell/setup-emacs@master
Expand Down Expand Up @@ -63,19 +67,7 @@ jobs:
scoop bucket add extras
scoop bucket add scoop-clojure https://github.com/littleli/scoop-clojure
scoop install bbin
- name: Install clj2el as executable
if: "!startsWith (matrix.os, 'windows')"
run: bbin install .

- name: Install clj2el as executable
if: startsWith (matrix.os, 'windows')
run: |
iex "& {$(irm get.scoop.sh)} -RunAsAdmin"
scoop bucket add extras
scoop bucket add scoop-clojure https://github.com/littleli/scoop-clojure
scoop install bbin
bbin install .
get-command bbin.cmd | split-path -parent | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Install Eldev
if: "!startsWith (matrix.os, 'windows')"
Expand All @@ -88,5 +80,4 @@ jobs:
- name: Test the project
run: |
export PATH="$PATH:$HOME/.babashka/bbin/bin"
eldev -dtT test
20 changes: 17 additions & 3 deletions clj2el.el
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,35 @@
;;
;;; Code:

(defcustom clj2el-command
"clj2el"
"The command used to execute clj2el."
:type 'string
:group 'clj2el)

(defun clj2el-transpile-buffer ()
(interactive)
(shell-command-on-region (point-min) (point-max) "clj2el" (current-buffer)))
(shell-command-on-region (point-min) (point-max) clj2el-command (current-buffer)))

(defun clj2el-transpile-region ()
(interactive)
(shell-command-on-region (point) (mark) "clj2el" (current-buffer) 't))
(shell-command-on-region (point) (mark) clj2el-command (current-buffer) 't))

(defmacro clj2el-clj! (expr)
"Transpile clojure like EXPR form to elisp and eval it.
Transpilation is performed by sending EXPR as input to
`clj2el-command'. Signals an error if the program cannot be find
or an error is reported."
(let* ((expr-as-string (prin1-to-string expr))
(temp-buf "*el2clj-work*"))
(get-buffer-create temp-buf)
(let* ((elisp-code (with-current-buffer temp-buf
(erase-buffer)
(insert expr-as-string)
(shell-command-on-region (point-min) (point-max) "clj2el" temp-buf)
(when (not (= (shell-command-on-region (point-min) (point-max) clj2el-command temp-buf) 0))
(error ":clj23el-clj!-cmd-error :clj2el-command %S :error %s"
clj2el-command (buffer-substring-no-properties (point-min) (point-max))))
(buffer-substring (point-min) (point-max))))
(read (read-from-string elisp-code))
(expr (car read)))
Expand All @@ -43,6 +56,7 @@
(&rest _exprs))

(clj2el-comment
(setq clj2el-command "bb -x clj2el.exec/exec")
(clj2el-clj!
(do (defn foo [x] (inc x))
(defn bar [x] (inc x))))
Expand Down
66 changes: 66 additions & 0 deletions test/integration-tests.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
(require 'clj2el)

(require 'cl-lib)
(require 'ert)

(defmacro with-temp-bbin-install (&rest body)
"Create a temp dir to install clj2el to with bbin and run BODY.
The following functions are updated in BODY to use this installation
- `clj2el-clj!'
- `clj2el-transpile-buffer' (also called interactively with prefix arg)
- `clj2el-transpile-range' (also called interactively with prefix arg)."
(declare (indent 0))
`(let ((bbin-install-dir (make-temp-file "clj2el" t))
(bbin-exec (executable-find "bbin"))
(env-bbd (getenv "BABASHKA_BBIN_DIR"))
(env-path (getenv "PATH")))
;; (message ":temp-bbin-install-dir-created-at %s" bbin-install-dir)
(unwind-protect
(progn
(should bbin-exec)
(setenv "BABASHKA_BBIN_DIR" bbin-install-dir)
(setenv "PATH" (concat (expand-file-name "bin" bbin-install-dir) path-separator
(getenv "PATH")))
(with-temp-buffer
(let ((ret (call-process-shell-command "bbin" nil (current-buffer) nil
"install" ".")))
(when (not (= ret 0))
(message ":bbin-install-error %s" (buffer-substring-no-properties (point-min) (point-max))))
(should (= ret 0))))
(cl-macrolet ((clj2el-clj! (expr) `(eval '(clj2el-clj! ,expr)))
(clj2el-transpile-buffer () '(let ((current-prefix-arg '(4)))
(call-interactively 'clj2el-transpile-buffer)))
(clj2el-transpile-range () '(let ((current-prefix-arg '(4)))
(call-interactively 'clj2el-transpile-range))))
,@body))
(progn
(setenv "BABASHKA_BBIN_DIR" env-bbd)
(setenv "PATH" env-path)
;; (message ":temp-bbin-install-deleting... %s" bbin-install-dir)
(delete-directory bbin-install-dir t)))))


(ert-deftest integration ()
(with-temp-bbin-install

;; clj2el-transpile-buffer
(should (string= "(1+ 3)\n"
(with-temp-buffer
(insert "(inc 3)")
(clj2el-transpile-buffer)
(buffer-substring-no-properties (point-min) (point-max)))))

;; clj2el-transpile-region
(should (string= "[[ (1+ 4)\n ]]"
(with-temp-buffer
(insert "[[ (inc 4) ]]")
(set-mark 4)
(goto-char 11)
(clj2el-transpile-region)
(buffer-substring-no-properties (point-min) (point-max)))))


;; clj2el-clj!
(should (= 6 (clj2el-clj! (inc 5))))))
81 changes: 66 additions & 15 deletions test/test.el
Original file line number Diff line number Diff line change
@@ -1,18 +1,69 @@
(require 'clj2el)

(require 'cl-lib)
(require 'ert)

(cl-defmacro with-clj2el-test (&rest body &aux (test-clj2el-command "bb -x clj2el.exec/exec"))
"Execute BODY with `clj2el-command' bound to TEST-CLJ2EL-COMMAND.
The command is supposed to execute clj2el from source.
the following fucntions are also updated to be called interactively with a prefix arg:
- `clj2el-transpile-buffer'
- `clj2el-transpile-range'."
(declare (indent 0))
`(let ((clj2el-command ,test-clj2el-command))
(cl-macrolet (;; use eval to pick up the updated
;; `clj2el-command'.
(clj2el-clj! (expr) `(eval '(clj2el-clj! ,expr)))

;; call with prefix arg.
(clj2el-transpile-buffer () '(let ((current-prefix-arg '(4)))
(call-interactively 'clj2el-transpile-buffer)))
(clj2el-transpile-range () '(let ((current-prefix-arg '(4)))
(call-interactively 'clj2el-transpile-range))))
,@body)))

(ert-deftest basic ()
(with-clj2el-test

;; clj2el-transpile-buffer
(should (string= "(1+ 2)\n"
(with-temp-buffer
(insert "(inc 2)")
(clj2el-transpile-buffer)
(buffer-substring-no-properties (point-min) (point-max)))))

;; clj2el-transpile-region
(should (string= "[[ (1+ 2)\n ]]"
(with-temp-buffer
(insert "[[ (inc 2) ]]")
(set-mark 4)
(goto-char 11)
(clj2el-transpile-region)
;; (test--call-interactively-with-prefix 'clj2el-transpile-region)
(buffer-substring-no-properties (point-min) (point-max)))))


;; clj2el-clj!
(should (= 3 (clj2el-clj! (inc 2))))))

(ert-deftest juxt ()
(should (equal
(clj2el-clj! ((juxt inc dec) 1))
'(2 0)))
(should (equal
(clj2el-clj! ((juxt + -)
0 1 2 3 4 5))
'(15 -15)))
;; Currently, `funcall' is required here. Might change in the future.
(should (equal
(clj2el-clj! (let [fns (juxt + -)]
(funcall fns 0 1 2 3 4 5)))
'(15 -15)))
;; Missing `funcall'
(should-error (clj2el-clj! (let [fns (juxt + -)]
(fns 0 1 2 3 4 5)))))
(with-clj2el-test
(should (equal
(clj2el-clj! ((juxt inc dec) 1))
'(2 0)))
(should (equal
(clj2el-clj! ((juxt + -)
0 1 2 3 4 5))
'(15 -15)))
;; Currently, `funcall' is required here. Might change in the future.

(should (equal
(clj2el-clj! (let [fns (juxt + -)]
(funcall fns 0 1 2 3 4 5)))
'(15 -15)))
;; Missing `funcall'

(should-error (clj2el-clj! (let [fns (juxt + -)]
(fns 0 1 2 3 4 5))))))

0 comments on commit fa156db

Please sign in to comment.