summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/fixtures/grammar-correct.txt5
-rw-r--r--tests/fixtures/grammar-errors-basic.txt7
-rw-r--r--tests/fixtures/grammar-errors-punctuation.txt5
-rw-r--r--tests/test-flycheck-languagetool-setup.el71
-rw-r--r--tests/test-integration-grammar-checking.el190
-rw-r--r--tests/test-transcription-config--transcription-script-path.el106
6 files changed, 384 insertions, 0 deletions
diff --git a/tests/fixtures/grammar-correct.txt b/tests/fixtures/grammar-correct.txt
new file mode 100644
index 00000000..bea335e8
--- /dev/null
+++ b/tests/fixtures/grammar-correct.txt
@@ -0,0 +1,5 @@
+This is a well-written sentence with no grammar errors.
+
+The quick brown fox jumps over the lazy dog.
+
+Everything here follows standard English grammar rules.
diff --git a/tests/fixtures/grammar-errors-basic.txt b/tests/fixtures/grammar-errors-basic.txt
new file mode 100644
index 00000000..c2f72c12
--- /dev/null
+++ b/tests/fixtures/grammar-errors-basic.txt
@@ -0,0 +1,7 @@
+This are a test of basic grammar errors.
+
+I could of done better with this sentence.
+
+Their going to the store to buy there groceries.
+
+The dog wagged it's tail happily.
diff --git a/tests/fixtures/grammar-errors-punctuation.txt b/tests/fixtures/grammar-errors-punctuation.txt
new file mode 100644
index 00000000..37de646a
--- /dev/null
+++ b/tests/fixtures/grammar-errors-punctuation.txt
@@ -0,0 +1,5 @@
+This sentence is missing punctuation at the end
+
+Multiple spaces between words should be detected.
+
+A sentence with,incorrect comma,placement and usage.
diff --git a/tests/test-flycheck-languagetool-setup.el b/tests/test-flycheck-languagetool-setup.el
new file mode 100644
index 00000000..a719e822
--- /dev/null
+++ b/tests/test-flycheck-languagetool-setup.el
@@ -0,0 +1,71 @@
+;;; test-flycheck-languagetool-setup.el --- Unit tests for LanguageTool setup -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Unit tests verifying LanguageTool installation and wrapper script setup.
+;; Focus: Testing OUR code (wrapper script, file setup), not flycheck internals.
+;;
+;; We trust that flycheck works correctly (it's an external framework).
+;; These tests verify:
+;; - LanguageTool is installed and accessible
+;; - Our wrapper script exists, is executable, and has correct structure
+;; - Python 3 dependency is available
+;;
+;; Categories: Normal (installation checks), Boundary (script structure), Error (missing dependencies)
+
+;;; Code:
+
+(require 'ert)
+
+;; ----------------------------- Normal Cases ----------------------------------
+
+(ert-deftest test-flycheck-languagetool-setup-normal-wrapper-exists ()
+ "Test that languagetool-flycheck wrapper script exists."
+ (let ((wrapper-path (expand-file-name "~/.emacs.d/scripts/languagetool-flycheck")))
+ (should (file-exists-p wrapper-path))))
+
+(ert-deftest test-flycheck-languagetool-setup-normal-wrapper-executable ()
+ "Test that languagetool-flycheck wrapper script is executable."
+ (let ((wrapper-path (expand-file-name "~/.emacs.d/scripts/languagetool-flycheck")))
+ (should (file-executable-p wrapper-path))))
+
+(ert-deftest test-flycheck-languagetool-setup-normal-languagetool-installed ()
+ "Test that languagetool command is available in PATH."
+ (should (executable-find "languagetool")))
+
+(ert-deftest test-flycheck-languagetool-setup-normal-python3-available ()
+ "Test that python3 is available for wrapper script."
+ (should (executable-find "python3")))
+
+
+;; ----------------------------- Boundary Cases --------------------------------
+
+(ert-deftest test-flycheck-languagetool-setup-boundary-wrapper-script-format ()
+ "Test that wrapper script has correct shebang and structure."
+ (let ((wrapper-path (expand-file-name "~/.emacs.d/scripts/languagetool-flycheck")))
+ (with-temp-buffer
+ (insert-file-contents wrapper-path)
+ (goto-char (point-min))
+ ;; Check shebang
+ (should (looking-at "#!/usr/bin/env python3"))
+ ;; Check it contains required imports
+ (should (search-forward "import json" nil t))
+ (should (search-forward "import subprocess" nil t)))))
+
+;; ----------------------------- Error Cases -----------------------------------
+
+(ert-deftest test-flycheck-languagetool-setup-error-missing-file-argument ()
+ "Test that wrapper script requires file argument.
+When called without arguments, wrapper should exit with error."
+ (let* ((wrapper (expand-file-name "~/.emacs.d/scripts/languagetool-flycheck"))
+ (exit-code nil))
+ (with-temp-buffer
+ (setq exit-code (call-process wrapper nil t nil))
+ ;; Should exit with non-zero status when no file provided
+ (should-not (= 0 exit-code))
+ ;; Should print usage message to stderr (captured in buffer)
+ (goto-char (point-min))
+ (should (or (search-forward "Usage:" nil t)
+ (search-forward "FILE" nil t))))))
+
+(provide 'test-flycheck-languagetool-setup)
+;;; test-flycheck-languagetool-setup.el ends here
diff --git a/tests/test-integration-grammar-checking.el b/tests/test-integration-grammar-checking.el
new file mode 100644
index 00000000..8948c17a
--- /dev/null
+++ b/tests/test-integration-grammar-checking.el
@@ -0,0 +1,190 @@
+;;; test-integration-grammar-checking.el --- Integration tests for grammar checking -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Integration tests for the LanguageTool wrapper script with real grammar checking.
+;; Tests the integration: test fixture → wrapper script → LanguageTool → formatted output
+;;
+;; Components integrated:
+;; - scripts/languagetool-flycheck (our wrapper script)
+;; - languagetool command (external grammar checker)
+;; - Test fixtures with known grammar errors
+;; - Output formatting (JSON → flycheck format)
+;;
+;; Focus: Testing OUR integration code (wrapper), not flycheck framework.
+;; We trust that flycheck works; we test that our wrapper produces correct output.
+;;
+;; Categories: Normal workflow, Boundary cases, Error handling
+
+;;; Code:
+
+(require 'ert)
+
+;; ----------------------------- Test Helpers ----------------------------------
+
+(defun test-integration-grammar--fixture-path (filename)
+ "Return absolute path to test fixture FILENAME."
+ (expand-file-name (concat "tests/fixtures/" filename)
+ user-emacs-directory))
+
+(defun test-integration-grammar--wrapper-output (file-path)
+ "Run languagetool-flycheck wrapper directly on FILE-PATH.
+Returns output as string."
+ (let ((wrapper (expand-file-name "~/.emacs.d/scripts/languagetool-flycheck")))
+ (with-temp-buffer
+ (call-process wrapper nil t nil file-path)
+ (buffer-string))))
+
+;; ----------------------------- Normal Cases ----------------------------------
+
+(ert-deftest test-integration-grammar-checking-normal-wrapper-detects-errors ()
+ "Test that wrapper script detects grammar errors in fixture.
+
+Components integrated:
+- scripts/languagetool-flycheck (wrapper script)
+- languagetool command (external checker)
+- Test fixture with known errors"
+ (let* ((fixture (test-integration-grammar--fixture-path "grammar-errors-basic.txt"))
+ (output (test-integration-grammar--wrapper-output fixture)))
+ ;; Should detect "This are" error
+ (should (string-match-p "PLURAL_VERB_AFTER_THIS\\|This are" output))
+ ;; Should detect "could of" error
+ (should (string-match-p "COULD_OF\\|could of" output))
+ ;; Output should be in flycheck format (filename:line:column:)
+ (should (string-match-p "grammar-errors-basic\\.txt:[0-9]+:[0-9]+:" output))))
+
+(ert-deftest test-integration-grammar-checking-normal-wrapper-format ()
+ "Test that wrapper outputs flycheck-compatible format.
+
+Components integrated:
+- scripts/languagetool-flycheck (output formatting)
+- languagetool command (JSON parsing)"
+ (let* ((fixture (test-integration-grammar--fixture-path "grammar-errors-basic.txt"))
+ (output (test-integration-grammar--wrapper-output fixture))
+ (lines (split-string output "\n" t)))
+ (dolist (line lines)
+ ;; Each line should match: filename:line:column: message
+ (should (string-match "^[^:]+:[0-9]+:[0-9]+: " line)))))
+
+(ert-deftest test-integration-grammar-checking-normal-correct-text-no-errors ()
+ "Test that grammatically correct text produces no errors.
+
+Components integrated:
+- scripts/languagetool-flycheck (wrapper script)
+- languagetool command (validation)
+- Test fixture with correct grammar"
+ (let* ((fixture (test-integration-grammar--fixture-path "grammar-correct.txt"))
+ (output (test-integration-grammar--wrapper-output fixture)))
+ ;; Correct grammar should produce no output (or only whitespace)
+ (should (or (string-empty-p (string-trim output))
+ (= 0 (length (string-trim output)))))))
+
+;; ----------------------------- Boundary Cases --------------------------------
+
+(ert-deftest test-integration-grammar-checking-boundary-empty-file ()
+ "Test that empty file produces no errors.
+
+Components integrated:
+- scripts/languagetool-flycheck (empty input handling)
+- languagetool command"
+ (let ((temp-file (make-temp-file "grammar-test-" nil ".txt")))
+ (unwind-protect
+ (let ((output (test-integration-grammar--wrapper-output temp-file)))
+ (should (or (string-empty-p (string-trim output))
+ (= 0 (length (string-trim output))))))
+ (delete-file temp-file))))
+
+(ert-deftest test-integration-grammar-checking-boundary-single-word ()
+ "Test that single word file produces no errors.
+
+Components integrated:
+- scripts/languagetool-flycheck (minimal input)
+- languagetool command"
+ (let ((temp-file (make-temp-file "grammar-test-" nil ".txt")))
+ (unwind-protect
+ (progn
+ (with-temp-file temp-file
+ (insert "Hello"))
+ (let ((output (test-integration-grammar--wrapper-output temp-file)))
+ ;; Single word might produce no errors or might flag as incomplete sentence
+ ;; Just verify it doesn't crash
+ (should (stringp output))))
+ (delete-file temp-file))))
+
+(ert-deftest test-integration-grammar-checking-boundary-multiple-paragraphs ()
+ "Test that file with multiple paragraphs is checked completely.
+
+Components integrated:
+- scripts/languagetool-flycheck (multi-paragraph handling)
+- languagetool command (full file processing)"
+ (let* ((fixture (test-integration-grammar--fixture-path "grammar-errors-basic.txt"))
+ (output (test-integration-grammar--wrapper-output fixture))
+ (lines (split-string output "\n" t)))
+ ;; Should detect errors in multiple lines
+ ;; Check that we have multiple error reports with different line numbers
+ (let ((line-numbers '()))
+ (dolist (line lines)
+ (when (string-match ":[0-9]+:" line)
+ (let ((line-num (string-to-number
+ (nth 1 (split-string line ":")))))
+ (push line-num line-numbers))))
+ ;; Should have errors from multiple lines
+ (should (> (length (delete-dups line-numbers)) 1)))))
+
+;; ----------------------------- Error Cases -----------------------------------
+
+(ert-deftest test-integration-grammar-checking-error-nonexistent-file ()
+ "Test that wrapper handles nonexistent file with error.
+
+Components integrated:
+- scripts/languagetool-flycheck (error handling)
+- File system (missing file)
+- Python exception handling"
+ (let* ((nonexistent "/tmp/this-file-does-not-exist-12345.txt")
+ (wrapper (expand-file-name "~/.emacs.d/scripts/languagetool-flycheck"))
+ (exit-code nil)
+ (output nil))
+ (with-temp-buffer
+ (setq exit-code (call-process wrapper nil t nil nonexistent))
+ (setq output (buffer-string)))
+ ;; LanguageTool/Python should handle the error
+ ;; Check that we get output (error message or error in flycheck format)
+ (should (stringp output))
+ ;; Output should contain some indication of the error (filename or error marker)
+ (should (or (string-match-p nonexistent output)
+ (string-match-p "error" output)
+ (string-match-p "Error" output)
+ ;; Or it might report no errors for a nonexistent file
+ (string-empty-p (string-trim output))))))
+
+(ert-deftest test-integration-grammar-checking-error-no-file-argument ()
+ "Test that wrapper requires file argument.
+
+Components integrated:
+- scripts/languagetool-flycheck (argument validation)"
+ (let* ((wrapper (expand-file-name "~/.emacs.d/scripts/languagetool-flycheck"))
+ (exit-code nil))
+ (with-temp-buffer
+ (setq exit-code (call-process wrapper nil t nil))
+ ;; Should exit with non-zero status when no file provided
+ (should-not (= 0 exit-code)))))
+
+;; ----------------------------- Integration with Real Files -------------------
+
+(ert-deftest test-integration-grammar-checking-integration-comprehensive-errors ()
+ "Test that wrapper catches multiple types of grammar errors in one file.
+
+Components integrated:
+- scripts/languagetool-flycheck (our wrapper)
+- languagetool command (comprehensive checking)
+- Test fixture with various error types"
+ (let* ((fixture (test-integration-grammar--fixture-path "grammar-errors-basic.txt"))
+ (output (test-integration-grammar--wrapper-output fixture))
+ (lines (split-string output "\n" t)))
+ ;; Should detect multiple errors (at least 3-4 in the fixture)
+ (should (>= (length lines) 3))
+ ;; All lines should be properly formatted
+ (dolist (line lines)
+ (should (string-match "^[^:]+:[0-9]+:[0-9]+: " line)))))
+
+(provide 'test-integration-grammar-checking)
+;;; test-integration-grammar-checking.el ends here
diff --git a/tests/test-transcription-config--transcription-script-path.el b/tests/test-transcription-config--transcription-script-path.el
new file mode 100644
index 00000000..a56cb05c
--- /dev/null
+++ b/tests/test-transcription-config--transcription-script-path.el
@@ -0,0 +1,106 @@
+;;; test-transcription-config--transcription-script-path.el --- Tests for cj/--transcription-script-path -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Tests for the cj/--transcription-script-path function from transcription-config.el
+;;
+;; This function returns the absolute path to the transcription script based on
+;; the current value of cj/transcribe-backend.
+
+;;; Code:
+
+(require 'ert)
+
+;; Add modules directory to load path
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+
+;; Stub dependencies before loading the module
+(defvar cj/custom-keymap (make-sparse-keymap)
+ "Stub keymap for testing.")
+
+;; Stub notification function
+(unless (fboundp 'notifications-notify)
+ (defun notifications-notify (&rest _args)
+ "Stub notification function for testing."
+ nil))
+
+;; Now load the actual production module
+(require 'transcription-config)
+
+;;; Setup and Teardown
+
+(defun test-transcription-script-path-setup ()
+ "Set up test environment."
+ ;; Save original backend setting
+ (setq test-transcription-original-backend cj/transcribe-backend))
+
+(defun test-transcription-script-path-teardown ()
+ "Clean up test environment."
+ ;; Restore original backend setting
+ (setq cj/transcribe-backend test-transcription-original-backend))
+
+;;; Normal Cases
+
+(ert-deftest test-transcription-config--transcription-script-path-normal-openai-api-returns-oai-transcribe ()
+ "Should return oai-transcribe script path for openai-api backend."
+ (test-transcription-script-path-setup)
+ (unwind-protect
+ (progn
+ (setq cj/transcribe-backend 'openai-api)
+ (let ((result (cj/--transcription-script-path)))
+ (should (stringp result))
+ (should (string-suffix-p "scripts/oai-transcribe" result))
+ (should (string-prefix-p (expand-file-name user-emacs-directory) result))))
+ (test-transcription-script-path-teardown)))
+
+(ert-deftest test-transcription-config--transcription-script-path-normal-assemblyai-returns-assemblyai-transcribe ()
+ "Should return assemblyai-transcribe script path for assemblyai backend."
+ (test-transcription-script-path-setup)
+ (unwind-protect
+ (progn
+ (setq cj/transcribe-backend 'assemblyai)
+ (let ((result (cj/--transcription-script-path)))
+ (should (stringp result))
+ (should (string-suffix-p "scripts/assemblyai-transcribe" result))
+ (should (string-prefix-p (expand-file-name user-emacs-directory) result))))
+ (test-transcription-script-path-teardown)))
+
+(ert-deftest test-transcription-config--transcription-script-path-normal-local-whisper-returns-local-whisper ()
+ "Should return local-whisper script path for local-whisper backend."
+ (test-transcription-script-path-setup)
+ (unwind-protect
+ (progn
+ (setq cj/transcribe-backend 'local-whisper)
+ (let ((result (cj/--transcription-script-path)))
+ (should (stringp result))
+ (should (string-suffix-p "scripts/local-whisper" result))
+ (should (string-prefix-p (expand-file-name user-emacs-directory) result))))
+ (test-transcription-script-path-teardown)))
+
+(ert-deftest test-transcription-config--transcription-script-path-normal-returns-absolute-path ()
+ "Should return absolute path starting with user-emacs-directory."
+ (test-transcription-script-path-setup)
+ (unwind-protect
+ (progn
+ (setq cj/transcribe-backend 'openai-api)
+ (let ((result (cj/--transcription-script-path)))
+ (should (file-name-absolute-p result))
+ (should (string-prefix-p "/" result))))
+ (test-transcription-script-path-teardown)))
+
+;;; Boundary Cases
+
+(ert-deftest test-transcription-config--transcription-script-path-boundary-path-format-consistent ()
+ "Should return paths in consistent format across backends."
+ (test-transcription-script-path-setup)
+ (unwind-protect
+ (let (paths)
+ (dolist (backend '(openai-api assemblyai local-whisper))
+ (setq cj/transcribe-backend backend)
+ (push (cj/--transcription-script-path) paths))
+ ;; All paths should have same structure: <emacs-dir>/scripts/<name>
+ (should (= (length paths) 3))
+ (should (seq-every-p (lambda (p) (string-match-p "/scripts/[^/]+$" p)) paths)))
+ (test-transcription-script-path-teardown)))
+
+(provide 'test-transcription-config--transcription-script-path)
+;;; test-transcription-config--transcription-script-path.el ends here