dotemacs

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

go-font-lock-test.el (8412B)


      1 ;;; go-font-lock-test.el
      2 
      3 ;; Copyright 2019 The go-mode Authors. All rights reserved. Use of
      4 ;; this source code is governed by a BSD-style license that can be
      5 ;; found in the LICENSE file.
      6 
      7 (require 'ert)
      8 (require 'go-mode)
      9 (require 'cl-lib)
     10 
     11 (ert-deftest go--fontify-signature ()
     12   (go--should-fontify "KfuncK FfooF() { }")
     13   (go--should-fontify "KfuncK FfooF(TaT) { }")
     14   (go--should-fontify "KfuncK FfooF(TaT, TbT) { }")
     15   (go--should-fontify "KfuncK FfooF(TaT) TaT { }")
     16   (go--should-fontify "KfuncK FfooF(VaV TbT) (VaV TbT) { }")
     17   (go--should-fontify "KfuncK FfooF(VaV, VbV TcT) (VaV TbT, VcV TdT) { }")
     18 
     19   (go--should-fontify "KfuncK (TbT) FfooF(VaV, VbV TcT) TdT { }")
     20   (go--should-fontify "KfuncK (VaV TbT) FfooF(VaV TbT) (TdT) { }")
     21 
     22   (go--should-fontify "VfooV := KfuncK(VaV TbT) TcT { }")
     23 
     24   (go--should-fontify "KfuncK(...TintT) { }")
     25   (go--should-fontify "KfuncK(VaV ...TintT) { }")
     26   (go--should-fontify "KfuncK(VaV ...KinterfaceK{}) { }")
     27 
     28   (go--should-fontify "KfuncK(KinterfaceK { FfooF() }, TstringT) KinterfaceK{}")
     29 
     30   (go--should-fontify "KfuncK(VaV TbT, VcV KfuncK(VdV *TeT) TdT) TfT")
     31   (go--should-fontify "KfuncK(VaV KfuncK() TbT, VcV TdT)")
     32 
     33   (go--should-fontify "
     34 KfuncK FfooF(
     35   VaV TcatT, VbV KinterfaceK { FbarkF() },
     36   VcV TbananaT,
     37 ) (
     38   VwhyV TdothisT,
     39   VjustV TstopT,
     40 ) { }")
     41 
     42   (go--should-fontify "
     43 D// DQ
     44 QD// DQ(
     45 QKfuncK (VfV TintT) {}
     46 "))
     47 
     48 (ert-deftest go--fontify-struct ()
     49   (go--should-fontify "KstructK { i TintT }")
     50   (go--should-fontify "KstructK { a, b TintT }")
     51 
     52   (go--should-fontify "
     53 KstructK {
     54   a TboolT
     55   c KstructK { f *Tfoo.ZebraT }
     56 }"))
     57 
     58 (ert-deftest go--fontify-interface ()
     59   (go--should-fontify "
     60 KinterfaceK {
     61   FfooF(VaV, VbV TcT) *TstringT
     62 }")
     63 
     64   (go--should-fontify "
     65 KinterfaceK {
     66   FfooF(KinterfaceK { FaF() TintT }) (VcV TdT)
     67 }")
     68 
     69   (go--should-fontify "
     70 KmapK[TstringT]KinterfaceK{}{
     71   S`foo`S: foo.FbarF(baz),
     72 }"))
     73 
     74 
     75 (ert-deftest go--fontify-type-switch ()
     76   (go--should-fontify "
     77 KswitchK foo.(KtypeK) {
     78 KcaseK TstringT, *Tfoo.ZebraT, [2]TbyteT:
     79 KcaseK CnilC:
     80 KcaseK TfooT, TbarT, D// DQhi
     81 Q
     82   D// DQthere
     83 Q  TbazT, TquxT:
     84 KdefaultK:
     85 }")
     86 
     87   (go--should-fontify "
     88 KswitchK foo.(KtypeK) {
     89 KcaseK KinterfaceK { FfooF(TintT, TstringT) }, KstructK { i, j TintT }, TstringT:
     90 }")
     91 
     92   (go--should-fontify "
     93 KswitchK 123 {
     94 KcaseK string:
     95 }"))
     96 
     97 (ert-deftest go--fontify-composite-literal ()
     98   (go--should-fontify "TfooT{")
     99   (go--should-fontify "[]TfooT{")
    100   (go--should-fontify "Tfoo.ZarT{")
    101   (go--should-fontify "[]Tfoo.ZarT{")
    102 
    103   (go--should-fontify "TfooT{CbarC:baz, CquxC: 123}")
    104 
    105   (go--should-fontify "TfooT{
    106 CbarC: baz,
    107 }")
    108 
    109   (go--should-fontify "[]TfooT{{
    110 CbarC: baz,
    111 }, {
    112 CbarC: baz,
    113 }}")
    114 
    115   (go--should-fontify "TsomeMapT{
    116 foo.Zar: baz,
    117 a + b: 3,
    118 a-b: 4,
    119 }"))
    120 
    121 (ert-deftest go--fontify-slices-arrays-maps ()
    122   (go--should-fontify "[]TfooT")
    123   (go--should-fontify "[]Tfoo.ZarT")
    124   (go--should-fontify "[]*Tfoo.ZarT")
    125 
    126   (go--should-fontify "[123]TfooT")
    127   (go--should-fontify "[...]TfooT")
    128   (go--should-fontify "[foo.Zar]TfooT")
    129   (go--should-fontify "D/*DQhi*/Q[1]*TfooT")
    130 
    131   (go--should-fontify "KmapK[*Tfoo.ZarT]*Tbar.ZarT")
    132   (go--should-fontify "[]KmapK[TfooT]TbarT")
    133   (go--should-fontify "KmapK[[1][2][three]*Tfoo.ZarT][four][]*Tbar.ZarT")
    134   (go--should-fontify "KmapK[TstringT]KmapK[TstringT]Tfloat64T")
    135   (go--should-fontify "KmapK[[2][c]*TintT]TboolT"))
    136 
    137 (ert-deftest go--fontify-negation ()
    138   ;; Fontify unary "!".
    139   (go--should-fontify "N!Nfoo")
    140 
    141   ;; Alternate fontification with multiple "!".
    142   (go--should-fontify "N!N!foo")
    143   (go--should-fontify "N!N!N!Nfoo")
    144 
    145   ;; Don't fontify "!=" operator.
    146   (go--should-fontify "foo != bar"))
    147 
    148 
    149 (ert-deftest go--fontify-type-decl ()
    150   (go--should-fontify "KtypeK TfooT TbarT")
    151   (go--should-fontify "KtypeK TfooT Tbar.ZarT")
    152   (go--should-fontify "KtypeK TfooT KstructK { }")
    153   (go--should-fontify "KtypeK TfooT = Tbar.ZarT")
    154   (go--should-fontify "KtypeK TfooT = KmapK[TstringT]TstringT")
    155 
    156   (go--should-fontify "
    157 KtypeK (
    158   TfooT TbarT
    159   TfooT KstructK {}
    160   TfooT = *Tbar.ZarT
    161 )"))
    162 
    163 (ert-deftest go--fontify-var-decl ()
    164   (go--should-fontify "KvarK VfooV = bar")
    165   (go--should-fontify "KvarK VfooV, VbarV = bar, baz")
    166   (go--should-fontify "KvarK VfooV TbarT D// DQcoolQ")
    167   (go--should-fontify "KvarK VfooV TbarT = baz")
    168   (go--should-fontify "KvarK VfooV KstructK { i TintT } = baz")
    169   (go--should-fontify "KvarK VfooV []*Tfoo.ZarT D// DQcoolQ")
    170 
    171   (go--should-fontify "
    172 KvarK (
    173   VfooV TbarT
    174   VfooV KfuncK(ViV TintT)
    175   VfooV = bar
    176   VfooV TbarT = baz
    177   VfooV, VbarV = baz, qux
    178   VfooV, VbarV TbazT = qux, zorb
    179 )"))
    180 
    181 (ert-deftest go--fontify-const-decl ()
    182   (go--should-fontify "KconstK CfooC, CbarC = 123, 456 D// D")
    183   (go--should-fontify "KconstK CfooC, CbarC TbazT = 123, 456")
    184   (go--should-fontify "
    185 KconstK (
    186   CaC = 1
    187   CaC TintT = 1
    188   CaC, CbC TintT = 1, 2
    189 )"))
    190 
    191 (ert-deftest go--fontify-labels ()
    192   (go--should-fontify "
    193 CfooC:
    194 KforK {
    195   KcontinueK CfooC
    196   KbreakK CfooC
    197   KgotoK CfooC
    198 }
    199 "))
    200 
    201 (ert-deftest go--fontify-assign ()
    202   (go--should-fontify "VfooV := bar")
    203   (go--should-fontify "foo = bar D// DQ:=Q")
    204   (go--should-fontify "VfooV, VbarV := baz, qux")
    205   (go--should-fontify "foo, bar = baz, qux")
    206   (go--should-fontify "KfuncK FfooF(ViV TintT) { VbarV := baz }"))
    207 
    208 (ert-deftest go--fontify-index-multiply ()
    209   (go--should-fontify "foo[1]*10 + 1")
    210   (go--should-fontify "foo[1]*foo[2] + 1"))
    211 
    212 (ert-deftest go--fontify-go-dot-mod ()
    213   (go--should-fontify "
    214 KmoduleK foo
    215 
    216 KgoK 1.13
    217 
    218 KrequireK (
    219   Nexample.com/require/go/bananaN Sv12.34.56SV-1234-456abcV D// DQindirect
    220 Q	Nnoslash.devN Sv1.2.3S
    221 )
    222 
    223 KreplaceK (
    224 	Nfoo.example.com/barN Sv1.2.3S => Nfoo.example.com/barN Sv1.2.3S
    225 	Nexample.com/foo/barN => Nexample.com/baz/barN Sv0.0.0SV-20201112005413-933910cbaea0V
    226 )
    227 " 'go-dot-mod-mode))
    228 
    229 (defun go--should-match-face (want-face)
    230   (let ((got-face (get-text-property (point) 'face)))
    231     (if (not (eq got-face want-face))
    232         (progn
    233           (message "char '%s' (%s): wanted %s, got %s" (char-to-string (char-after)) (point) want-face got-face)
    234           nil)
    235       t)))
    236 
    237 (defun go--should-fontify (contents &optional mode)
    238   "Verify fontification.
    239 
    240 CONTENTS is a template that uses single capital letters to
    241 represent expected font lock face names. For example:
    242 
    243 BmakeB([]TintT, 0)
    244 
    245 expects \"make\" to be a (B)uiltin and \"int\" to be a (T)type."
    246   (with-temp-buffer
    247     (setq mode (or mode 'go-mode))
    248     (funcall mode)
    249     (insert contents)
    250     (goto-char (point-min))
    251 
    252     ;; First pass through buffer looks for the face tags. We delete
    253     ;; the tags and record the expected face ranges in `faces'.
    254     (let ((case-fold-search nil) faces start start-pos)
    255       (while (re-search-forward "[TBKCFSNVDQ]" nil t)
    256         (let ((found-char (char-before)))
    257           (backward-delete-char 1)
    258           (if start
    259               (progn
    260                 (should (= found-char start))
    261                 (let ((face (cl-case found-char
    262                               (?T 'font-lock-type-face)
    263                               (?B 'font-lock-builtin-face)
    264                               (?K 'font-lock-keyword-face)
    265                               (?C 'font-lock-constant-face)
    266                               (?F 'font-lock-function-name-face)
    267                               (?S (if (eq mode 'go-mode) 'font-lock-string-face 'go-dot-mod-module-semver))
    268                               (?N (if (eq mode 'go-mode) 'font-lock-negation-char-face 'go-dot-mod-module-name))
    269                               (?V (if (eq mode 'go-mode) 'font-lock-variable-name-face 'go-dot-mod-module-version))
    270                               (?D 'font-lock-comment-delimiter-face)
    271                               (?Q 'font-lock-comment-face))))
    272                   (setq faces (append faces `((,face ,start-pos ,(point))))))
    273                 (setq start nil))
    274             (setq start found-char)
    275             (setq start-pos (point)))))
    276 
    277       ;; Fontify buffer now that we have removed the tags.
    278       (font-lock-fontify-buffer)
    279       (goto-char (point-min))
    280 
    281       ;; Go through buffer one character at a time making sure the
    282       ;; character's face is correct.
    283       (let ((face (pop faces)))
    284         (while (not (eobp))
    285           (while (and face (>= (point) (nth 2 face)))
    286             (setq face (pop faces)))
    287           (if (and face (>= (point) (nth 1 face)))
    288               (should (go--should-match-face (nth 0 face)))
    289             (should (go--should-match-face nil)))
    290           (forward-char))))))