diff options
| author | Craig Jennings <c@cjennings.net> | 2025-11-04 23:35:07 -0600 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2025-11-04 23:35:07 -0600 |
| commit | 9d99ca0e41d0ccd6e8861ef6701da58c5b00a547 (patch) | |
| tree | 354ba854ed0d96fb70f2227bc3efecd8f1f415b7 /tests/test-integration-grammar-checking.el | |
| parent | eda461086e94265b67ab5b21032e7ee23112ad87 (diff) | |
test: Add comprehensive test suite for LanguageTool grammar checking
Created complete test coverage for the LanguageTool integration:
Unit Tests (test-flycheck-languagetool-setup.el):
- 6 tests covering installation and configuration
- Verifies LanguageTool binary availability
- Checks wrapper script exists and is executable
- Validates wrapper script structure (shebang, imports)
- Tests error handling for missing arguments
- All tests pass ✓
Integration Tests (test-integration-grammar-checking.el):
- 9 tests covering end-to-end grammar checking workflow
- Tests wrapper script with real LanguageTool execution
- Validates output format (filename:line:column: message)
- Tests normal cases (error detection, formatting)
- Tests boundary cases (empty files, single word, multiple paragraphs)
- Tests error cases (nonexistent files, missing arguments)
- Uses real test fixtures with known grammar errors
- All tests pass ✓ (takes ~35 seconds due to LanguageTool execution)
Test Fixtures (tests/fixtures/grammar-*.txt):
- grammar-errors-basic.txt: Common errors (subject-verb, could of, etc.)
- grammar-errors-punctuation.txt: Punctuation and spacing errors
- grammar-correct.txt: Clean text with no errors
Testing Philosophy Applied:
- Focus on OUR code (wrapper script), not flycheck internals
- Trust external frameworks work correctly
- Test real integration (wrapper → LanguageTool → output)
- No mocking of domain logic, only external side-effects
- Clear test categories: Normal, Boundary, Error cases
- Comprehensive docstrings listing integrated components
- Deterministic tests using real fixtures
Usage:
make test-file FILE=test-flycheck-languagetool-setup.el
make test-file FILE=test-integration-grammar-checking.el
make test-integration # Includes grammar integration test
Tests automatically discovered by Makefile wildcards.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Diffstat (limited to 'tests/test-integration-grammar-checking.el')
| -rw-r--r-- | tests/test-integration-grammar-checking.el | 190 |
1 files changed, 190 insertions, 0 deletions
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 |
