mix deps support
This commit is contained in:
213
test/test-ob-elixir-deps.el
Normal file
213
test/test-ob-elixir-deps.el
Normal file
@@ -0,0 +1,213 @@
|
||||
;;; test-ob-elixir-deps.el --- Deps block tests -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2024 Your Name
|
||||
|
||||
;; Author: Your Name <your.email@example.com>
|
||||
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Tests for ob-elixir Mix dependencies support.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'ert)
|
||||
(require 'ob-elixir)
|
||||
|
||||
;;; Parsing Tests
|
||||
|
||||
(ert-deftest ob-elixir-test-deps-block-parsing ()
|
||||
"Test finding deps blocks in buffer."
|
||||
(with-temp-buffer
|
||||
(insert "#+BEGIN_DEPS elixir\n[{:jason, \"~> 1.4\"}]\n#+END_DEPS\n\n")
|
||||
(insert "#+BEGIN_SRC elixir\nJason.encode!(%{})\n#+END_SRC\n")
|
||||
(goto-char (point-max))
|
||||
(let ((deps (ob-elixir--find-deps-for-position (point))))
|
||||
(should deps)
|
||||
(should (string-match-p ":jason" deps)))))
|
||||
|
||||
(ert-deftest ob-elixir-test-deps-block-override ()
|
||||
"Test that later deps blocks override earlier ones."
|
||||
(with-temp-buffer
|
||||
(insert "#+BEGIN_DEPS elixir\n[{:jason, \"~> 1.4\"}]\n#+END_DEPS\n\n")
|
||||
(insert "#+BEGIN_SRC elixir\ncode1\n#+END_SRC\n\n")
|
||||
(insert "#+BEGIN_DEPS elixir\n[{:httpoison, \"~> 2.0\"}]\n#+END_DEPS\n\n")
|
||||
(let ((pos (point)))
|
||||
(insert "#+BEGIN_SRC elixir\ncode2\n#+END_SRC\n")
|
||||
(let ((deps (ob-elixir--find-deps-for-position (+ pos 10))))
|
||||
(should deps)
|
||||
(should (string-match-p ":httpoison" deps))
|
||||
(should-not (string-match-p ":jason" deps))))))
|
||||
|
||||
(ert-deftest ob-elixir-test-no-deps-block ()
|
||||
"Test behavior when no deps block exists."
|
||||
(with-temp-buffer
|
||||
(insert "#+BEGIN_SRC elixir\n1 + 1\n#+END_SRC\n")
|
||||
(should (null (ob-elixir--find-deps-for-position (point))))))
|
||||
|
||||
(ert-deftest ob-elixir-test-deps-block-before-position ()
|
||||
"Test that deps block must be before the position."
|
||||
(with-temp-buffer
|
||||
(insert "#+BEGIN_SRC elixir\n1 + 1\n#+END_SRC\n\n")
|
||||
(let ((pos (point)))
|
||||
(insert "#+BEGIN_DEPS elixir\n[{:jason, \"~> 1.4\"}]\n#+END_DEPS\n")
|
||||
;; Position is before deps block, should not find it
|
||||
(should (null (ob-elixir--find-deps-for-position pos))))))
|
||||
|
||||
(ert-deftest ob-elixir-test-deps-hash-consistency ()
|
||||
"Test that same deps produce same hash."
|
||||
(let ((deps1 "[{:jason, \"~> 1.4\"}]")
|
||||
(deps2 "[{:jason, \"~> 1.4\"}]") ; extra space
|
||||
(deps3 "[{:httpoison, \"~> 2.0\"}]"))
|
||||
(should (string= (ob-elixir--hash-deps deps1)
|
||||
(ob-elixir--hash-deps deps2)))
|
||||
(should-not (string= (ob-elixir--hash-deps deps1)
|
||||
(ob-elixir--hash-deps deps3)))))
|
||||
|
||||
(ert-deftest ob-elixir-test-normalize-deps ()
|
||||
"Test deps normalization."
|
||||
;; Extra spaces between tokens get normalized to single space
|
||||
(should (string= (ob-elixir--normalize-deps "[{:a, \"1\"}]")
|
||||
(ob-elixir--normalize-deps "[{:a, \"1\"}]")))
|
||||
;; Comments are stripped
|
||||
(should (string= (ob-elixir--normalize-deps "[{:a, \"1\"}] # comment")
|
||||
(ob-elixir--normalize-deps "[{:a, \"1\"}]"))))
|
||||
|
||||
(ert-deftest ob-elixir-test-normalize-deps-multiline ()
|
||||
"Test normalization of multiline deps."
|
||||
;; Multiline deps with same content should produce the same hash
|
||||
(let ((multiline1 "[\n {:jason, \"~> 1.4\"},\n {:decimal, \"~> 2.0\"}\n]")
|
||||
(multiline2 "[\n{:jason, \"~> 1.4\"},\n{:decimal, \"~> 2.0\"}\n]"))
|
||||
;; Both should hash to the same value since they have equivalent whitespace normalization
|
||||
(should (string= (ob-elixir--hash-deps multiline1)
|
||||
(ob-elixir--hash-deps multiline2)))))
|
||||
|
||||
(ert-deftest ob-elixir-test-deps-block-with-comments ()
|
||||
"Test deps block parsing with Elixir comments."
|
||||
(with-temp-buffer
|
||||
(insert "#+BEGIN_DEPS elixir\n")
|
||||
(insert "[\n")
|
||||
(insert " # JSON library\n")
|
||||
(insert " {:jason, \"~> 1.4\"}\n")
|
||||
(insert "]\n")
|
||||
(insert "#+END_DEPS\n\n")
|
||||
(insert "#+BEGIN_SRC elixir\ncode\n#+END_SRC\n")
|
||||
(goto-char (point-max))
|
||||
(let ((deps (ob-elixir--find-deps-for-position (point))))
|
||||
(should deps)
|
||||
(should (string-match-p ":jason" deps)))))
|
||||
|
||||
;;; Mix Project Template Tests
|
||||
|
||||
(ert-deftest ob-elixir-test-mix-exs-template ()
|
||||
"Test that mix.exs template is valid."
|
||||
(should (stringp ob-elixir--mix-exs-template))
|
||||
(should (string-match-p "defmodule" ob-elixir--mix-exs-template))
|
||||
(should (string-match-p "use Mix.Project" ob-elixir--mix-exs-template))
|
||||
(should (string-match-p "deps()" ob-elixir--mix-exs-template))
|
||||
(should (string-match-p "%s" ob-elixir--mix-exs-template)))
|
||||
|
||||
(ert-deftest ob-elixir-test-mix-exs-generation ()
|
||||
"Test generating mix.exs content."
|
||||
(let ((deps "[{:jason, \"~> 1.4\"}]")
|
||||
(mix-exs (format ob-elixir--mix-exs-template "[{:jason, \"~> 1.4\"}]")))
|
||||
(should (string-match-p ":jason" mix-exs))
|
||||
(should (string-match-p "~> 1.4" mix-exs))))
|
||||
|
||||
;;; Cache Directory Tests
|
||||
|
||||
(ert-deftest ob-elixir-test-cache-dir-default ()
|
||||
"Test default cache directory."
|
||||
(should (stringp ob-elixir-deps-cache-dir))
|
||||
(should (string-match-p "ob-elixir" ob-elixir-deps-cache-dir)))
|
||||
|
||||
;;; Integration Tests (require network and mix)
|
||||
|
||||
(ert-deftest ob-elixir-test-deps-project-creation ()
|
||||
"Test creating a temporary Mix project with deps."
|
||||
:tags '(:integration :network)
|
||||
(skip-unless (and (executable-find "mix")
|
||||
(executable-find "elixir")))
|
||||
(let ((ob-elixir-deps-cache-dir (make-temp-file "ob-elixir-test-" t))
|
||||
(deps "[{:jason, \"~> 1.4\"}]"))
|
||||
(unwind-protect
|
||||
(let ((project-dir (ob-elixir--get-deps-project deps)))
|
||||
(should (file-directory-p project-dir))
|
||||
(should (file-exists-p (expand-file-name "mix.exs" project-dir)))
|
||||
(should (file-directory-p (expand-file-name "deps/jason" project-dir))))
|
||||
;; Cleanup
|
||||
(ob-elixir-cleanup-deps-projects)
|
||||
(when (file-directory-p ob-elixir-deps-cache-dir)
|
||||
(delete-directory ob-elixir-deps-cache-dir t)))))
|
||||
|
||||
(ert-deftest ob-elixir-test-deps-execution ()
|
||||
"Test executing code with deps."
|
||||
:tags '(:integration :network)
|
||||
(skip-unless (and (executable-find "mix")
|
||||
(executable-find "elixir")))
|
||||
(let ((ob-elixir-deps-cache-dir (make-temp-file "ob-elixir-test-" t))
|
||||
(deps "[{:jason, \"~> 1.4\"}]"))
|
||||
(unwind-protect
|
||||
(let ((result (ob-elixir--execute-with-deps
|
||||
"Jason.encode!(%{a: 1})"
|
||||
'value
|
||||
deps)))
|
||||
;; Result should contain JSON output with key "a"
|
||||
;; Jason.encode! returns "{\"a\":1}" which when inspected becomes "\"{\\\"a\\\":1}\""
|
||||
(should (string-match-p "a" result)))
|
||||
;; Cleanup
|
||||
(ob-elixir-cleanup-deps-projects)
|
||||
(when (file-directory-p ob-elixir-deps-cache-dir)
|
||||
(delete-directory ob-elixir-deps-cache-dir t)))))
|
||||
|
||||
(ert-deftest ob-elixir-test-deps-caching ()
|
||||
"Test that deps projects are cached and reused."
|
||||
:tags '(:integration :network)
|
||||
(skip-unless (executable-find "mix"))
|
||||
(let ((ob-elixir-deps-cache-dir (make-temp-file "ob-elixir-test-" t))
|
||||
(deps "[{:jason, \"~> 1.4\"}]"))
|
||||
(unwind-protect
|
||||
(let ((project1 (ob-elixir--get-deps-project deps))
|
||||
(project2 (ob-elixir--get-deps-project deps)))
|
||||
;; Should return same directory
|
||||
(should (string= project1 project2))
|
||||
;; Should only have one entry in hash table
|
||||
(should (= 1 (hash-table-count ob-elixir--deps-projects))))
|
||||
;; Cleanup
|
||||
(ob-elixir-cleanup-deps-projects)
|
||||
(when (file-directory-p ob-elixir-deps-cache-dir)
|
||||
(delete-directory ob-elixir-deps-cache-dir t)))))
|
||||
|
||||
(ert-deftest ob-elixir-test-different-deps-different-projects ()
|
||||
"Test that different deps create different projects."
|
||||
:tags '(:integration :network)
|
||||
(skip-unless (executable-find "mix"))
|
||||
(let ((ob-elixir-deps-cache-dir (make-temp-file "ob-elixir-test-" t))
|
||||
(deps1 "[{:jason, \"~> 1.4\"}]")
|
||||
(deps2 "[{:decimal, \"~> 2.0\"}]"))
|
||||
(unwind-protect
|
||||
(let ((project1 (ob-elixir--get-deps-project deps1))
|
||||
(project2 (ob-elixir--get-deps-project deps2)))
|
||||
;; Should be different directories
|
||||
(should-not (string= project1 project2))
|
||||
;; Should have two entries in hash table
|
||||
(should (= 2 (hash-table-count ob-elixir--deps-projects))))
|
||||
;; Cleanup
|
||||
(ob-elixir-cleanup-deps-projects)
|
||||
(when (file-directory-p ob-elixir-deps-cache-dir)
|
||||
(delete-directory ob-elixir-deps-cache-dir t)))))
|
||||
|
||||
;;; Cleanup Tests
|
||||
|
||||
(ert-deftest ob-elixir-test-cleanup-clears-hash-table ()
|
||||
"Test that cleanup clears the hash table."
|
||||
(let ((ob-elixir--deps-projects (make-hash-table :test 'equal)))
|
||||
(puthash "test-hash" "/tmp/test-dir" ob-elixir--deps-projects)
|
||||
(should (= 1 (hash-table-count ob-elixir--deps-projects)))
|
||||
;; Cleanup should clear the table (dir doesn't exist, so no error)
|
||||
(ob-elixir-cleanup-deps-projects)
|
||||
(should (= 0 (hash-table-count ob-elixir--deps-projects)))))
|
||||
|
||||
(provide 'test-ob-elixir-deps)
|
||||
;;; test-ob-elixir-deps.el ends here
|
||||
Reference in New Issue
Block a user