Skip to content

Commit c593dbe

Browse files
Copilottninja
andauthored
Add test coverage for refactored filepath candidate functions (#156)
* Initial plan * Add tests for refactored helper functions and behaviors Co-authored-by: tninja <714625+tninja@users.noreply.github.com> * Fix trailing whitespace in test Co-authored-by: tninja <714625+tninja@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: tninja <714625+tninja@users.noreply.github.com>
1 parent 9d888db commit c593dbe

1 file changed

Lines changed: 255 additions & 0 deletions

File tree

test/test_ai-code-prompt-mode.el

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,261 @@ and ensures everything is cleaned up afterward."
411411
(when (file-exists-p test-file-2) (delete-file test-file-2))
412412
(when (file-exists-p test-file-3) (delete-file test-file-3))))))
413413

414+
(ert-deftest ai-code-test-normalize-path ()
415+
"Test that ai-code--normalize-path returns correct normalized paths."
416+
(ai-code-with-test-repo
417+
(let ((existing-file mock-file-in-repo)
418+
(non-existing-file (expand-file-name "non-existent.el" git-root)))
419+
;; Test with existing file - should return truename
420+
(let ((result (ai-code--normalize-path existing-file)))
421+
(should (string= result (file-truename existing-file))))
422+
423+
;; Test with non-existing file - should return expanded path
424+
(let ((result (ai-code--normalize-path non-existing-file)))
425+
(should (string= result (expand-file-name non-existing-file)))))))
426+
427+
(ert-deftest ai-code-test-candidate-path-in-repo ()
428+
"Test that ai-code--candidate-path returns relative path for in-repo files."
429+
(ai-code-with-test-repo
430+
(let ((test-file (expand-file-name "src/test.el" git-root)))
431+
(unwind-protect
432+
(progn
433+
;; Create test file
434+
(make-directory (file-name-directory test-file) t)
435+
(with-temp-file test-file (insert "content"))
436+
437+
(let ((result (ai-code--candidate-path test-file (file-truename git-root))))
438+
;; Should return relative path with @ prefix
439+
(should (string= result "@src/test.el"))))
440+
441+
;; Cleanup
442+
(when (file-exists-p test-file) (delete-file test-file))))))
443+
444+
(ert-deftest ai-code-test-candidate-path-out-of-repo ()
445+
"Test that ai-code--candidate-path returns absolute path for out-of-repo files."
446+
(ai-code-with-test-repo
447+
(let ((out-file (expand-file-name "outside.el" temporary-file-directory)))
448+
(unwind-protect
449+
(progn
450+
;; Create file outside repo
451+
(with-temp-file out-file (insert "content"))
452+
453+
(let ((result (ai-code--candidate-path out-file (file-truename git-root))))
454+
;; Should return absolute path (truename)
455+
(should (string= result (file-truename out-file)))))
456+
457+
;; Cleanup
458+
(when (file-exists-p out-file) (delete-file out-file))))))
459+
460+
(ert-deftest ai-code-test-visible-window-files ()
461+
"Test that ai-code--visible-window-files returns files from visible windows."
462+
(ai-code-with-test-repo
463+
(let ((test-file-1 (expand-file-name "file1.el" git-root))
464+
(test-file-2 (expand-file-name "file2.el" git-root)))
465+
(unwind-protect
466+
(progn
467+
;; Create test files
468+
(with-temp-file test-file-1 (insert "content1"))
469+
(with-temp-file test-file-2 (insert "content2"))
470+
471+
;; Open files in buffers
472+
(let ((buf1 (find-file-noselect test-file-1))
473+
(buf2 (find-file-noselect test-file-2)))
474+
(unwind-protect
475+
(progn
476+
;; Mock window-list to simulate visible windows
477+
(cl-letf (((symbol-function 'window-list)
478+
(lambda (&optional frame no-minibuf)
479+
(list (selected-window))))
480+
((symbol-function 'window-buffer)
481+
(lambda (win)
482+
(if (eq win (selected-window))
483+
buf1
484+
buf2)))
485+
((symbol-function 'selected-window)
486+
(lambda () 'mock-window)))
487+
(let ((result (ai-code--visible-window-files)))
488+
;; Should contain the file from the mocked window
489+
(should (member test-file-1 result))
490+
;; Should not filter by git repo (unlike old implementation)
491+
(should (= 1 (length result))))))
492+
493+
;; Kill buffers
494+
(when (buffer-live-p buf1) (kill-buffer buf1))
495+
(when (buffer-live-p buf2) (kill-buffer buf2)))))
496+
497+
;; Cleanup
498+
(when (file-exists-p test-file-1) (delete-file test-file-1))
499+
(when (file-exists-p test-file-2) (delete-file test-file-2))))))
500+
501+
(ert-deftest ai-code-test-recent-buffer-paths ()
502+
"Test that ai-code--recent-buffer-paths returns recent buffer paths."
503+
(ai-code-with-test-repo
504+
(let ((test-file-1 (expand-file-name "recent1.el" git-root))
505+
(test-file-2 (expand-file-name "recent2.el" git-root))
506+
(test-file-3 (expand-file-name "recent3.el" git-root)))
507+
(unwind-protect
508+
(progn
509+
;; Create test files
510+
(with-temp-file test-file-1 (insert "content1"))
511+
(with-temp-file test-file-2 (insert "content2"))
512+
(with-temp-file test-file-3 (insert "content3"))
513+
514+
;; Open files in buffers (most recent first in buffer-list)
515+
(let ((buf1 (find-file-noselect test-file-1))
516+
(buf2 (find-file-noselect test-file-2))
517+
(buf3 (find-file-noselect test-file-3)))
518+
(unwind-protect
519+
(progn
520+
(let ((result (ai-code--recent-buffer-paths (file-truename git-root))))
521+
;; Should return candidate paths (relative with @ prefix for in-repo)
522+
(should (member "@recent1.el" result))
523+
(should (member "@recent2.el" result))
524+
(should (member "@recent3.el" result))
525+
;; Should limit to 5 files
526+
(should (<= (length result) 5))))
527+
528+
;; Kill buffers
529+
(when (buffer-live-p buf1) (kill-buffer buf1))
530+
(when (buffer-live-p buf2) (kill-buffer buf2))
531+
(when (buffer-live-p buf3) (kill-buffer buf3)))))
532+
533+
;; Cleanup
534+
(when (file-exists-p test-file-1) (delete-file test-file-1))
535+
(when (file-exists-p test-file-2) (delete-file test-file-2))
536+
(when (file-exists-p test-file-3) (delete-file test-file-3))))))
537+
538+
(ert-deftest ai-code-test-recent-buffer-paths-includes-dired ()
539+
"Test that ai-code--recent-buffer-paths includes dired directories."
540+
(ai-code-with-test-repo
541+
(let ((dired-dir (expand-file-name "testdir/" git-root))
542+
(dired-buf nil))
543+
(unwind-protect
544+
(progn
545+
;; Create test directory
546+
(make-directory dired-dir t)
547+
548+
;; Open dired buffer
549+
(setq dired-buf (dired-noselect dired-dir))
550+
551+
(let ((result (ai-code--recent-buffer-paths (file-truename git-root))))
552+
;; Should include the dired directory
553+
(should (member "@testdir/" result))))
554+
555+
;; Cleanup
556+
(when (buffer-live-p dired-buf) (kill-buffer dired-buf))
557+
(when (file-directory-p dired-dir) (delete-directory dired-dir))))))
558+
559+
(ert-deftest ai-code-test-current-frame-dired-paths ()
560+
"Test that ai-code--current-frame-dired-paths returns dired directories."
561+
(ai-code-with-test-repo
562+
(let ((dired-dir-1 (expand-file-name "src/" git-root))
563+
(dired-dir-2 (expand-file-name "test/" git-root))
564+
(dired-buf-1 nil)
565+
(dired-buf-2 nil))
566+
(unwind-protect
567+
(progn
568+
;; Create test directories
569+
(make-directory dired-dir-1 t)
570+
(make-directory dired-dir-2 t)
571+
572+
;; Open dired buffers
573+
(setq dired-buf-1 (dired-noselect dired-dir-1))
574+
(setq dired-buf-2 (dired-noselect dired-dir-2))
575+
576+
;; Mock window-list and git-ignored check
577+
(cl-letf (((symbol-function 'window-list)
578+
(lambda (&optional frame no-minibuf)
579+
(list 'win1 'win2)))
580+
((symbol-function 'window-buffer)
581+
(lambda (win)
582+
(if (eq win 'win1) dired-buf-1 dired-buf-2)))
583+
((symbol-function 'ai-code--git-ignored-repo-file-p)
584+
(lambda (file root) nil)))
585+
586+
(let ((result (ai-code--current-frame-dired-paths (file-truename git-root))))
587+
;; Should include both dired directories
588+
(should (member "@src/" result))
589+
(should (member "@test/" result)))))
590+
591+
;; Cleanup
592+
(when (buffer-live-p dired-buf-1) (kill-buffer dired-buf-1))
593+
(when (buffer-live-p dired-buf-2) (kill-buffer dired-buf-2))
594+
(when (file-directory-p dired-dir-1) (delete-directory dired-dir-1))
595+
(when (file-directory-p dired-dir-2) (delete-directory dired-dir-2))))))
596+
597+
(ert-deftest ai-code-test-prompt-filepath-candidates-prioritizes-visible-windows ()
598+
"Test that ai-code--prompt-filepath-candidates prioritizes visible window files."
599+
(ai-code-with-test-repo
600+
(let ((visible-file (expand-file-name "visible.el" git-root))
601+
(buffer-file (expand-file-name "buffer.el" git-root)))
602+
(unwind-protect
603+
(progn
604+
;; Create test files
605+
(with-temp-file visible-file (insert "visible"))
606+
(with-temp-file buffer-file (insert "buffer"))
607+
608+
;; Mock dependencies
609+
(cl-letf (((symbol-function 'ai-code--git-ignored-repo-file-p)
610+
(lambda (file root) nil))
611+
((symbol-function 'ai-code--visible-window-files)
612+
(lambda () (list visible-file)))
613+
((symbol-function 'ai-code--current-frame-dired-paths)
614+
(lambda (root) '()))
615+
((symbol-function 'ai-code--recent-buffer-paths)
616+
(lambda (root) '()))
617+
((symbol-function 'ai-code--buffer-file-list)
618+
(lambda (root skip) (list buffer-file)))
619+
((symbol-function 'ai-code--repo-recent-files)
620+
(lambda (root) '())))
621+
622+
(let ((candidates (ai-code--prompt-filepath-candidates)))
623+
;; Visible file should come before buffer file
624+
(should (equal candidates '("@visible.el" "@buffer.el"))))))
625+
626+
;; Cleanup
627+
(when (file-exists-p visible-file) (delete-file visible-file))
628+
(when (file-exists-p buffer-file) (delete-file buffer-file))))))
629+
630+
(ert-deftest ai-code-test-prompt-filepath-candidates-includes-dired-directories ()
631+
"Test that ai-code--prompt-filepath-candidates includes dired directories from current frame."
632+
(ai-code-with-test-repo
633+
(let ((test-file (expand-file-name "file.el" git-root)))
634+
(unwind-protect
635+
(progn
636+
;; Create test file
637+
(with-temp-file test-file (insert "content"))
638+
639+
;; Mock dependencies
640+
(cl-letf (((symbol-function 'ai-code--git-ignored-repo-file-p)
641+
(lambda (_file _root) nil))
642+
((symbol-function 'ai-code--visible-window-files)
643+
(lambda () '()))
644+
((symbol-function 'ai-code--current-frame-dired-paths)
645+
(lambda (_root) '("@src/" "@test/")))
646+
((symbol-function 'ai-code--recent-buffer-paths)
647+
(lambda (_root) '()))
648+
((symbol-function 'ai-code--buffer-file-list)
649+
(lambda (_root _skip) (list test-file)))
650+
((symbol-function 'ai-code--repo-recent-files)
651+
(lambda (_root) '())))
652+
653+
(let ((candidates (ai-code--prompt-filepath-candidates)))
654+
;; Both dired directories should be included in candidates
655+
(should (member "@src/" candidates))
656+
(should (member "@test/" candidates))
657+
;; Test file should also be included
658+
(should (member "@file.el" candidates))
659+
;; Dired directories should come before buffer files
660+
(let ((src-pos (cl-position "@src/" candidates :test #'string=))
661+
(test-pos (cl-position "@test/" candidates :test #'string=))
662+
(file-pos (cl-position "@file.el" candidates :test #'string=)))
663+
(should (< src-pos file-pos))
664+
(should (< test-pos file-pos))))))
665+
666+
;; Cleanup
667+
(when (file-exists-p test-file) (delete-file test-file))))))
668+
414669
(ert-deftest ai-code-test-prompt-filepath-candidates-excludes-current-file ()
415670
"Test that ai-code--prompt-filepath-candidates excludes the current file."
416671
(ai-code-with-test-repo

0 commit comments

Comments
 (0)