emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
blob d12307d98baf246ea3c7cc8c016f963bf6557847 5841 bytes (raw)
name: testing/lisp/test-org-element-parser.el 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
 
;;; test-org-element-parser.el --- Tests for org-element.el parser

;; Copyright (C) 2021  Ihor Radchenko

;; Author: Ihor Radchenko <yantar92 at gmail dot com>

;; This program 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 program 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 program.  If not, see <https://www.gnu.org/licenses/>.

;;; Code:

(require 'org-element)

(defvar test-org-element-parser-properties
  '((:global :begin :end :contents-begin :contents-end :pre-blank :post-blank :post-affiliated)
    (headline :raw-value :title :level :priority :tags :todo-keyword :todo-type :footnote-section-p :archivedp :commentedp))
  "List of important properties that should be parsed.")

(defvar test-org-element-parser-source-directory "../lisp/test-org-element-parser-sources/"
  "Path to directory containing all the test Org files.
The expected parsed representation is stored alongside in .el files.
For example, parsed representation of file.org is in file.el.")

(defun test-org-element-parser-generate-syntax-sexp ()
  "Return SEXP with important parts of parsed representation of current Org buffer."
  (unless (derived-mode-p 'org-mode) (user-error "Not an Org buffer."))
  (let ((datum (org-element-parse-buffer 'object))
	(strip-func (lambda (el)
		      (let ((type (org-element-type el))
			    (plist (when (listp el) (nth 1 el)))
			    prop value tmpalist)
                        (if (eq type 'plain-text)
                            (set-text-properties 0 (length el) nil el)
			  (while plist
			    (setq prop (car plist))
			    (setq value (cadr plist))
			    (when (stringp value) (setq value (substring-no-properties value)))
			    (setq plist (cddr plist))
			    (when (or (memq prop (alist-get :global test-org-element-parser-properties))
				      (memq prop (alist-get type test-org-element-parser-properties)))
                              (push (cons prop value) tmpalist)))
                          (setq tmpalist (sort tmpalist (lambda (a b) (string< (symbol-name (car a))
                                                                          (symbol-name (car b))))))
			  (setf (nth 1 el)
                                (apply #'append
                                       (mapcar (lambda (c) (list (car c) (cdr c)))
                                               tmpalist))))))))
    (org-element-map datum (append '(plain-text)  org-element-all-elements org-element-all-objects)
      strip-func nil nil nil 'with-affiliated)
    ;; `org-element-map' never maps over `org-data'. Update it separately.
    (funcall strip-func datum)
    datum))

(defun test-org-element-parser-save-expected-result (&optional file)
  "Save reference parsed representation of current Org buffer or FILE.
The parsed representation will be saved alongside with the buffer file."
  (interactive)
  (with-current-buffer (if file
			   (get-buffer-create file)
                         (current-buffer))
    (save-buffer)
    (let ((datum (test-org-element-parser-generate-syntax-sexp))
	  (path (buffer-file-name))
          newpath)
      (unless (and path (file-exists-p path)) (user-error "Not in a file buffer."))
      (setq newpath (format "%s.el" (file-name-base path)))
      (with-temp-file newpath
        (condition-case err
            (progn
	      (pp datum (current-buffer))
              (message "Parsed representation saved to %s" (expand-file-name newpath)))
          (err (message "Failed to save parsed representation: \"%S\"" err)))))))

(defmacro org-test-element-verify (&optional file)
  "Verify `org-element-parse-buffer' for current Org buffer or FILE."
  `(progn
     (unless ,file
       (setq file (buffer-file-name))
       (save-buffer))
     (unless (and ,file (file-exists-p ,file))
       (user-error "%s does not exist." ,file))
     (let ((reference-file (format "%s%s.el"
                                   (file-name-directory ,file)
                                   (file-name-base ,file))))
       (unless (file-exists-p reference-file)
         (user-error "Reference result file %s does not exist." reference-file))
       (with-temp-buffer
         (insert-file-contents ,file)
         (org-mode)
         (should
          (equal (test-org-element-parser-generate-syntax-sexp)
	         (with-temp-buffer
                   (insert-file-contents reference-file)
	           (read (current-buffer)))))))))

(defmacro test-org-element-parser-files (&rest files)
  "Run `org-test-element-verify' for each file in FILES."
  `(progn
     (unless (and test-org-element-parser-source-directory
                  (file-exists-p test-org-element-parser-source-directory))
       (error "%s does not exist." test-org-element-parser-source-directory))
     (dolist (file '(,@files))
       (setq file (format "%s%s.org"
                          (file-name-as-directory test-org-element-parser-source-directory)
                          (file-name-base file)))
       (org-test-element-verify file))))

\f

(ert-deftest test-org-element-parser/simple-headlines ()
  "Basic tests for Org files with headings and plain text paragraphs."
  (test-org-element-parser-files "simple-heading"))

(ert-deftest test-org-element-parser/README ()
  "Test README.org in the example file repo."
  (test-org-element-parser-files "README"))

(provide 'test-org-element-parser)
;;; test-org-element-parser.el ends here

debug log:

solving d12307d98 ...
found d12307d98 in https://list.orgmode.org/orgmode/87fsqzi4tw.fsf@localhost/

applying [1/1] https://list.orgmode.org/orgmode/87fsqzi4tw.fsf@localhost/
diff --git a/testing/lisp/test-org-element-parser.el b/testing/lisp/test-org-element-parser.el
new file mode 100644
index 000000000..d12307d98

Checking patch testing/lisp/test-org-element-parser.el...
Applied patch testing/lisp/test-org-element-parser.el cleanly.

index at:
100644 d12307d98baf246ea3c7cc8c016f963bf6557847	testing/lisp/test-org-element-parser.el

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).