dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

csharp-mode-tests.el (16123B)


      1 ;;; csharp-mode-tests.el --- Tests for csharp-mode.el            -*- lexical-binding: t; -*-
      2 
      3 ;; Copyright (C) 2020-2021 Free Software Foundation, Inc.
      4 
      5 ;; Author: Josten Kjønigsen <jostein@gmail.com>
      6 ;; Keywords: tests
      7 
      8 ;; This program is free software; you can redistribute it and/or modify
      9 ;; it under the terms of the GNU General Public License as published by
     10 ;; the Free Software Foundation, either version 3 of the License, or
     11 ;; (at your option) any later version.
     12 
     13 ;; This program is distributed in the hope that it will be useful,
     14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 ;; GNU General Public License for more details.
     17 
     18 ;; You should have received a copy of the GNU General Public License
     19 ;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
     20 
     21 (require 'ert)
     22 (require 'cl-lib)
     23 (require 'csharp-mode)
     24 (require 'package)
     25 
     26 ;; development only packages, not declared as a package-dependency
     27 ;; FIXME: loading a .el file from `load-path' should not change user's settings
     28 ;; like that.  It can happen without the user explicitly requesting it!
     29 (package-initialize)
     30 (add-to-list 'package-archives '("melpa" . "https://stable.melpa.org/packages/"))
     31 
     32 ;; required to resolve SEQ (or anything on elpa) on Emacs25.
     33 (setq package-check-signature nil)
     34 
     35 ;; assess depends on dash 2.12.1, which is no longer available
     36 ;; installing dash, resolves 2.13.0, and fixes this broken dependency.
     37 (dolist (p '(dash assess))
     38   (when (not (package-installed-p p))
     39     (package-refresh-contents)
     40     (package-install p)))
     41 
     42 ;;; test-helper functions
     43 
     44 (defmacro assess-face-in-text= (testee &rest assessments)
     45   (when assessments
     46     (let* ((text (car assessments))
     47            (face (cadr assessments))
     48            (rest (cddr assessments)))
     49       `(progn
     50          (require 'assess)
     51          (should (assess-face-at= ,testee 'csharp-mode ,text ,face))
     52          (assess-face-in-text= ,testee ,@rest)))))
     53 
     54 (defmacro assess-face-in-file= (file-name &rest assessments)
     55   (let* ((find-file-hook nil) ;; disable vc-mode hooks
     56          (buffer (find-file-read-only file-name))
     57          (contents (buffer-substring-no-properties (point-min) (point-max))))
     58     (kill-buffer buffer)
     59     `(assess-face-in-text= ,contents ,@assessments)))
     60 
     61 ;;; actual tests
     62 
     63 (ert-deftest activating-mode-doesnt-cause-failure ()
     64   (with-temp-buffer
     65     (csharp-mode)
     66     (should
     67      (equal 'csharp-mode major-mode))))
     68 
     69 (defvar debug-res nil)
     70 
     71 (ert-deftest fontification-of-literals-detects-end-of-strings ()
     72   (assess-face-in-file= "./test-files/fontification-test.cs"
     73                         "bool1"      'font-lock-type-face
     74                         "Reference1" 'font-lock-variable-name-face
     75                         "false"      'font-lock-constant-face
     76                         "bool2"      'font-lock-type-face
     77                         "Reference2" 'font-lock-variable-name-face
     78                         "true"       'font-lock-constant-face
     79                         ))
     80 
     81 (when (and (>= emacs-major-version 29)
     82            (string-lessp "5.35.0" c-version))
     83   (ert-deftest fontification-of-multiline-strings ()
     84     (assess-face-in-file= "./test-files/multiline-strings.cs"
     85                           "Literal0" 'font-lock-variable-name-face
     86                           "Literal1" 'font-lock-variable-name-face
     87                           "Literal2" 'font-lock-variable-name-face
     88                           "Literal3" 'font-lock-variable-name-face
     89                           "Literal4" 'font-lock-variable-name-face
     90                           "Literal5" 'font-lock-variable-name-face
     91                           "Literal6" 'font-lock-variable-name-face
     92                           "Literal7" 'font-lock-variable-name-face)))
     93 
     94 (ert-deftest fontification-of-constants ()
     95   (require 'assess)
     96   (assess-face-in-text=
     97    "testBool1 = true;\ntestBool2 = false;\ntestObj = null;\ntestProp = value;"
     98    "false" 'font-lock-constant-face
     99    "true"  'font-lock-constant-face
    100    "null"  'font-lock-constant-face
    101    "value" 'font-lock-constant-face
    102    ))
    103 
    104 (ert-deftest fontification-of-package ()
    105   (require 'assess)
    106   (assess-face-in-text=
    107    "var package = true;"
    108    "package" 'font-lock-variable-name-face))
    109 
    110 (ert-deftest fontification-of-functions ()
    111   (require 'assess)
    112   (assess-face-in-text= "var foo = bar.Baz()"
    113                         "Baz" 'font-lock-function-name-face)
    114   (assess-face-in-text= "var foo = bar.Baz<Quux>()"
    115                         "Baz" 'font-lock-function-name-face
    116                         "Quux" 'font-lock-type-face))
    117 
    118 (ert-deftest fontification-of-import ()
    119   (require 'assess)
    120   (assess-face-in-text=
    121    "var import = true;"
    122    "import" 'font-lock-variable-name-face))
    123 
    124 (ert-deftest fontification-of-literals-allows-multi-line-strings ()
    125   (require 'assess)
    126   (should (assess-face-at=
    127            "string Literal = \"multi-line\nstring\";"
    128            'csharp-mode
    129            ;; should be interpreted as error
    130            18 'font-lock-warning-face
    131            ))
    132   (should (assess-face-at=
    133            "string Literal = @\"multi-line\nstring\";"
    134            'csharp-mode
    135            ;; should not be interpreted as error because of @
    136            19 'font-lock-string-face
    137            )))
    138 
    139 ;; (ert-deftest fontification-of-compiler-directives ()
    140 ;;   ;; this replaces the manual test of
    141 ;;   ;; test-files/fontification-test-compiler-directives.cs, but file
    142 ;;   ;; has been kept around to assist manual testing/verification.
    143 ;;   (assess-face-in-file= "test-files/fontification-test-compiler-directives.cs"
    144 ;;                         "strReference" 'font-lock-string-face
    145 ;;                         "strVerification" 'font-lock-string-face
    146 ;;                         "singleQuote" 'font-lock-string-face
    147 ;;                         "doubleQuote" 'font-lock-string-face)
    148 
    149 ;;   (assess-face-in-text=
    150 ;;    "#region test\nbool bar = true;"
    151 ;;    ;; should not be interpreted as string because of trailing \!
    152 ;;    "bool" 'font-lock-type-face
    153 ;;    "bar"  'font-lock-variable-name-face
    154 ;;    "true" 'font-lock-constant-face
    155 ;;    )
    156 ;;   (should (assess-face-at=
    157 ;;            "#region test'\nx = true;"
    158 ;;            'csharp-mode
    159 ;;            ;; should not be interpreted as string because of trailing \!
    160 ;;            "true" 'font-lock-constant-face
    161 ;;            ))
    162 ;;   (should (assess-face-at=
    163 ;;            "#region test\"\nx = true;"
    164 ;;            'csharp-mode
    165 ;;            ;; should not be interpreted as string because of trailing \!
    166 ;;            "true" 'font-lock-constant-face
    167 ;;            )))
    168 
    169 (ert-deftest fontification-of-compiler-directives-after-comments ()
    170   (assess-face-in-file= "./test-files/fontification-test-compiler-directives-with-comments.cs"
    171                         "case1" 'font-lock-comment-face
    172                         "case2" 'font-lock-comment-face))
    173 
    174 (ert-deftest fontification-of-method-names ()
    175   (assess-face-in-file= "./test-files/imenu-method-test.cs"
    176                         "OpenWebServicesAsync" 'font-lock-function-name-face
    177                         "ToString"             'font-lock-function-name-face
    178                         "Equals"               'font-lock-function-name-face
    179                         "AbstractMethod"       'font-lock-function-name-face
    180                         "UnsafeCopy"           'font-lock-function-name-face
    181                         ;; "GenericMethod1"       'font-lock-function-name-face
    182                         ;; "GenericMethod2"       'font-lock-function-name-face
    183                         ))
    184 
    185 (ert-deftest fontification-of-using-statements ()
    186   (assess-face-in-file= "./test-files/using-fontification.cs"
    187                         "using" 'font-lock-keyword-face
    188                         "Reference" 'font-lock-variable-name-face
    189                         "Under_scored" 'font-lock-variable-name-face
    190                         "WithNumbers09" 'font-lock-variable-name-face
    191                         "Ok" 'font-lock-variable-name-face
    192                         "WithNumbers09" 'font-lock-variable-name-face
    193                         "OkV2" 'font-lock-variable-name-face
    194                         ))
    195 
    196 (ert-deftest fontification-of-namespace-statements ()
    197   (assess-face-in-file= "./test-files/namespace-fontification.cs"
    198                         "namespace" 'font-lock-keyword-face
    199                         "Reference" 'font-lock-variable-name-face
    200                         "Under_scored" 'font-lock-variable-name-face
    201                         "WithNumbers09" 'font-lock-variable-name-face
    202                         "Ok" 'font-lock-variable-name-face
    203                         "WithNumbers09" 'font-lock-variable-name-face
    204                         "Ok" 'font-lock-variable-name-face
    205                         ))
    206 
    207 (defun list-repeat-once (mylist)
    208   (append mylist mylist))
    209 
    210 (ert-deftest build-warnings-and-errors-are-parsed ()
    211   (dolist (test-case
    212            `(("./test-files/msbuild-warning.txt" ,csharp-compilation-re-msbuild-warning
    213               ,(list-repeat-once
    214                 '("Class1.cs"
    215                   "Folder\\Class1.cs"
    216                   "Program.cs"
    217                   "Program.cs")))
    218              ("./test-files/msbuild-error.txt" ,csharp-compilation-re-msbuild-error
    219               ,(list-repeat-once
    220                 '("Folder\\Class1.cs")))
    221              ("./test-files/msbuild-concurrent-warning.txt" ,csharp-compilation-re-msbuild-warning
    222               ,(list-repeat-once
    223                 '("Program.cs")))
    224              ("./test-files/msbuild-concurrent-error.txt" ,csharp-compilation-re-msbuild-error
    225               ,(list-repeat-once
    226                 '("Program.cs")))
    227              ("./test-files/msbuild-square-brackets.txt" ,csharp-compilation-re-msbuild-error
    228               ,(list-repeat-once
    229                 '("Properties\\AssemblyInfo.cs"
    230                   "Program.cs"
    231                   "Program.cs")))
    232              ("./test-files/msbuild-square-brackets.txt" ,csharp-compilation-re-msbuild-warning
    233               ,(list-repeat-once
    234                 '("Program.cs")))
    235              ("./test-files/xbuild-warning.txt" ,csharp-compilation-re-xbuild-warning
    236               ,(list-repeat-once
    237                 '("/Users/jesseblack/Dropbox/barfapp/ConsoleApplication1/ClassLibrary1/Class1.cs"
    238                   "/Users/jesseblack/Dropbox/barfapp/ConsoleApplication1/ClassLibrary1/Folder/Class1.cs"
    239                   "/Users/jesseblack/Dropbox/barfapp/ConsoleApplication1/ConsoleApplication1/Program.cs"
    240                   "/Users/jesseblack/Dropbox/barfapp/ConsoleApplication1/ConsoleApplication1/Program.cs"
    241                   "/Users/jesseblack/Dropbox/barfapp/ConsoleApplication1/ConsoleApplication1/Program.cs")))
    242              ("./test-files/xbuild-error.txt" ,csharp-compilation-re-xbuild-error
    243               ,(list-repeat-once
    244                 '("/Users/jesseblack/Dropbox/barfapp/ConsoleApplication1/ClassLibrary1/Folder/Class1.cs")))
    245              ("./test-files/devenv-error.txt" ,csharp-compilation-re-xbuild-error
    246               ("c:\\working_chad\\dev_grep\\build_grep_database\\databaseconnection.cpp"
    247                "c:\\working_chad\\dev_grep\\build_grep_database\\databaseconnection.cpp"
    248                "c:\\working_chad\\dev_grep\\build_grep_database\\databaseconnection.cpp"))
    249              ("./test-files/devenv-error.txt" ,csharp-compilation-re-xbuild-warning
    250               ("c:\\working_chad\\dev_grep\\build_grep_database\\databaseconnection.cpp"))
    251              ("./test-files/devenv-mixed-error.txt" ,csharp-compilation-re-xbuild-error
    252               ("C:\\inservice\\SystemTesting\\OperateDeviceProxy\\OperateDevice_Proxy\\Program.cs"
    253                "C:\\inservice\\SystemTesting\\OperateDeviceProxy\\OperateDevice_Proxy\\Program.cs"
    254                "C:\\inservice\\SystemTesting\\OperateDeviceProxy\\OperateDevice_Proxy\\Program.cs"
    255                "c:\\inservice\\systemtesting\\operationsproxy\\operationsproxy.cpp"
    256                "c:\\inservice\\systemtesting\\operationsproxy\\operationsproxy.cpp"
    257                "c:\\inservice\\systemtesting\\operationsproxy\\operationsproxy.cpp"))
    258 
    259              ("./test-files/dotnet-nuget-error.txt" ,csharp-compilation-re-dotnet-error
    260               ("/home/jostein/build/sample-app/sample-app.csproj"))
    261              ("./test-files/dotnet-nuget-warning.txt" ,csharp-compilation-re-dotnet-warning
    262               ("/home/jostein/build/sample-app/sample-app.csproj"))
    263              ("./test-files/dotnet-test-fail-xunit.txt" ,csharp-compilation-re-dotnet-testfail
    264               ("/home/jostein/build/sample-app/Module/Testee.cs"))))
    265 
    266     (let* ((file-name (car test-case))
    267            (regexp    (cadr test-case))
    268            (matched-file-names (cl-caddr test-case))
    269            (times     (length matched-file-names))
    270            (find-file-hook '()) ;; avoid vc-mode file-hooks when opening!
    271            (buffer (find-file-read-only file-name)))
    272       ;; (message (concat "Testing compilation-log: " file-name))
    273       (dotimes (number times)
    274         (let* ((expected (nth number matched-file-names)))
    275           ;; (message (concat "- Expecting match: " expected))
    276           (re-search-forward regexp)
    277           (should
    278            (equal expected (match-string 1)))))
    279       (kill-buffer buffer))))
    280 
    281 (defvar csharp-hook1 nil)
    282 (defvar csharp-hook2 nil)
    283 
    284 (ert-deftest activating-mode-triggers-all-hooks ()
    285   (add-hook 'csharp-mode-hook (lambda () (setq csharp-hook1 t)))
    286   (add-hook 'prog-mode-hook   (lambda () (setq csharp-hook2 t)))
    287 
    288   (with-temp-buffer
    289     (csharp-mode)
    290     (should (equal t (and csharp-hook1
    291                           csharp-hook2)))))
    292 
    293 (defvar c-mode-hook-run nil)
    294 (ert-deftest avoid-runing-c-mode-hook ()
    295   (add-hook 'c-mode-hook (lambda () (setq c-mode-hook-run t)))
    296 
    297   (with-temp-buffer
    298     (csharp-mode)
    299     (should-not c-mode-hook-run)))
    300 
    301 (ert-deftest indentation-rules-should-be-as-specified-in-test-doc ()
    302   (let* ((buffer (find-file "test-files/indentation-tests.cs"))
    303          (orig-content)
    304          (indented-content))
    305     ;; double-ensure mode is active
    306     (csharp-mode)
    307 
    308     (setq orig-content (buffer-substring-no-properties (point-min) (point-max)))
    309     (indent-region (point-min) (point-max))
    310     (setq indented-content (buffer-substring-no-properties (point-min) (point-max)))
    311 
    312     (should (equal orig-content indented-content))))
    313 
    314 (ert-deftest region-directive-comment-movement ()
    315   (find-file "test-files/region-fontification.cs")
    316   (csharp-mode)
    317   (goto-char (point-min))
    318   (search-forward "#region ")
    319   (forward-word 1)
    320   (forward-word -1)
    321   (should (looking-at "fontifies")))
    322 
    323 ;; (ert-deftest fontification-of-regions ()
    324 ;;   (require 'assess)
    325 ;;   (require 'm-buffer)
    326 ;;   (find-file "test-files/region-fontification.cs")
    327 ;;   (csharp-mode)
    328 ;;   (let ((buf (current-buffer)))
    329 ;;     ;; look for 'a region comment' - should always be a comment
    330 ;;     (should (assess-face-at= buf 'csharp-mode (lambda (buf) (m-buffer-match buf "a region comment")) 'font-lock-comment-face))
    331 ;;     ;; look for 'string' - should always be a type
    332 ;;     (should (assess-face-at= buf 'csharp-mode (lambda (buf) (m-buffer-match buf "string")) 'font-lock-type-face))))
    333 
    334 (ert-deftest activating-mode-doesnt-clobber-global-adaptive-fill-regexp ()
    335   (let ((before adaptive-fill-regexp))
    336     (with-temp-buffer
    337       (csharp-mode))
    338     (should
    339      (equal before adaptive-fill-regexp))))
    340 
    341 (ert-deftest activating-mode-style-defaults-to-csharp ()
    342   (with-temp-buffer
    343     (csharp-mode)
    344     (should
    345      (equal "csharp" c-indentation-style)))
    346 
    347   (let ((c-default-style "csharp"))
    348     (with-temp-buffer
    349       (csharp-mode)
    350       (should
    351        (equal "csharp" c-indentation-style))))
    352 
    353   (let ((c-default-style '((csharp-mode . "csharp")
    354                            (java-mode . "java"))))
    355     (with-temp-buffer
    356       (csharp-mode)
    357       (should
    358        (equal "csharp" c-indentation-style)))))
    359 
    360 (ert-deftest inside-bracelist-test ()
    361   (with-temp-buffer
    362     (csharp-mode)
    363     (insert "public class A { public void F() {")
    364     (call-interactively #'newline)))
    365 
    366 ;;(ert-run-tests-interactively t)
    367 ;; (local-set-key (kbd "<f6>") '(lambda ()
    368 ;;                               (interactive)
    369 ;;                               (ert-run-tests-interactively t)))