aboutsummaryrefslogtreecommitdiff
path: root/tests/base64.scm
blob: 504acbfa4f73a85443320efb826293bfb94f5718 (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
;;; guile-email --- Guile email parser
;;; Copyright © 2020 Arun Isaac <arunisaac@systemreboot.net>
;;;
;;; This file is part of guile-email.
;;;
;;; guile-email is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU Affero General Public License as
;;; published by the Free Software Foundation; either version 3 of the
;;; License, or (at your option) any later version.
;;;
;;; guile-email 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
;;; Affero General Public License for more details.
;;;
;;; You should have received a copy of the GNU Affero General Public
;;; License along with guile-email.  If not, see
;;; <http://www.gnu.org/licenses/>.

(use-modules (email base64)
             (ice-9 iconv))

(load "encoding.scm")

(define (string-has-only-valid-base64-characters? str)
  (string-every (char-set-union
                 (char-set #\newline #\return #\space)
                 (ucs-range->char-set (char->integer #\A) (1+ (char->integer #\Z)))
                 (ucs-range->char-set (char->integer #\a) (1+ (char->integer #\z)))
                 (ucs-range->char-set (char->integer #\0) (1+ (char->integer #\9)))
                 (char-set #\+ #\/ #\=))
                str))

(test-begin "base64")

(let ((decoded-text
       "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.")
      (encoded-text
       "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=")
      (charset "UTF-8"))
  (test-equal "base64 wikipedia example: decoding"
    (bytevector->string (base64-decode encoded-text) charset)
    decoded-text)

  (test-equal "base64 wikipedia example: encoding"
    (base64-encode
     (string->bytevector decoded-text charset))
    encoded-text)

  (test-assert "base64 wikipedia example: encoded output should not be more than 76 columns wide"
    (each-line-has-a-maximum-of-76-characters?
     (base64-encode
      (string->bytevector decoded-text charset)))))

(test-assert "base64 random bytevector: base64-encode and base64-decode are inverses of each other"
  (every (lambda (len)
           (let ((x (random-bytevector len)))
             (equal? x (base64-decode (base64-encode x)))))
         (iota 1000)))

(test-assert "base64 random bytevector: encoded output should not be more than 76 columns wide"
  (every (lambda (len)
           (each-line-has-a-maximum-of-76-characters?
            (base64-encode (random-bytevector len))))
         (iota 1000)))

(test-assert "base64 random bytevector: encoded output must only consist of characters from the base64 alphabet"
  (every (lambda (len)
           (string-has-only-valid-base64-characters?
            (base64-encode (random-bytevector len))))
         (iota 1000)))

(test-equal "base64 decoding should ignore invalid characters"
  (bytevector->string (base64-decode "..TWFu,") "utf-8")
  "Man")

(test-end "base64")