aboutsummaryrefslogtreecommitdiff
path: root/tests/test-dev-fkeys--f6-test-runner-cmd-for.el
blob: 9a55261252a6933a8a397053ddf8389e8d92527c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
;;; test-dev-fkeys--f6-test-runner-cmd-for.el --- Tests for cj/--f6-test-runner-cmd-for -*- lexical-binding: t -*-

;;; Commentary:
;; Tests for the per-language test-runner-command builder.
;;
;; Inputs are five primitives the orchestrator pre-computes:
;;
;;   LANGUAGE        symbol from `cj/--f6-language-detect'
;;   IS-TEST-FILE    boolean from `cj/--f6-buffer-is-test-file-p'
;;   REL-PATH        file path relative to project root
;;   STEM            source module stem from `cj/--f6-source-stem'
;;   REL-DIR         file's directory relative to project root
;;
;; Returns a shell command string to pipe through `compile', or nil for
;; languages we don't have a runner for. The TS / JS handlers are punted
;; for v1 — they return nil.

;;; Code:

(require 'ert)
(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
(require 'dev-fkeys)

;;; Normal Cases — Elisp

(ert-deftest test-dev-fkeys-f6-cmd-for-elisp-test-file ()
  "Normal: an elisp test file runs via `make test-file FILE=<basename>'.
The project Makefile prepends `tests/' to whatever FILE you pass, so the
runner command must use just the basename (not the rel-path) to avoid
`tests/tests/...' double-prefix."
  (should (string=
           (cj/--f6-test-runner-cmd-for
            'elisp t "tests/test-foo.el" "foo" "tests")
           "make test-file FILE=test-foo.el")))

(ert-deftest test-dev-fkeys-f6-cmd-for-elisp-source-file ()
  "Normal: an elisp source file runs via `make test-name TEST=^test-<stem>-'.
The trailing hyphen anchors the regex so test names from a different
module that happen to share a prefix don't get pulled in."
  (should (string=
           (cj/--f6-test-runner-cmd-for
            'elisp nil "modules/foo.el" "foo" "modules")
           "make test-name TEST=^test-foo-")))

;;; Normal Cases — Python

(ert-deftest test-dev-fkeys-f6-cmd-for-python-test-file ()
  "Normal: a Python test file runs via `pytest <rel-path>'."
  (should (string=
           (cj/--f6-test-runner-cmd-for
            'python t "tests/test_foo.py" "foo" "tests")
           "pytest tests/test_foo.py")))

(ert-deftest test-dev-fkeys-f6-cmd-for-python-source-file ()
  "Normal: a Python source file runs via `pytest tests/test_<stem>.py'."
  (should (string=
           (cj/--f6-test-runner-cmd-for
            'python nil "pkg/foo.py" "foo" "pkg")
           "pytest tests/test_foo.py")))

;;; Normal Cases — Go

(ert-deftest test-dev-fkeys-f6-cmd-for-go-test-file ()
  "Normal: a Go test file runs the package via `go test ./<rel-dir>'."
  (should (string=
           (cj/--f6-test-runner-cmd-for
            'go t "pkg/foo_test.go" "foo" "pkg")
           "go test ./pkg")))

(ert-deftest test-dev-fkeys-f6-cmd-for-go-source-file ()
  "Normal: a Go source file runs the same package via `go test ./<rel-dir>'.
Go test scope is per-package; running the source's package picks up its
test files."
  (should (string=
           (cj/--f6-test-runner-cmd-for
            'go nil "pkg/foo.go" "foo" "pkg")
           "go test ./pkg")))

;;; Boundary Cases

(ert-deftest test-dev-fkeys-f6-cmd-for-elisp-test-file-with-double-dash ()
  "Boundary: a per-helper test file runs only that file, not the whole
test-name prefix. `make test-file FILE=...' is precise; `test-name'
would over-match. Pass just the basename — the Makefile re-prepends
`tests/' itself."
  (should (string=
           (cj/--f6-test-runner-cmd-for
            'elisp t "tests/test-foo--bar.el" "foo" "tests")
           "make test-file FILE=test-foo--bar.el")))

(ert-deftest test-dev-fkeys-f6-cmd-for-go-source-at-root ()
  "Boundary: a Go source file at project root runs `go test ./'."
  (should (string=
           (cj/--f6-test-runner-cmd-for
            'go nil "main.go" "main" "")
           "go test ./")))

(ert-deftest test-dev-fkeys-f6-cmd-for-python-test-file-quotes-spaces ()
  "Boundary: a Python test file path with spaces is shell-escaped."
  (should (string=
           (cj/--f6-test-runner-cmd-for
            'python t "tests/dir with spaces/test_foo.py" "foo" "tests/dir with spaces")
           "pytest tests/dir\\ with\\ spaces/test_foo.py")))

(ert-deftest test-dev-fkeys-f6-cmd-for-elisp-source-quotes-test-regex ()
  "Boundary: an elisp source stem with shell metacharacters is escaped."
  (should (string=
           (cj/--f6-test-runner-cmd-for
            'elisp nil "modules/foo;bar.el" "foo;bar" "modules")
           "make test-name TEST=\\^test-foo\\;bar-")))

(ert-deftest test-dev-fkeys-f6-cmd-for-go-source-quotes-spaces ()
  "Boundary: a Go package path with spaces is shell-escaped."
  (should (string=
           (cj/--f6-test-runner-cmd-for
            'go nil "pkg/with spaces/foo.go" "foo" "pkg/with spaces")
           "go test ./pkg/with\\ spaces")))

;;; Error Cases

(ert-deftest test-dev-fkeys-f6-cmd-for-typescript-uses-jest-or-vitest ()
  "Normal: TypeScript builds an `npx vitest|jest <path>' command.
Picks vitest when on PATH, jest otherwise.  Falls back to jest as the
default runner so the command shape is always inspectable -- even if
neither tool is present, the user gets a clear runner-not-found error
rather than a silent nil that F6's outer wrapper interprets as
\"language unsupported.\""
  (cl-letf (((symbol-function 'executable-find)
             (lambda (_) nil)))
    (should (equal
             (cj/--f6-test-runner-cmd-for
              'typescript t "src/foo.test.ts" "foo" "src")
             "npx --no-install jest src/foo.test.ts")))
  (cl-letf (((symbol-function 'executable-find)
             (lambda (p) (when (equal p "vitest") "/usr/bin/vitest"))))
    (should (equal
             (cj/--f6-test-runner-cmd-for
              'typescript t "src/foo.test.ts" "foo" "src")
             "npx --no-install vitest src/foo.test.ts"))))

(ert-deftest test-dev-fkeys-f6-cmd-for-javascript-returns-nil ()
  "Error: JavaScript is punted for v1 and returns nil."
  (should (null (cj/--f6-test-runner-cmd-for
                 'javascript t "src/foo.test.js" "foo" "src"))))

(ert-deftest test-dev-fkeys-f6-cmd-for-unknown-returns-nil ()
  "Error: an unknown language returns nil."
  (should (null (cj/--f6-test-runner-cmd-for
                 'unknown nil "Makefile" "Makefile" ""))))

(provide 'test-dev-fkeys--f6-test-runner-cmd-for)
;;; test-dev-fkeys--f6-test-runner-cmd-for.el ends here