(examples-for date

("creates a single date"            (to-string (date 1965 6 8))                                 "1965-06-08" )
("navigates to next day"            (let d (date 2004  3 11) (to-string d.tomorrow))            "2004-03-12" )
("navigates to previous day"        (let d (date 2006  6 22) (to-string d.yesterday))           "2006-06-21" )
("navigates to previous year"       (let d (date 1971 12 18) (to-string d.last-year))           "1970-12-18" )
("navigates to next year"           (let d (date 1974  1 11) (to-string d.next-year))           "1975-01-11" )
("navigates to previous month"      (let d (date 1971 12 18) (to-string d.last-month))          "1971-11-18" )
("navigates to next month"          (let d (date 1974  1 11) (to-string d.next-month))          "1974-02-11" )
("jumps a year to previous month"   (let d (date 1974  1 11) (to-string d.last-month))          "1973-12-11" )
("navigates to previous week"       (let d (date 2008  2 16) (to-string d.last-week))           "2008-02-09" )
("navigates to next week"           (let d (date 1972 11 13) (to-string d.next-week))           "1972-11-20" )
("navigates to year start"          (let d (date 1972 11 13) (to-string d.beginning-of-year))   "1972-01-01" )
("navigates to year end"            (let d (date 1972 11 13) (to-string d.end-of-year))         "1972-12-31" )
("navigates to month start"         (let d (date 1971 11 18) (to-string d.beginning-of-month))  "1971-11-01" )
("navigates to month end"           (let d (date 1971 11 18) (to-string d.end-of-month))        "1971-11-30" )
("navigates to week start"          (let d (date 2015 11  6) (to-string d.beginning-of-week))   "2015-11-02" )
("navigates to week start from sun" (let d (date 2015 11  1) (to-string d.beginning-of-week))   "2015-10-26" )
("navigates to week end from sun"   (let d (date 2015 11  1) (to-string d.end-of-week))         "2015-11-01" )
("navigates to week end"            (let d (date 2015 11  6) (to-string d.end-of-week))         "2015-11-08" )

("works with apply"       (to-string (apply date '(2006 6 21))) "2006-06-21")
("works with apply again" (to-string (apply date 2006 6 21 nil)) "2006-06-21")

("parses string" (let d (date "2004-03-12") (list d.year d.month d.day)) (2004 3 12))

("can act as hash key"
 (with (h {} d (date 2015 11 8))
   (hash-set h d "on this day")
   (to-string (hash-get h (date 2015 11 8))))
 "on this day")

("equals itself"              (eq? (date 2004 3 12) (date 2004 3 12))  t  )
("does not equal another"     (eq? (date 2004 3 12) (date 2006 6 21))  nil)
("does not equal nil"         (eq? (date 2004 3 12) nil             )  nil)
("nil does not equal a date"  (eq? nil (date 2004 3 12)             )  nil)

("returns its year"      (let d (date 1999 12 31) d.year)     1999)
("returns its month"     (let d (date 1999 12 31) d.month)    12  )
("returns its day"       (let d (date 1999 12 31) d.day)      31  )
("returns its week-day"  (let d (date 1999 12 31) d.week-day) 5   )
("recognises not monday" (let d (date 2015 11  1) d.monday?   ) nil )
("recognises monday"     (let d (date 2015 11  2) d.monday?   ) t   )
("recognises tuesday"    (let d (date 2015 11  3) d.tuesday?  ) t   )
("recognises wednesday"  (let d (date 2015 11  4) d.wednesday?) t   )
("recognises thursday"   (let d (date 2015 11  5) d.thursday? ) t   )
("recognises friday"     (let d (date 2015 11  6) d.friday?   ) t   )
("recognises not friday" (let d (date 2015 11  7) d.friday?   ) nil )
("recognises saturday"   (let d (date 2015 11  7) d.saturday? ) t   )
("recognises sunday"     (let d (date 2015 11  8) d.sunday?   ) t   )
("adds days"             (let d (date 2015 11  8) (to-string (+ d  1))) "2015-11-09")
("adds more days"        (let d (date 2015 11  8) (to-string (+ d 10))) "2015-11-18")
("subtracts a day"       (let d (date 2015 11 18) (to-string (- d  1))) "2015-11-17")
("subtracts more days"   (let d (date 2015 11 18) (to-string (- d  5))) "2015-11-13")

("advances by -2 weeks"   (let d (date 1965  6  8) (to-string (+ d '(-2 week)))) "1965-05-25")
("advances by -1 week"    (let d (date 1965  6  8) (to-string (+ d '(-1 week)))) "1965-06-01")
("advances by  1 week"    (let d (date 1965  6  8) (to-string (+ d '( 1 week)))) "1965-06-15")
("advances by  2 weeks"   (let d (date 1965  6  8) (to-string (+ d '( 2 week)))) "1965-06-22")

("advances by -2 weeks"   (let d (date 1965  6  8) (to-string (+   d '(-2 week)))) "1965-05-25")
("advances by -1 week"    (let d (date 1965  6  8) (to-string (+   d '(-1 week)))) "1965-06-01")
("advances by  1 week"    (let d (date 1965  6  8) (to-string (+   d '( 1 week)))) "1965-06-15")
("advances by  2 weeks"   (let d (date 1965  6  8) (to-string (+   d '( 2 week)))) "1965-06-22")

("advances by -2 days"    (let d (date 1965  6  8) (to-string (+   d '(-2 day)))) "1965-06-06")
("advances by -1 day"     (let d (date 1965  6  8) (to-string (+   d '(-1 day)))) "1965-06-07")
("advances by  1 day"     (let d (date 1965  6  8) (to-string (+   d '( 1 day)))) "1965-06-09")
("advances by  2 days"    (let d (date 1965  6  8) (to-string (+   d '( 2 day)))) "1965-06-10")

("advances by -2 months"  (let d (date 1965  6  8) (to-string (+   d '(-2 month)))) "1965-04-08")
("advances by -1 month"   (let d (date 1965  6  8) (to-string (+   d '(-1 month)))) "1965-05-08")
("advances by  1 month"   (let d (date 1965  6  8) (to-string (+   d '( 1 month)))) "1965-07-08")
("advances by  2 months"  (let d (date 1965  6  8) (to-string (+   d '( 2 month)))) "1965-08-08")

("advances by -2 years"   (let d (date 1965  6  8) (to-string (+   d '(-2 year)))) "1963-06-08")
("advances by -1 year"    (let d (date 1965  6  8) (to-string (+   d '(-1 year)))) "1964-06-08")
("advances by  1 year"    (let d (date 1965  6  8) (to-string (+   d '( 1 year)))) "1966-06-08")
("advances by  2 years"   (let d (date 1965  6  8) (to-string (+   d '( 2 year)))) "1967-06-08")

("adapts for leap years"         (let d (date 2019 12 31) (to-string (+   d '( 2 month)))) "2020-02-29")
("jumps one year"                (let d (date 2019 12 31) (to-string (+   d '( 1 year) ))) "2020-12-31")
("jumps to 28 feb a year later"  (let d (date 2019 12 31) (to-string (+   d '(14 month)))) "2021-02-28")
("jumps to end of june"          (let d (date 2019 12 31) (to-string (+   d '( 6 month)))) "2020-06-30")
("jumps to end of july"          (let d (date 2019 12 31) (to-string (+   d '( 7 month)))) "2020-07-31")
("jumps from end feb to end feb" (let d (date 2020 02 29) (to-string (+   d '(12 month)))) "2021-02-28")

("finds anniversary before a given date in previous year"
 (to-string (anniversary/previous (date 2019 6 21) (date 1949 10 3)))
 "2018-10-03")

("finds anniversary before a given date in same year"
 (to-string (anniversary/previous (date 2019 11 20) (date 1949 10 3)))
 "2019-10-03")

("finds anniversary after a given date in same year"
 (to-string (anniversary/next (date 2019 6 21) (date 1949 10 3)))
 "2019-10-03")

("finds anniversary after a given date in following year"
 (to-string (anniversary/next (date 2019 11 20) (date 1949 10 3)))
 "2020-10-03"))

(examples-for future?

("is true for a future date"
 (let d (+ (today) 10)
   d.future?)
 t)
("is false for a past date"
 (let d (- (today) 10)
   d.future?)
 nil)
("is false for today"
 (let d (today)
   d.future?)
 nil))

(examples-for past?

("is true for a past date"
 (let d (- (today) 10)
   d.past?)
 t)
("is false for a future date"
 (let d (+ (today) 10)
   d.past?)
 nil)
("is false for today"
 (let d (today)
   d.past?)
 nil))