]> git.donarmstrong.com Git - lilypond.git/blob - guile18/test-suite/tests/srfi-19.test
New upstream version 2.19.65
[lilypond.git] / guile18 / test-suite / tests / srfi-19.test
1 ;;;; srfi-19.test --- test suite for SRFI-19 -*- scheme -*-
2 ;;;; Matthias Koeppe <mkoeppe@mail.math.uni-magdeburg.de> --- June 2001
3 ;;;;
4 ;;;;    Copyright (C) 2001, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
5 ;;;;
6 ;;;; This program is free software; you can redistribute it and/or modify
7 ;;;; it under the terms of the GNU General Public License as published by
8 ;;;; the Free Software Foundation; either version 2, or (at your option)
9 ;;;; any later version.
10 ;;;;
11 ;;;; This program is distributed in the hope that it will be useful,
12 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ;;;; GNU General Public License for more details.
15 ;;;;
16 ;;;; You should have received a copy of the GNU General Public License
17 ;;;; along with this software; see the file COPYING.  If not, write to
18 ;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 ;;;; Boston, MA 02110-1301 USA
20
21 ;; SRFI-19 overrides current-date, so we have to do the test in a
22 ;; separate module, or later tests will fail.
23
24 (define-module (test-suite test-srfi-19)
25   :duplicates (last)  ;; avoid warning about srfi-19 replacing `current-time'
26   :use-module (test-suite lib)
27   :use-module (srfi srfi-19)
28   :use-module (ice-9 format))
29
30 (define (with-tz* tz thunk)
31   "Temporarily set the TZ environment variable to the passed string
32 value and call THUNK."
33   (let ((old-tz #f))
34     (dynamic-wind
35         (lambda ()
36           (set! old-tz (getenv "TZ"))
37           (putenv (format "TZ=~A" tz)))
38         thunk
39         (lambda ()
40           (if old-tz
41               (putenv (format "TZ=~A" old-tz))
42               (putenv "TZ"))))))
43
44 (defmacro with-tz (tz . body)
45   `(with-tz* ,tz (lambda () ,@body)))
46
47 (define (test-integral-time-structure date->time)
48   "Test whether the given DATE->TIME procedure creates a time
49 structure with integral seconds.  (The seconds shall be maintained as
50 integers, or precision may go away silently.  The SRFI-19 reference
51 implementation was not OK for Guile in this respect because of Guile's
52 incomplete numerical tower implementation.)"
53   (pass-if (format "~A makes integer seconds"
54                    date->time)
55            (exact? (time-second
56                     (date->time (make-date 0 0 0 12 1 6 2001 0))))))
57
58 (define (test-time->date time->date date->time)
59   (pass-if (format "~A works"
60                    time->date)
61            (begin
62              (time->date (date->time (make-date 0 0 0 12 1 6 2001 0)))
63              #t)))
64
65 (define (test-dst time->date date->time)
66   (pass-if (format "~A respects local DST if no TZ-OFFSET given"
67                    time->date)
68            (let ((time (date->time (make-date 0 0 0 12 1 6 2001 0))))
69              ;; on 2001-06-01, there should be 4 hours zone offset
70              ;; between EST (EDT) and GMT
71              (= (date-zone-offset
72                  (with-tz "EST5EDT"
73                    (time->date time)))
74                 -14400))))
75
76 (define-macro (test-time-conversion a b)
77   (let* ((a->b-sym (symbol-append a '-> b))
78          (b->a-sym (symbol-append b '-> a)))
79     `(pass-if (format "~A and ~A work and are inverses of each other"
80                       ',a->b-sym ',b->a-sym)
81               (let ((time (make-time ,a 12345 67890123)))
82                 (time=? time (,b->a-sym (,a->b-sym time)))))))
83
84 (define (test-time-comparison cmp a b)
85   (pass-if (format #f "~A works" cmp)
86            (cmp a b)))
87
88 (define (test-time-arithmetic op a b res)
89   (pass-if (format #f "~A works" op)
90            (time=? (op a b) res)))
91
92 ;; return true if time objects X and Y are equal
93 (define (time-equal? x y)
94   (and (eq?  (time-type x)       (time-type y))
95        (eqv? (time-second x)     (time-second y))
96        (eqv? (time-nanosecond x) (time-nanosecond y))))
97
98 (with-test-prefix "SRFI date/time library"
99   ;; check for typos and silly errors
100   (pass-if "date-zone-offset is defined"
101            (and (defined? 'date-zone-offset)
102                 date-zone-offset
103                 #t))
104   (pass-if "add-duration is defined"
105            (and (defined? 'add-duration)
106                 add-duration
107                 #t))
108   (pass-if "(current-time time-tai) works"
109            (time? (current-time time-tai)))
110   (pass-if "(current-time time-process) works"
111            (time? (current-time time-process)))
112   (test-time-conversion time-utc time-tai)
113   (test-time-conversion time-utc time-monotonic)
114   (test-time-conversion time-tai time-monotonic)
115   (pass-if "string->date works"
116            (begin (string->date "2001-06-01@14:00" "~Y-~m-~d@~H:~M")
117                   #t))
118   ;; check for code paths where reals were passed to quotient, which
119   ;; doesn't work in Guile (and is unspecified in R5RS)
120   (test-time->date time-utc->date date->time-utc)
121   (test-time->date time-tai->date date->time-tai)
122   (test-time->date time-monotonic->date date->time-monotonic)
123   (pass-if "Fractional nanoseconds are handled"
124            (begin (make-time time-duration 1000000000.5 0) #t))
125   ;; the seconds in a time shall be maintained as integers, or
126   ;; precision may silently go away
127   (test-integral-time-structure date->time-utc)
128   (test-integral-time-structure date->time-tai)
129   (test-integral-time-structure date->time-monotonic)
130   ;; check for DST and zone related problems
131   (pass-if "date->time-utc is the inverse of time-utc->date"
132            (let ((time (date->time-utc
133                         (make-date 0 0 0 14 1 6 2001 7200))))
134              (time=? time
135                      (date->time-utc (time-utc->date time 7200)))))
136   (test-dst time-utc->date date->time-utc)
137   (test-dst time-tai->date date->time-tai)
138   (test-dst time-monotonic->date date->time-monotonic)
139   (test-dst julian-day->date date->julian-day)
140   (test-dst modified-julian-day->date date->modified-julian-day)
141
142   (pass-if "`date->julian-day' honors timezone"
143     (let ((now (current-date -14400)))
144       (time=? (date->time-utc (julian-day->date (date->julian-day now)))
145               (date->time-utc now))))
146
147   (pass-if "string->date respects local DST if no time zone is read"
148            (time=? (date->time-utc
149                     (with-tz "EST5EDT"
150                       (string->date "2001-06-01@08:00" "~Y-~m-~d@~H:~M")))
151                    (date->time-utc
152                     (make-date 0 0 0 12 1 6 2001 0))))
153   ;; check time comparison procedures
154   (let* ((time1 (make-time time-monotonic 0 0))
155          (time2 (make-time time-monotonic 0 0))
156          (time3 (make-time time-monotonic 385907 998360432))
157          (time4 (make-time time-monotonic 385907 998360432)))
158     (test-time-comparison time<=? time1 time3)
159     (test-time-comparison time<?  time1 time3)
160     (test-time-comparison time=?  time1 time2)
161     (test-time-comparison time>=? time3 time3)
162     (test-time-comparison time>?  time3 time2))
163   ;; check time arithmetic procedures
164   (let* ((time1 (make-time time-monotonic 0 0))
165          (time2 (make-time time-monotonic 385907 998360432))
166          (diff (time-difference time2 time1)))
167     (test-time-arithmetic add-duration time1 diff time2)
168     (test-time-arithmetic subtract-duration time2 diff time1))
169
170   (with-test-prefix "date->time-tai"
171     ;; leap second 1 Jan 1999, 1 second of UTC in make-date is out as 2
172     ;; seconds of TAI in date->time-tai
173     (pass-if "31dec98 23:59:59"
174       (time-equal? (make-time time-tai 0 915148830)
175                    (date->time-tai (make-date 0 59 59 23 31 12 1998 0))))
176     (pass-if "1jan99 0:00:00"
177       (time-equal? (make-time time-tai 0 915148832)
178                    (date->time-tai (make-date 0 0  0  0   1  1 1999 0))))
179
180     ;; leap second 1 Jan 2006, 1 second of UTC in make-date is out as 2
181     ;; seconds of TAI in date->time-tai
182     (pass-if "31dec05 23:59:59"
183       (time-equal? (make-time time-tai 0 1136073631)
184                    (date->time-tai (make-date 0 59 59 23 31 12 2005 0))))
185     (pass-if "1jan06 0:00:00"
186       (time-equal? (make-time time-tai 0 1136073633)
187                    (date->time-tai (make-date 0 0  0  0   1  1 2006 0)))))
188
189   (with-test-prefix "date-week-number"
190     (pass-if (= 0 (date-week-number (make-date 0 0 0 0 1 1 1984 0) 0)))
191     (pass-if (= 0 (date-week-number (make-date 0 0 0 0 7 1 1984 0) 0)))
192     (pass-if (= 1 (date-week-number (make-date 0 0 0 0 8 1 1984 0) 0)))))
193
194
195 ;; Local Variables:
196 ;; eval: (put 'with-tz 'scheme-indent-function 1)
197 ;; End: