emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/bnf-mode d88eef6 36/36: Merge pull request #15 from ser


From: Stefan Monnier
Subject: [elpa] externals/bnf-mode d88eef6 36/36: Merge pull request #15 from sergeyklay/refactor-tests
Date: Wed, 17 Mar 2021 18:40:20 -0400 (EDT)

branch: externals/bnf-mode
commit d88eef69ae66ea1ffa21a65317afe84c9ddb0814
Merge: e3489f3 e99dd39
Author: Serghei Iakovlev <sergeyklay@users.noreply.github.com>
Commit: GitHub <noreply@github.com>

    Merge pull request #15 from sergeyklay/refactor-tests
    
    Removed support of ALGOL 60 style comments
---
 NEWS                            |   8 +-
 bnf-mode.el                     |  60 ++------------
 bnf-mode.info                   |  81 +++++++++++--------
 bnf-mode.texi                   |  54 ++++++++-----
 test/bnf.bnf                    |  34 ++++++++
 test/ebnf-grammar.ebnf          |  68 ----------------
 test/test-bnf-mode-font-lock.el | 173 ++++++++++++----------------------------
 test/test-bnf-mode-generic.el   |  53 ++++++++++++
 test/utils.el                   |  93 ++++++++++++++++++---
 9 files changed, 312 insertions(+), 312 deletions(-)

diff --git a/NEWS b/NEWS
index a71ef24..27cfd78 100644
--- a/NEWS
+++ b/NEWS
@@ -5,15 +5,17 @@ See the end of the file for license conditions.
 
 This file is about changes in BNF Mode.
 
-* Unreleased
+* BNF Mode 0.4.5
 ** Tests were migrated from ert-runner to buttercup.
 Previously BNF Mode used `ert' through `ert-runner' for testing
 purposes.  However, it seems `ert-runner' is semi-abandoned.  Thus,
 tests were migrated to use more aggressively maintained test
 framework calles `buttercup'.
 
-** Added abbreviation table to use in bnf-mode buffers.
-To use abbreviations in BNF buffers refers to `bnf-mode-abbrev-table'.
+** Removed support of ALGOL 60 style comments.
+Actually, this syntax was never part of the BNF and was mistakenly
+interpreted as an alternative way of commenting BNF grammars
+introduced by Peter Naur.
 
 * BNF Mode 0.4.4
 ** Rework documentation and provide Info-file.
diff --git a/bnf-mode.el b/bnf-mode.el
index c824f2f..7a8840a 100644
--- a/bnf-mode.el
+++ b/bnf-mode.el
@@ -4,7 +4,7 @@
 
 ;; Author: Serghei Iakovlev <egrep@protonmail.ch>
 ;; Maintainer: Serghei Iakovlev <egrep@protonmail.ch>
-;; Version: 0.4.4
+;; Version: 0.4.5
 ;; URL: https://github.com/sergeyklay/bnf-mode
 ;; Keywords: languages
 ;; Package-Requires: ((cl-lib "0.5") (emacs "24.3"))
@@ -51,27 +51,6 @@
   :link '(url-link :tag "GitHub Page" "https://github.com/sergeyklay/bnf-mode";)
   :link '(emacs-commentary-link :tag "Commentary" "bnf-mode"))
 
-(defcustom bnf-mode-algol-comments-style nil
-  "Non-nil means use for BNF comments style introduced in ALGOL 60.
-
-For the purpose of including text among the symbols of a program the
-following \"comment\" conventions will hold:
-
-  :------------------------------------------------:------------------:
-  | The sequence of basic symbols:                 | is equivalent to |
-  :------------------------------------------------:------------------:
-  | ; comment <any sequence not containing ;>;     | ;                |
-  | begin comment <any sequence not containing ;>; | begin            |
-  :------------------------------------------------:------------------:
-
-Note: enabling this feature will disable comments recognition, which
-start with semicolons only (\";\")."
-  :type 'boolean)
-
-(defvar bnf-mode-abbrev-table nil
-  "Abbreviation table used in `bnf-mode' buffers.")
-(define-abbrev-table 'bnf-mode-abbrev-table ())
-
 
 ;;;; Specialized rx
 
@@ -144,10 +123,6 @@ See `rx' documentation for more information about REGEXPS 
param."
 
 (defvar bnf-mode-syntax-table
   (let ((table (make-syntax-table)))
-    ;; Give CR the same syntax as newline
-    ;; FIXME: Why?
-    (modify-syntax-entry ?\^m "> b" table)
-
     ;; FIXME: "_" doesn't mean "symbol" but "symbol constituent".
     ;; I.e. the settings below mean that Emacs will consider "a:b=(c" as one
     ;; symbol (aka "identifier") which can be seen if you try to C-M-f and
@@ -178,24 +153,13 @@ See `rx' documentation for more information about REGEXPS 
param."
     (modify-syntax-entry ?\< "(>" table)
     (modify-syntax-entry ?\> ")<" table)
 
-    ;; Comments setup
-    (if bnf-mode-algol-comments-style
-        (modify-syntax-entry ?\; ">" table)
-      (progn
-        (modify-syntax-entry ?\; "<" table)
-        (modify-syntax-entry ?\n ">" table)))
+    ;; Comments are begins with “;” and ends with “\n”
+    (modify-syntax-entry ?\; "<" table)
+    (modify-syntax-entry ?\n ">" table)
 
     table)
   "Syntax table in use in `bnf-mode' buffers.")
 
-(defconst bnf--syntax-propertize
-  (syntax-propertize-rules
-   ;; Fontify comments in ALGOL 60 style.
-   ("\\(?:begin\\s-+\\|;\\s-*\\)\\(comment\\)\\(;\\|\\s-+[^;]*;\\)" (1 "<")))
-  "Apply syntax table properties to special constructs.
-Provide a macro to apply syntax table properties to comments in ALGOL 60
-style.  Will be used only if `bnf-mode-algol-comments-style' is set to t.")
-
 
 ;;;; Initialization
 
@@ -204,26 +168,16 @@ style.  Will be used only if 
`bnf-mode-algol-comments-style' is set to t.")
   "A major mode for editing BNF grammars.
 
 \\{bnf-mode-map}
-The variable `bnf-mode-algol-comments-style' can be changed to control
-comments style used in grammars.
 
 Turning on BNF Mode calls the value of `prog-mode-hook' and then of
 `bnf-mode-hook', if they are non-nil."
-  :abbrev-table bnf-mode-abbrev-table
   :syntax-table bnf-mode-syntax-table
 
   ;; Comments setup
   (setq-local comment-use-syntax nil)
-  (if bnf-mode-algol-comments-style
-      (progn
-        (setq-local comment-start "; comment ")
-        (setq-local comment-end ";")
-        (setq-local comment-start-skip "\\(?:\\(\\W\\|^\\)comment\\)\\s-+")
-        (setq-local syntax-propertize-function bnf--syntax-propertize))
-    (progn
-      (setq-local comment-start "; ")
-      (setq-local comment-end "")
-      (setq-local comment-start-skip "\\(?:\\(\\W\\|^\\);+\\)\\s-+")))
+  (setq-local comment-start "; ")
+  (setq-local comment-end "")
+  (setq-local comment-start-skip "\\(?:\\(\\W\\|^\\);+\\)\\s-+")
 
   ;; Font locking
   (setq font-lock-defaults
diff --git a/bnf-mode.info b/bnf-mode.info
index 61b8740..576bdc3 100644
--- a/bnf-mode.info
+++ b/bnf-mode.info
@@ -6,9 +6,9 @@ it provides basic syntax and font-locking for BNF files.  BNF 
notation
 is supported exactly form as it was first announced in the ALGOL 60
 report.
 
-This manual is for BNF Mode version 0.4.4.
+This manual is for BNF Mode version 0.4.5.
 
-   Copyright © 2019, 2020 Free Software Foundation, Inc.
+   Copyright © 2019-2020 Free Software Foundation, Inc.
 
      Permission is granted to copy, distribute and/or modify this
      document under the terms of the GNU Free Documentation License,
@@ -68,6 +68,36 @@ it provides basic syntax and font-locking for BNF files.  
BNF notation
 is supported exactly form as it was first announced in the ALGOL 60
 report.
 
+   Bellow canonical BNF notation represented with a BNF is presented.
+The syntax of the BNF has been carefully copied from Revised ALGOL 60
+report.  For more see <http://www.masswerk.at/algol60/report.htm>.
+
+     <syntax>         ::= <rule> | <rule> <syntax>
+     <rule>           ::= <opt-ws> < <rule-name> > <opt-ws>
+                          ::= <opt-ws> <expression> <line-end>
+     <opt-ws>         ::= <space> <opt-ws> | <empty>
+     <expression>     ::= <list> | <list> <opt-ws> <or> <opt-ws>
+                          <expression>
+     <line-end>       ::= <opt-ws> <EOL> | <line-end> <line-end>
+     <list>           ::= <term> | <term> <opt-ws> <list>
+     <term>           ::= <literal> | < <rule-name> >
+     <literal>        ::= <character> <text>
+     <character>      ::= <letter> | <digit> | <symbol>
+     <letter>         ::= A | B | C | D | E | F | G | H | I | J | K | L |
+                          M | N | O | P | Q | R | S | T | U | V | W | X |
+                          Y | Z | a | b | c | d | e | f | g | h | i | j |
+                          k | l | m | n | o | p | q | r | s | t | u | v |
+                          w | x | y | z
+     <digit>          ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
+     <symbol>         ::= <or>  | <space>   | ! | # | $ | % | & | ( | ) |
+                          * | + | , | - | . | / | : | ~ | > | = | < | ? |
+                          @ | [ | \ | ] | ^ | _ | ` | ' | " | { | } | ;
+     <rule-name>      ::= <letter> | <rule-name> <rule-char>
+     <rule-char>      ::= <letter> | <digit> | -
+     <space>          ::= <space, tab or new line character>
+     <or>             ::= |
+     <empty>          ::=
+
 
 File: bnf-mode.info,  Node: Installation,  Next: Usage,  Prev: Introduction,  
Up: Top
 
@@ -216,19 +246,7 @@ File: bnf-mode.info,  Node: Customizing,  Next: Project 
Links,  Prev: Usage,  Up
 4 Customizing
 *************
 
-There are not so much customization options yet.  The most interested
-option is ‘bnf-mode-algol-comments-style’.  This variable can be changed
-to control comments style used in grammars.  Setting it to non-nil means
-use for BNF comments style introduced in ALGOL 60.  In this case the
-following "comment" conventions will hold:
-
-The sequence of basic symbols                      Is equivalent to
---------------------------------------------------------------------------
-‘; comment <any sequence not containing ;>;’       ‘;’
-‘begin comment <any sequence not containing ;>;’   ‘begin’
-
-   Note: enabling this feature will disable comments recognition, which
-start with semicolons only (‘;’).
+There are not so much customization options yet.
 
    To customize ‘abbrev-mode’ for ‘bnf-mode’, simple add preffered
 abbreviations to ‘bnf-mode-abbrev-table’.
@@ -338,28 +356,23 @@ File: bnf-mode.info,  Node: Variable Index,  Prev: Index, 
 Up: Top
 Variable Index
 **************
 
-[index]
-* Menu:
-
-* bnf-mode-algol-comments-style:         Customizing.           (line 6)
-
 
 
 Tag Table:
-Node: Top1104
-Node: Introduction1803
-Node: Installation2141
-Node: Installing from Elpa or Melpa2663
-Node: Installing using El-get4880
-Node: Installing from the Git Repository5559
-Node: Usage6460
-Node: Customizing6745
-Node: Project Links8090
-Node: Bugs Tracker8261
-Node: Change Log8494
-Node: Bibliography8743
-Node: Index9901
-Node: Variable Index10608
+Node: Top1103
+Node: Introduction1802
+Node: Installation3803
+Node: Installing from Elpa or Melpa4325
+Node: Installing using El-get6542
+Node: Installing from the Git Repository7221
+Node: Usage8122
+Node: Customizing8407
+Node: Project Links9084
+Node: Bugs Tracker9255
+Node: Change Log9488
+Node: Bibliography9737
+Node: Index10895
+Node: Variable Index11602
 
 End Tag Table
 
diff --git a/bnf-mode.texi b/bnf-mode.texi
index 42554fb..24b6c74 100644
--- a/bnf-mode.texi
+++ b/bnf-mode.texi
@@ -15,7 +15,7 @@ BNF notation is supported exactly form as it was first 
announced in
 the ALGOL 60 report.
 
 @noindent
-This manual is for BNF Mode version 0.4.4.
+This manual is for BNF Mode version 0.4.5.
 @end ifnottex
 
 Copyright @copyright{} 2019-2020 Free Software Foundation, Inc.
@@ -41,7 +41,7 @@ modify this GNU manual.”
 @finalout
 @titlepage
 @title BNF Mode User Manual
-@subtitle for version 0.4.4
+@subtitle for version 0.4.5
 @author Serghei Iakovlev
 @page
 @vskip 0pt plus 1filll
@@ -92,6 +92,36 @@ Presently it provides basic syntax and font-locking for BNF 
files.
 BNF notation is supported exactly form as it was first announced in
 the ALGOL 60 report.
 
+Bellow canonical BNF notation represented with a BNF is presented.  The syntax 
of the BNF has been carefully copied from Revised ALGOL 60 report.  For more 
see @url{http://www.masswerk.at/algol60/report.htm}.
+
+@example
+<syntax>         ::= <rule> | <rule> <syntax>
+<rule>           ::= <opt-ws> < <rule-name> > <opt-ws>
+                     ::= <opt-ws> <expression> <line-end>
+<opt-ws>         ::= <space> <opt-ws> | <empty>
+<expression>     ::= <list> | <list> <opt-ws> <or> <opt-ws>
+                     <expression>
+<line-end>       ::= <opt-ws> <EOL> | <line-end> <line-end>
+<list>           ::= <term> | <term> <opt-ws> <list>
+<term>           ::= <literal> | < <rule-name> >
+<literal>        ::= <character> <text>
+<character>      ::= <letter> | <digit> | <symbol>
+<letter>         ::= A | B | C | D | E | F | G | H | I | J | K | L |
+                     M | N | O | P | Q | R | S | T | U | V | W | X |
+                     Y | Z | a | b | c | d | e | f | g | h | i | j |
+                     k | l | m | n | o | p | q | r | s | t | u | v |
+                     w | x | y | z
+<digit>          ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
+<symbol>         ::= <or>  | <space>   | ! | # | $ | % | & | ( | ) |
+                     * | + | @comma{} | - | . | / | : | ~ | > | = | < | ? |
+                     @atchar{} | [ | @backslashchar{} | ] | ^ | _ | ` | ' | " 
| @{ | @} | ;
+<rule-name>      ::= <letter> | <rule-name> <rule-char>
+<rule-char>      ::= <letter> | <digit> | -
+<space>          ::= <space, tab or new line character>
+<or>             ::= |
+<empty>          ::=
+@end example
+
 @node Installation
 @chapter Installation
 
@@ -269,24 +299,8 @@ current buffer use @kbd{M-x} @code{bnf-mode} @kbd{RET}.
 @chapter Customizing
 
 @cindex Customizing
-@vindex bnf-mode-algol-comments-style
-
-There are not so much customization options yet.  The most interested
-option is @code{bnf-mode-algol-comments-style}.  This variable can be
-changed to control comments style used in grammars.  Setting it to
-non-nil means use for BNF comments style introduced in ALGOL 60.  In
-this case the following "comment" conventions will hold:
-
-@multitable @columnfractions .7 .3
-@headitem The sequence of basic symbols @tab Is equivalent to
-@item @code{; comment <any sequence not containing ;>;}
-@tab @code{;}
-@item @code{begin comment <any sequence not containing ;>;}
-@tab @code{begin}
-@end multitable
-
-Note: enabling this feature will disable comments recognition, which
-start with semicolons only (@code{;}).
+
+There are not so much customization options yet.
 
 To customize @code{abbrev-mode} for @code{bnf-mode}, simple add preffered
 abbreviations to @code{bnf-mode-abbrev-table}.
diff --git a/test/bnf.bnf b/test/bnf.bnf
new file mode 100644
index 0000000..54913c0
--- /dev/null
+++ b/test/bnf.bnf
@@ -0,0 +1,34 @@
+;; This is canonical BNF notation represented with a BNF.
+;;
+;; The syntax of the BNF has been carefully copied from Revised ALGOL 60 report
+;; <http://www.masswerk.at/algol60/report.htm>.
+
+ <syntax>         ::= <rule> | <rule> <syntax>
+ <rule>           ::= <opt-ws> < <rule-name> > <opt-ws>
+                      ::= <opt-ws> <expression> <line-end>
+ <opt-ws>         ::= <space> <opt-ws> | <empty>
+ <expression>     ::= <list> | <list> <opt-ws> <or> <opt-ws>
+                      <expression>
+ <line-end>       ::= <opt-ws> <EOL> | <line-end> <line-end>
+ <list>           ::= <term> | <term> <opt-ws> <list>
+ <term>           ::= <literal> | < <rule-name> >
+ <literal>        ::= <character> <text>
+ <character>      ::= <letter> | <digit> | <symbol>
+ <letter>         ::= A | B | C | D | E | F | G | H | I | J | K | L |
+                      M | N | O | P | Q | R | S | T | U | V | W | X |
+                      Y | Z | a | b | c | d | e | f | g | h | i | j |
+                      k | l | m | n | o | p | q | r | s | t | u | v |
+                      w | x | y | z
+ <digit>          ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
+ <symbol>         ::= <or>  | <space>   | ! | # | $ | % | & | ( | ) |
+                      * | + | , | - | . | / | : | ~ | > | = | < | ? |
+                      @ | [ | \ | ] | ^ | _ | ` | ' | " | { | } | ;
+ <rule-name>      ::= <letter> | <rule-name> <rule-char>
+ <rule-char>      ::= <letter> | <digit> | -
+ <space>          ::= <space, tab or new line character>
+ <or>             ::= |
+ <empty>          ::=
+
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
diff --git a/test/ebnf-grammar.ebnf b/test/ebnf-grammar.ebnf
deleted file mode 100644
index b8e8f20..0000000
--- a/test/ebnf-grammar.ebnf
+++ /dev/null
@@ -1,68 +0,0 @@
-(*  This example defines Extended BNF informally.  Many of the syntax
-rules include a comment to explain their meaning; inside a comment a
-meta identifier is enclosed in angle brackets  <  and  >  to avoid
-confusion with similar English words.  The non-terminal symbols
-<letter>, <decimal_digit> and <character> are NOT defined.  The position
-of <comments> is stated in a comment but not formally defined.  *)
-
-(*  A <syntax_rule> defines the sequences of symbols represented by a
-<meta_identifier>  *)
-syntax = syntax_rule, { syntax_rule } ;
-syntax_rule = meta_identifier, '=', definitions_list, ';' ;
-
-(*  |  separates alternative <single_definitions>  *)
-definitions_list = single_definition, { '|', single_definition } ;
-
-(* ,  separates successive <terms>  *)
-single_definition = term, { ',', term } ;
-
-(*  A <term> represents any sequence of symbols that is defined by the
-<factor> but not defined by the <exception>  *)
-term = factor, ['-', exception] ;
-
-(*  A <factor> may be used as an <exception> if it could be replaced by
-a <factor> containing no <meta_identifiers>  *)
-exception =  factor;
-
-(*  The <integer> specifies the number of repetitions of the
-<primary>  *)
-factor = [ integer, '*' ], primary ;
-
-primary = optional_sequence | repeated_sequence | special_sequence
-          | grouped_sequence | meta_identifier | terminal_string
-          | empty ;
-
-empty = ;
-
-(*  The brackets  [  and  ]  enclose symbols which are optional  *)
-optional_sequence = '[', definitions_list, ']' ;
-
-(*  The brackets  {  and  }  enclose symbols which may be repeated any
-number of times  *)
-repeated_sequence = '{', definitions_list, '}' ;
-
-(*  The brackets  (  and  )  allow any <definitions_list> to be a
-<primary>  *)
-grouped_sequence = '(', definitions_list, ')' ;
-
-(*  A <terminal_string> represents the <characters> between the quote
-symbols '_'  or  "_"  *)
-terminal_string = "'", character - "'", { character - "'" }, "'"
-                  | '"', character - '"', { character - '"' }, '"' ;
-
-(*  A <meta_identifier> is the name of a syntactic element of the
-language being defined  *)
-meta_identifier = letter, { letter | decimal_digit } ;
-
-integer = decimal_digit, { decimal_digit } ;
-
-(*  The meaning of a <special_sequence> is not defined in the standard
-metalanguage.  *)
-special_sequence = '?', { character - '?' }, '?' ;
-
-(*  A comment is allowed anywhere outside a <terminal_string>,
-<meta_identifier>, <integer> or <special_sequence>  *)
-comment = '(*', { comment_symbol }, '*)' ;
-
-comment_symbol = comment | terminal_string | special_sequence
-                 | character ;
diff --git a/test/test-bnf-mode-font-lock.el b/test/test-bnf-mode-font-lock.el
index 41ea0ca..5de92cb 100644
--- a/test/test-bnf-mode-font-lock.el
+++ b/test/test-bnf-mode-font-lock.el
@@ -4,7 +4,7 @@
 
 ;; Author: Serghei Iakovlev <egrep@protonmail.ch>
 ;; Maintainer: Serghei Iakovlev <egrep@protonmail.ch>
-;; Version: 0.4.4
+;; Version: 0.4.5
 ;; URL: https://github.com/sergeyklay/bnf-mode
 
 ;;;; License
@@ -46,128 +46,57 @@
 
 (describe "BNF Fontification"
   (it "does not fontify strings"
-    (bnf-test-with-temp-buffer
-     "<string delimers> ::= \" | ' | ` | ”"
-     (should-not (bnf-get-face-at 23))
-     (should-not (bnf-get-face-at 27))
-     (should-not (bnf-get-face-at 31))
-     (should-not (bnf-get-face-at 35))))
-
-  (it "fontify line comments"
-    (custom-set-variables '(bnf-mode-algol-comments-style nil))
-    (bnf-test-with-temp-buffer
-     "; A
-
-<stm> ::= <decl> ; foo"
-     (should (eq (bnf-get-face-at 1) 'font-lock-comment-delimiter-face))
-     (should (eq (bnf-get-face-at 3) 'font-lock-comment-face))
-     (should-not (bnf-get-face-at 5))
-     (should (eq (bnf-get-face-at 24) 'font-lock-comment-face))))
-
-  ;; TODO(sergei): Implement me
-  (it "fontify ALGOL comments"
-    (custom-set-variables '(bnf-mode-algol-comments-style t))
-    (bnf-test-with-temp-buffer "" ))
-
-  (it "fontify nonterminals"
-    (bnf-test-with-temp-buffer
-     "<stm> ::= <decl>
-angle-brackets ::= are-optional"
-     ;; angle bracket
-     (should-not (bnf-get-face-at 1))
-     ;; "stm"
-     (should (eq (bnf-get-face-at 2) 'font-lock-function-name-face))
-     (should (eq (bnf-get-face-at 4) 'font-lock-function-name-face))
-     ;; angle bracket
-     (should-not (bnf-get-face-at 5))
-     ;; "::=" symbol
-     (should (eq (bnf-get-face-at 7) 'font-lock-constant-face))
-     (should (eq (bnf-get-face-at 9) 'font-lock-constant-face))
-     ;; angle bracket
-     (should-not (bnf-get-face-at 11))
-     ;; "dec" symbol
-     (should (eq (bnf-get-face-at 12) 'font-lock-builtin-face))
-     (should (eq (bnf-get-face-at 15) 'font-lock-builtin-face))))
-
-  (it "fontify nonterminals despite the case"
-    (bnf-test-with-temp-buffer
-     "<RULE> ::= <foo>
-<RuLe> ::= <foO>"
-     (should (eq (bnf-get-face-at 2) 'font-lock-function-name-face))
-     (should (eq (bnf-get-face-at 5) 'font-lock-function-name-face))
-     (should-not (bnf-get-face-at 17))
-     (should (eq (bnf-get-face-at 19) 'font-lock-function-name-face))
-     (should (eq (bnf-get-face-at 22) 'font-lock-function-name-face))
-     (should-not (bnf-get-face-at 23))
-     (should (eq (bnf-get-face-at 30) 'font-lock-builtin-face))
-     (should (eq (bnf-get-face-at 32) 'font-lock-builtin-face))
-     (should-not (bnf-get-face-at 33))))
-
-  (it "fontify nonterminals despite the indentation"
-    (bnf-test-with-temp-buffer
-     "   <rule> ::= <foo>"
-     (should-not (bnf-get-face-at 4))
-     (should (eq (bnf-get-face-at 5) 'font-lock-function-name-face))
-     (should (eq (bnf-get-face-at 6) 'font-lock-function-name-face))
-     (should (eq (bnf-get-face-at 7) 'font-lock-function-name-face))
-     (should (eq (bnf-get-face-at 8) 'font-lock-function-name-face))
-     (should-not (bnf-get-face-at 9))))
-
-  (it "fontify sequences"
-    (bnf-test-with-temp-buffer
-     "<rule> ::= <foo> <bar> <baz>"
-     ;; "<" angle bracket
-     (should-not (bnf-get-face-at 1))
-     ;; "rule"
-     (should (eq (bnf-get-face-at 2) 'font-lock-function-name-face))
-     (should (eq (bnf-get-face-at 5) 'font-lock-function-name-face))
-     ;; ">" angle bracket
-     (should-not (bnf-get-face-at 6))
-     ;; "foo"
-     (should (eq (bnf-get-face-at 13) 'font-lock-builtin-face))
-     (should (eq (bnf-get-face-at 15) 'font-lock-builtin-face))
-     ;; space
-     (should-not (bnf-get-face-at 17))
-     ;; "bar"
-     (should (eq (bnf-get-face-at 19) 'font-lock-builtin-face))
-     (should (eq (bnf-get-face-at 21) 'font-lock-builtin-face))
-     ;; space
-     (should-not (bnf-get-face-at 23))
-     ;; "baz"
-     (should (eq (bnf-get-face-at 25) 'font-lock-builtin-face))
-     (should (eq (bnf-get-face-at 27) 'font-lock-builtin-face))))
-
-  (it "fontify alternatives"
-    (bnf-test-with-temp-buffer
-     "<foo> | <bar> | <baz>"
-     ;; "foo"
-     (should (eq (bnf-get-face-at 2) 'font-lock-builtin-face))
-     (should (eq (bnf-get-face-at 4) 'font-lock-builtin-face))
-     ;; "|"
-     (should (eq (bnf-get-face-at 7) 'font-lock-warning-face))
-     ;; "bar"
-     (should (eq (bnf-get-face-at 10) 'font-lock-builtin-face))
-     (should (eq (bnf-get-face-at 12) 'font-lock-builtin-face))
-     ;; "|"
-     (should (eq (bnf-get-face-at 15) 'font-lock-warning-face))
-     ;; "baz"
-     (should (eq (bnf-get-face-at 18) 'font-lock-builtin-face))
-     (should (eq (bnf-get-face-at 20) 'font-lock-builtin-face))))
-
-  (it "fontify rule punctuation"
-    (bnf-test-with-temp-buffer
-     "
-<proper string> ::=
+    (expect "<string delimers> ::= \" | ' | ` | ”"
+            :to-be-fontified-as
+            '(("string delimers" function-name "::=" constant "|" warning
+               "|" warning "|" warning))))
+
+  (it "fontifies line comments"
+    (expect "; A
+     <stm> ::= <decl> ; foo"
+            :to-be-fontified-as
+            '(("; " comment-delimiter "A" comment)
+              ("stm" function-name "::=" constant "decl" builtin
+               "; foo" comment))))
+
+  (it "does not mix terminals and nonterminals"
+    (expect "<stm> ::= <decl>
+     angle-brackets ::= are-optional"
+            :to-be-fontified-as
+            '(("stm" function-name "::=" constant "decl" builtin)
+              ("::=" constant))))
+
+  (it "fontifies nonterminals despite the case"
+    (expect "<RULE> ::= <foo>
+     <RuLe> ::= <foO>"
+            :to-be-fontified-as
+            '(("RULE" function-name "::=" constant "foo" builtin)
+              ("RuLe" function-name "::=" constant "foO" builtin))))
+
+  (it "fontifies nonterminals despite the indentation"
+    (expect "   <rule> ::= <subrule>"
+            :to-be-fontified-as
+            '(("rule" function-name "::=" constant "subrule" builtin))))
+
+  (it "fontifies sequences"
+    (expect "<rule> ::= <foo> <bar> <baz>"
+            :to-be-fontified-as
+            '(("rule" function-name "::=" constant "foo" builtin
+               "bar" builtin "baz" builtin))))
+
+  (it "fontifies alternatives"
+    (expect "<foo> | <bar> | <baz>"
+            :to-be-fontified-as
+            '(("foo" builtin "|" warning "bar" builtin
+               "|" warning "baz" builtin))))
+
+  (it "fontifies rule punctuation"
+    (expect "<proper string> ::=
         <any sequence of symbols not containing ` or ' >
         | <empty>"
-     ;; "proper string"
-     (should (eq (bnf-get-face-at 3) 'font-lock-function-name-face))
-     (should (eq (bnf-get-face-at 15) 'font-lock-function-name-face))
-     ;; "any sequence of symbols not containing ` or ' "
-     (should (eq (bnf-get-face-at 31) 'font-lock-builtin-face))
-     (should (eq (bnf-get-face-at 76) 'font-lock-builtin-face))
-     ;; "empty"
-     (should (eq (bnf-get-face-at 90) 'font-lock-builtin-face))
-     (should (eq (bnf-get-face-at 94) 'font-lock-builtin-face)))))
+            :to-be-fontified-as
+            '(("proper string" function-name "::=" constant)
+              ("any sequence of symbols not containing ` or ' " builtin)
+              ("|" warning "empty" builtin)))))
 
 ;;; test-bnf-mode-font-lock.el ends here
diff --git a/test/test-bnf-mode-generic.el b/test/test-bnf-mode-generic.el
new file mode 100644
index 0000000..f7fc9a9
--- /dev/null
+++ b/test/test-bnf-mode-generic.el
@@ -0,0 +1,53 @@
+;;; test-bnf-mode-generic.el --- BNF Mode: Generic tests -*- lexical-binding: 
t; -*-
+
+;; Copyright (C) 2019-2020 Free Software Foundation, Inc.
+
+;; Author: Serghei Iakovlev <egrep@protonmail.ch>
+;; Maintainer: Serghei Iakovlev <egrep@protonmail.ch>
+;; Version: 0.4.5
+;; URL: https://github.com/sergeyklay/bnf-mode
+
+;;;; License
+
+;; This file is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License
+;; as published by the Free Software Foundation; either version 3
+;; of the License, or (at your option) any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this file.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Define test-suites to test common stuff of `bnf-mode' using `buttercup'.
+
+;;; Code:
+
+(require 'buttercup)
+
+(when (require 'undercover nil t)
+  ;; Track coverage, but don't send to coverage serivice.  Save in parent
+  ;; directory as undercover saves paths relative to the repository root.
+  (undercover "*.el" "test/utils.el"
+              (:report-file "coverage-final.json")
+              (:send-report nil)))
+
+(let* ((current-dir (file-name-directory (or load-file-name (buffer-file-name)
+                                             default-directory))))
+  (load (concat current-dir "utils.el") nil 'nomessage 'nosuffix))
+
+
+;;;; Tests
+
+(describe "bnf-mode"
+  (it "is derived from prog-mode"
+    (with-bnf-buffer
+     ""
+     (expect (derived-mode-p 'prog-mode)))))
+
+;;; test-bnf-mode-generic.el ends here
diff --git a/test/utils.el b/test/utils.el
index d3da4d8..c204cdb 100644
--- a/test/utils.el
+++ b/test/utils.el
@@ -3,8 +3,9 @@
 ;; Copyright (C) 2019-2020 Free Software Foundation, Inc
 
 ;; Author: Serghei Iakovlev <egrep@protonmail.ch>
+;;         immerrr <immerrr+lua@gmail.com>
 ;; Maintainer: Serghei Iakovlev <egrep@protonmail.ch>
-;; Version: 0.4.4
+;; Version: 0.4.5
 ;; URL: https://github.com/sergeyklay/bnf-mode
 
 ;;;; License
@@ -36,10 +37,10 @@
        ;; Don't load old byte-compiled versions
        (load-prefer-newer t))
   ;; Load the file under test
-  (load (expand-file-name "bnf-mode" source-directory)))
+  (load (expand-file-name "bnf-mode" source-directory) nil 'nomessage))
 
-(cl-defmacro bnf-test-with-temp-buffer (content &rest body)
-  "Evaluate BODY in a temporary buffer with CONTENT."
+(cl-defmacro with-bnf-buffer (content &rest body)
+  "Evaluate BODY in a temporary BNF buffer with CONTENT."
   (declare (debug t)
            (indent 1))
   `(with-temp-buffer
@@ -55,13 +56,81 @@
      (unwind-protect
          (progn ,@body))))
 
-(defun bnf-get-face-at (pos &optional content)
-  "Get the face at POS in CONTENT.
-If CONTENT is not given, return the face at POS in the current
-buffer."
-  (if content
-      (bnf-test-with-temp-buffer content
-                                 (get-text-property pos 'face))
-    (get-text-property pos 'face)))
+(defun bnf-make-font-lock-faces (sym)
+  "Decorate SYM with font-lock-%s-face.
+If SYM is a list, this function will be called recursively to
+decorate each of symbol."
+  (or (cond
+       ((symbolp sym)
+        (intern-soft (format "font-lock-%s-face" (symbol-name sym))))
+       ((listp sym) (mapcar 'bnf-make-font-lock-faces sym)))
+      sym))
+
+(defun get-str-faces (str)
+  "Find contiguous spans of non-default faces in STR.
+E.g. for properly fontified Lua string \"local x = 100\" it should return
+  '(\"local\" font-lock-keyword-face
+    \"x\" font-lock-variable-name-face
+    \"100\" font-lock-constant-face)"
+  (let ((pos 0)
+        nextpos
+        result prop newprop)
+    (while pos
+      (setq nextpos (next-property-change pos str)
+            newprop (or (get-text-property pos 'face str)
+                        (get-text-property pos 'font-lock-face str)))
+      (when (not (equal prop newprop))
+        (setq prop newprop)
+        (when (listp prop)
+          (when (eq (car-safe (last prop)) 'default)
+            (setq prop (butlast prop)))
+          (when (= 1 (length prop))
+            (setq prop (car prop)))
+          (when (symbolp prop)
+            (when (eq prop 'default)
+              (setq prop nil))))
+        (when prop
+          (push (substring-no-properties str pos nextpos) result)
+          (push prop result)))
+      (setq pos nextpos))
+    (nreverse result)))
+
+(defun bnf-get-line-faces (str)
+  "Find contiguous spans of non-default faces in each line of STR.
+The result is a list of lists."
+  (mapcar
+   'get-str-faces
+   (split-string
+    (with-bnf-buffer str (buffer-string))
+    "\n" nil)))
+
+(defun to-be-fontified-as (text faces)
+  "Check that TEXT is fontified using FACES.
+Custom matcher to test font locking using `buttercup'."
+  (let ((expected-faces (bnf-make-font-lock-faces faces))
+        (result-faces (bnf-get-line-faces text))
+        (lineno 1))
+    (when (/= (length expected-faces) (length result-faces))
+        (buttercup-fail "\
+Fontification check failed for:
+%S
+  Text contains %d lines, face list contains %d lines"
+                        text (length result-faces)
+                        (length expected-faces)))
+    (while expected-faces
+      (unless (equal (car expected-faces) (car result-faces))
+        (buttercup-fail "\
+Fontification check failed on line %d for:
+%S
+  Result faces:   %S
+  Expected faces: %S"
+                        lineno text (car expected-faces) (car result-faces)))
+      (setq expected-faces (cdr expected-faces)
+            result-faces (cdr result-faces)
+            lineno (1+ lineno)))
+    (cons t "Fontification check passed")))
+
+(buttercup-define-matcher :to-be-fontified-as (text faces)
+ (to-be-fontified-as (funcall text) (funcall faces)))
 
 ;;; utils.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]