(string-match-p "spec" file))))
(defun my/matching-test-file-p (test-file base-name extension)
- (let ((found nil))
- (dolist (pattern (list
- (concat "test/.*" base-name "[^/]*\\." extension "$")
- (concat "spec/.*" base-name "[^/]*\\." extension "$")
- (concat "test[^/]*" base-name "[^/]*\\." extension "$")
- (concat base-name "[^/]*test\\." extension "$")
- (concat base-name "[^/]*spec\\." extension "$")))
- (if (string-match-p pattern test-file)
- (setq found t)))
- found))
+ (cl-loop for pattern in (list
+ (concat "test/.*" base-name "[^/]*\\." extension "$")
+ (concat "spec/.*" base-name "[^/]*\\." extension "$")
+ (concat "test[^/]*" base-name "[^/]*\\." extension "$")
+ (concat base-name "[^/]*test\\." extension "$")
+ (concat base-name "[^/]*spec\\." extension "$"))
+ for matched = (string-match-p pattern test-file)
+ until matched
+ finally return (not (null matched))))
(defun my/matching-prod-file-p (prod-file base-name extension)
- (dolist (pattern '("test" "spec" "^\\.*" "\\.*$"))
+ (dolist (pattern '("test" "it.spec" "spec" "^\\.*" "\\.*$"))
(setq base-name (replace-regexp-in-string pattern "" base-name)))
(and (my/prod-file-p prod-file)
(string-match-p (concat base-name "[^/]*\\." extension "$") prod-file)))
-(defun my/find-prod-or-test-file ()
- "Find test file in the current Git repository."
- (interactive)
-
- (setq counsel--git-dir (locate-dominating-file
- default-directory ".git"))
- (if (null counsel--git-dir)
- (error "Not in a git repository")
- (setq counsel--git-dir (expand-file-name
- counsel--git-dir))
-
- (let* ((default-directory counsel--git-dir)
- (files (split-string
- (shell-command-to-string counsel-git-cmd)
- "\n"
- t))
- (base-name (file-name-sans-extension (file-name-nondirectory (buffer-file-name))))
- (extension (file-name-extension (buffer-file-name)))
- (predicate (if (my/prod-file-p (buffer-file-name)) #'my/matching-test-file-p #'my/matching-prod-file-p))
- (results nil))
-
- (dolist (file files)
- (if (funcall predicate file base-name extension)
- (cl-pushnew file results)))
-
- (cl-case (length results)
- (0 (message "No matching file found."))
- (1 (find-file (car results)))
- (t (ivy-read "Find test file" results
- :action #'counsel-git-action
- :caller 'counsel-git))))))
+(defun my/find-prod-or-test-file (&optional initial-directory)
+ "Find test file in the current project.
+INITIAL-DIRECTORY, if non-nil, is used as the root directory for search."
+ (interactive
+ (list (when current-prefix-arg
+ (read-directory-name "From directory: "))))
+ (counsel-require-program "rg")
+
+ (let* ((default-directory (or initial-directory
+ (locate-dominating-file default-directory ".git")
+ default-directory))
+ (files (split-string
+ (shell-command-to-string counsel-rg-files-command)
+ "\n"
+ t))
+ (base-name (file-name-sans-extension (file-name-nondirectory (buffer-file-name))))
+ (extension (file-name-extension (buffer-file-name)))
+ (predicate (if (my/prod-file-p (buffer-file-name)) #'my/matching-test-file-p #'my/matching-prod-file-p))
+ (results nil))
+
+ (dolist (file files)
+ (if (funcall predicate file base-name extension)
+ (cl-pushnew file results)))
+
+ (cl-case (length results)
+ (0 (message "No matching file found."))
+ (1 (find-file (car results)))
+ (t (ivy-read "Find test file" results
+ :action #'counsel-git-action
+ :caller 'my/find-prod-or-test-file)))))