summaryrefslogtreecommitdiff
path: root/test/lisp/net/shr-tests.el
blob: 171380534504e972b9664e05b7ec8364583c39c3 (plain)
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
;;; shr-tests.el --- tests for shr.el  -*- lexical-binding: t; -*-

;; Copyright (C) 2016-2024 Free Software Foundation, Inc.

;; Author: Lars Ingebrigtsen <larsi@gnus.org>

;; This file is part of GNU Emacs.

;; GNU Emacs 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.

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

;;; Commentary:

;;; Code:

(require 'ert)
(require 'ert-x)
(require 'shr)

(declare-function libxml-parse-html-region "xml.c")

(defun shr-test--rendering-check (name &optional context)
  "Render NAME.html and compare it to NAME.txt.
Raise a test failure if the rendered buffer does not match NAME.txt.
Append CONTEXT to the failure data, if non-nil."
  (let ((text-file (file-name-concat (ert-resource-directory) (concat name ".txt")))
        (html-file (file-name-concat (ert-resource-directory) (concat name ".html")))
        (description (if context (format "%s (%s)" name context) name)))
    (with-temp-buffer
      (insert-file-contents html-file)
      (let ((dom (libxml-parse-html-region (point-min) (point-max)))
            (shr-width 80)
            (shr-use-fonts nil))
        (erase-buffer)
        (shr-insert-document dom)
        (let ((result (buffer-substring-no-properties (point-min) (point-max)))
              (expected
               (with-temp-buffer
                 (insert-file-contents text-file)
                 (while (re-search-forward "%\\([0-9A-F][0-9A-F]\\)" nil t)
                   (replace-match (string (string-to-number (match-string 1) 16))
                                  t t))
                 (buffer-string))))
          (unless (equal result expected)
            (ert-fail (list description result expected))))))))

(defconst shr-test--rendering-extra-configs
  '(("blockquote"
     ;; Make sure blockquotes remain indented even when filling is
     ;; disabled (bug#69555).
     . ((shr-fill-text . nil))))
  "Extra customizations which can impact rendering.
This is a list of (NAME . SETTINGS) pairs.  NAME is the basename of a
set of txt/html files under shr-resources/, as passed to `shr-test'.
SETTINGS is a list of (OPTION . VALUE) pairs that are interesting to
validate for the NAME testcase.

The `rendering' testcase will test NAME once without altering any
settings, then once more for each (OPTION . VALUE) pair.")

(ert-deftest rendering ()
  (skip-unless (fboundp 'libxml-parse-html-region))
  (dolist (file (directory-files (ert-resource-directory) nil "\\.html\\'"))
    (let* ((name (string-remove-suffix ".html" file))
           (extra-options (alist-get name shr-test--rendering-extra-configs
                                     nil nil 'string=)))
      ;; Test once with default settings.
      (shr-test--rendering-check name)
      ;; Test once more for every extra option for this specific NAME.
      (pcase-dolist (`(,option-sym ,option-val)
                     extra-options)
        (let ((option-old (symbol-value option-sym)))
          (set option-sym option-val)
          (unwind-protect
              (shr-test--rendering-check
               name (format "with %s %s" option-sym option-val))
            (set option-sym option-old)))))))

(ert-deftest use-cookies ()
  (let ((shr-cookie-policy 'same-origin))
    (should
     (shr--use-cookies-p "http://images.fsf.org" '("http://www.fsf.org")))
    (should
     (shr--use-cookies-p "http://www.fsf.org" '("https://www.fsf.org")))
    (should
     (shr--use-cookies-p "http://www.fsf.org" '("https://www.fsf.org")))
    (should
     (shr--use-cookies-p "http://www.fsf.org" '("http://fsf.org")))
    (should-not
     (shr--use-cookies-p "http://www.gnu.org" '("http://www.fsf.org")))))

(ert-deftest shr-srcset ()
  (should (equal (shr--parse-srcset "") nil))

  (should (equal (shr--parse-srcset "a 10w, b 20w")
                 '(("b" 20) ("a" 10))))

  (should (equal (shr--parse-srcset "a 10w b 20w")
                 '(("a" 10))))

  (should (equal (shr--parse-srcset "https://example.org/1\n\n 10w , https://example.org/2 20w      ")
	         '(("https://example.org/2" 20) ("https://example.org/1" 10))))

  (should (equal (shr--parse-srcset "https://example.org/1,2\n\n 10w , https://example.org/2 20w      ")
	         '(("https://example.org/2" 20) ("https://example.org/1,2" 10)))))

(require 'shr)

;;; shr-tests.el ends here