Following TDD principles, this commit refactors the fuzzy clock's granularity levels after Day Of Week to follow a more intuitive progression using "part of period" (early/middle/late) patterns. Changes: - Level 7: Replace "week" with "part-of-month" (early/middle/late October) - Level 8: Keep "month" unchanged - Level 9: Replace "season" with "part-of-season" (early/middle/late Fall) - Level 10: Add "part-of-year" (early/middle/late 2025) - Level 11: Add "year" (2025, 2026) Implementation: - Updated fuzzy-clock-format-time with new granularity logic - Part of month: days 1-10 = Early, 11-20 = Middle, 21+ = Late - Part of season: first month = Early, second = Middle, third = Late - Part of year: months 1-4 = Early, 5-8 = Middle, 9-12 = Late - Year: displays full year number Test coverage: - Added comprehensive Buttercup tests for all new granularity levels - 9 tests for part-of-month (covering all three parts) - 12 tests for part-of-season (all 4 seasons × 3 parts) - 12 tests for part-of-year (testing all three parts across years) - 3 tests for year granularity Documentation: - Updated Commentary section with new level descriptions - Updated defcustom fuzzy-clock-fuzziness with new options - Updated function docstrings to reflect new fuzziness values
669 lines
25 KiB
EmacsLisp
669 lines
25 KiB
EmacsLisp
;;; fuzzy-clock-test.el --- Tests for fuzzy-clock -*- lexical-binding: t; -*-
|
|
|
|
;;; Commentary:
|
|
;; Acceptance and unit tests for fuzzy-clock package
|
|
|
|
;;; Code:
|
|
|
|
(require 'buttercup)
|
|
(require 'fuzzy-clock)
|
|
|
|
;;; Acceptance Tests
|
|
;; These tests define the complete expected behavior of the fuzzy clock
|
|
|
|
(describe "Fuzzy Clock Acceptance Tests"
|
|
|
|
(describe "Level 1: Every 5 minutes fuzziness"
|
|
;; At this level, time is rounded to the nearest 5-minute interval
|
|
;; and expressed in natural language
|
|
|
|
(it "should say 'Three o'clock' at 3:00"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 0)
|
|
:to-equal "Three o'clock"))
|
|
|
|
(it "should say 'Five past three' at 3:05"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 5)
|
|
:to-equal "Five past three"))
|
|
|
|
(it "should say 'Ten past three' at 3:10"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 10)
|
|
:to-equal "Ten past three"))
|
|
|
|
(it "should say 'Quarter past three' at 3:15"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 15)
|
|
:to-equal "Quarter past three"))
|
|
|
|
(it "should say 'Twenty past three' at 3:20"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 20)
|
|
:to-equal "Twenty past three"))
|
|
|
|
(it "should say 'Twenty five past three' at 3:25"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 25)
|
|
:to-equal "Twenty five past three"))
|
|
|
|
(it "should say 'Half past three' at 3:30"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 30)
|
|
:to-equal "Half past three"))
|
|
|
|
(it "should say 'Twenty five to four' at 3:35"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 35)
|
|
:to-equal "Twenty five to four"))
|
|
|
|
(it "should say 'Twenty to four' at 3:40"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 40)
|
|
:to-equal "Twenty to four"))
|
|
|
|
(it "should say 'Quarter to four' at 3:45"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 45)
|
|
:to-equal "Quarter to four"))
|
|
|
|
(it "should say 'Ten to four' at 3:50"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 50)
|
|
:to-equal "Ten to four"))
|
|
|
|
(it "should say 'Five to four' at 3:55"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 55)
|
|
:to-equal "Five to four"))
|
|
|
|
(it "should handle midnight correctly"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 0 0)
|
|
:to-equal "Midnight"))
|
|
|
|
(it "should handle noon correctly"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 12 0)
|
|
:to-equal "Noon"))
|
|
|
|
;; Rounding tests for non-exact 5-minute intervals
|
|
(it "should round 3:03 to 'Five past three'"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 3)
|
|
:to-equal "Five past three"))
|
|
|
|
(it "should round 3:07 to 'Five past three'"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 7)
|
|
:to-equal "Five past three"))
|
|
|
|
(it "should round 3:13 to 'Quarter past three'"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 13)
|
|
:to-equal "Quarter past three"))
|
|
|
|
(it "should round 3:23 to 'Twenty five past three'"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 23)
|
|
:to-equal "Twenty five past three"))
|
|
|
|
(it "should round 3:38 to 'Twenty to four'"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 38)
|
|
:to-equal "Twenty to four"))
|
|
|
|
(it "should round 3:47 to 'Quarter to four'"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 47)
|
|
:to-equal "Quarter to four"))
|
|
|
|
(it "should round 3:52 to 'Ten to four'"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 52)
|
|
:to-equal "Ten to four"))
|
|
|
|
(it "should round 3:58 to 'Four o'clock'"
|
|
(expect (fuzzy-clock-format-time 'five-minutes 3 58)
|
|
:to-equal "Four o'clock")))
|
|
|
|
(describe "Level 2: Every 15 minutes fuzziness"
|
|
;; At this level, time is rounded to the nearest 15-minute interval
|
|
|
|
(it "should say 'Three o'clock' at 3:00"
|
|
(expect (fuzzy-clock-format-time 'fifteen-minutes 3 0)
|
|
:to-equal "Three o'clock"))
|
|
|
|
(it "should say 'Quarter past three' at 3:15"
|
|
(expect (fuzzy-clock-format-time 'fifteen-minutes 3 15)
|
|
:to-equal "Quarter past three"))
|
|
|
|
(it "should say 'Half past three' at 3:30"
|
|
(expect (fuzzy-clock-format-time 'fifteen-minutes 3 30)
|
|
:to-equal "Half past three"))
|
|
|
|
(it "should say 'Quarter to four' at 3:45"
|
|
(expect (fuzzy-clock-format-time 'fifteen-minutes 3 45)
|
|
:to-equal "Quarter to four"))
|
|
|
|
(it "should round 3:07 to 'Quarter past three'"
|
|
(expect (fuzzy-clock-format-time 'fifteen-minutes 3 7)
|
|
:to-equal "Quarter past three"))
|
|
|
|
(it "should round 3:37 to 'Half past three'"
|
|
(expect (fuzzy-clock-format-time 'fifteen-minutes 3 37)
|
|
:to-equal "Half past three"))
|
|
|
|
(it "should handle midnight correctly"
|
|
(expect (fuzzy-clock-format-time 'fifteen-minutes 0 0)
|
|
:to-equal "Midnight"))
|
|
|
|
(it "should handle noon correctly"
|
|
(expect (fuzzy-clock-format-time 'fifteen-minutes 12 0)
|
|
:to-equal "Noon")))
|
|
|
|
(describe "Level 3: Half hour fuzziness"
|
|
;; At this level, time is rounded to the nearest half hour
|
|
|
|
(it "should say 'Three o'clock' at 3:00"
|
|
(expect (fuzzy-clock-format-time 'half-hour 3 0)
|
|
:to-equal "Three o'clock"))
|
|
|
|
(it "should say 'Half past three' at 3:30"
|
|
(expect (fuzzy-clock-format-time 'half-hour 3 30)
|
|
:to-equal "Half past three"))
|
|
|
|
(it "should round 3:14 to 'Three o'clock'"
|
|
(expect (fuzzy-clock-format-time 'half-hour 3 14)
|
|
:to-equal "Three o'clock"))
|
|
|
|
(it "should round 3:15 to 'Half past three'"
|
|
(expect (fuzzy-clock-format-time 'half-hour 3 15)
|
|
:to-equal "Half past three"))
|
|
|
|
(it "should round 3:44 to 'Half past three'"
|
|
(expect (fuzzy-clock-format-time 'half-hour 3 44)
|
|
:to-equal "Half past three"))
|
|
|
|
(it "should round 3:45 to 'Four o'clock'"
|
|
(expect (fuzzy-clock-format-time 'half-hour 3 45)
|
|
:to-equal "Four o'clock"))
|
|
|
|
(it "should handle midnight correctly"
|
|
(expect (fuzzy-clock-format-time 'half-hour 0 0)
|
|
:to-equal "Midnight"))
|
|
|
|
(it "should handle noon correctly"
|
|
(expect (fuzzy-clock-format-time 'half-hour 12 0)
|
|
:to-equal "Noon")))
|
|
|
|
(describe "Level 4: Hour fuzziness"
|
|
;; At this level, time is rounded to the nearest hour
|
|
|
|
(it "should say 'Three o'clock' at 3:00"
|
|
(expect (fuzzy-clock-format-time 'hour 3 0)
|
|
:to-equal "Three o'clock"))
|
|
|
|
(it "should say 'Three o'clock' at 3:29"
|
|
(expect (fuzzy-clock-format-time 'hour 3 29)
|
|
:to-equal "Three o'clock"))
|
|
|
|
(it "should say 'Four o'clock' at 3:30"
|
|
(expect (fuzzy-clock-format-time 'hour 3 30)
|
|
:to-equal "Four o'clock"))
|
|
|
|
(it "should say 'Four o'clock' at 3:45"
|
|
(expect (fuzzy-clock-format-time 'hour 3 45)
|
|
:to-equal "Four o'clock"))
|
|
|
|
(it "should handle midnight correctly"
|
|
(expect (fuzzy-clock-format-time 'hour 0 0)
|
|
:to-equal "Midnight"))
|
|
|
|
(it "should handle noon correctly"
|
|
(expect (fuzzy-clock-format-time 'hour 12 0)
|
|
:to-equal "Noon"))
|
|
|
|
(it "should handle transition to midnight"
|
|
(expect (fuzzy-clock-format-time 'hour 23 45)
|
|
:to-equal "Midnight")))
|
|
|
|
(describe "Level 5: Part of day fuzziness"
|
|
;; At this level, time is expressed as part of the day
|
|
|
|
(it "should say 'Night' at 0:00"
|
|
(expect (fuzzy-clock-format-time 'part-of-day 0 0)
|
|
:to-equal "Night"))
|
|
|
|
(it "should say 'Night' at 4:00"
|
|
(expect (fuzzy-clock-format-time 'part-of-day 4 0)
|
|
:to-equal "Night"))
|
|
|
|
(it "should say 'Morning' at 6:00"
|
|
(expect (fuzzy-clock-format-time 'part-of-day 6 0)
|
|
:to-equal "Morning"))
|
|
|
|
(it "should say 'Morning' at 11:00"
|
|
(expect (fuzzy-clock-format-time 'part-of-day 11 0)
|
|
:to-equal "Morning"))
|
|
|
|
(it "should say 'Afternoon' at 12:00"
|
|
(expect (fuzzy-clock-format-time 'part-of-day 12 0)
|
|
:to-equal "Afternoon"))
|
|
|
|
(it "should say 'Afternoon' at 17:00"
|
|
(expect (fuzzy-clock-format-time 'part-of-day 17 0)
|
|
:to-equal "Afternoon"))
|
|
|
|
(it "should say 'Evening' at 18:00"
|
|
(expect (fuzzy-clock-format-time 'part-of-day 18 0)
|
|
:to-equal "Evening"))
|
|
|
|
(it "should say 'Evening' at 21:00"
|
|
(expect (fuzzy-clock-format-time 'part-of-day 21 0)
|
|
:to-equal "Evening"))
|
|
|
|
(it "should say 'Night' at 22:00"
|
|
(expect (fuzzy-clock-format-time 'part-of-day 22 0)
|
|
:to-equal "Night"))
|
|
|
|
(it "should say 'Night' at 23:59"
|
|
(expect (fuzzy-clock-format-time 'part-of-day 23 59)
|
|
:to-equal "Night")))
|
|
|
|
(describe "Level 6: Day of week fuzziness"
|
|
;; At this level, time is expressed as the day of the week
|
|
;; Function signature: (fuzziness hour minute &optional day month year dow dst utcoff)
|
|
;; DOW: 0=Sunday, 1=Monday, 2=Tuesday, 3=Wednesday, 4=Thursday, 5=Friday, 6=Saturday
|
|
|
|
(it "should say 'Sunday' for Sunday"
|
|
;; hour=12, minute=0, day=27, month=10, year=2024, dow=0 (Sunday)
|
|
(expect (fuzzy-clock-format-time 'day-of-week 12 0 27 10 2024 0 nil -25200)
|
|
:to-equal "Sunday"))
|
|
|
|
(it "should say 'Monday' for Monday"
|
|
;; hour=12, minute=0, day=28, month=10, year=2024, dow=1 (Monday)
|
|
(expect (fuzzy-clock-format-time 'day-of-week 12 0 28 10 2024 1 nil -25200)
|
|
:to-equal "Monday"))
|
|
|
|
(it "should say 'Tuesday' for Tuesday"
|
|
(expect (fuzzy-clock-format-time 'day-of-week 12 0 29 10 2024 2 nil -25200)
|
|
:to-equal "Tuesday"))
|
|
|
|
(it "should say 'Wednesday' for Wednesday"
|
|
(expect (fuzzy-clock-format-time 'day-of-week 12 0 30 10 2024 3 nil -25200)
|
|
:to-equal "Wednesday"))
|
|
|
|
(it "should say 'Thursday' for Thursday"
|
|
(expect (fuzzy-clock-format-time 'day-of-week 12 0 31 10 2024 4 nil -25200)
|
|
:to-equal "Thursday"))
|
|
|
|
(it "should say 'Friday' for Friday"
|
|
(expect (fuzzy-clock-format-time 'day-of-week 12 0 1 11 2024 5 nil -25200)
|
|
:to-equal "Friday"))
|
|
|
|
(it "should say 'Saturday' for Saturday"
|
|
(expect (fuzzy-clock-format-time 'day-of-week 12 0 2 11 2024 6 nil -25200)
|
|
:to-equal "Saturday")))
|
|
|
|
(describe "Level 7: Part of month fuzziness"
|
|
;; At this level, time is expressed as part of the month
|
|
;; Early (days 1-10), Middle (days 11-20), Late (days 21-end)
|
|
|
|
(it "should say 'Early January' for January 1st"
|
|
(expect (fuzzy-clock-format-time 'part-of-month 12 0 1 1 2024 1 nil -25200)
|
|
:to-equal "Early January"))
|
|
|
|
(it "should say 'Early October' for October 5th"
|
|
(expect (fuzzy-clock-format-time 'part-of-month 12 0 5 10 2024 6 nil -25200)
|
|
:to-equal "Early October"))
|
|
|
|
(it "should say 'Early December' for December 10th"
|
|
(expect (fuzzy-clock-format-time 'part-of-month 12 0 10 12 2024 2 nil -25200)
|
|
:to-equal "Early December"))
|
|
|
|
(it "should say 'Middle February' for February 11th"
|
|
(expect (fuzzy-clock-format-time 'part-of-month 12 0 11 2 2024 0 nil -25200)
|
|
:to-equal "Middle February"))
|
|
|
|
(it "should say 'Middle June' for June 15th"
|
|
(expect (fuzzy-clock-format-time 'part-of-month 12 0 15 6 2024 6 nil -25200)
|
|
:to-equal "Middle June"))
|
|
|
|
(it "should say 'Middle September' for September 20th"
|
|
(expect (fuzzy-clock-format-time 'part-of-month 12 0 20 9 2024 5 nil -25200)
|
|
:to-equal "Middle September"))
|
|
|
|
(it "should say 'Late March' for March 21st"
|
|
(expect (fuzzy-clock-format-time 'part-of-month 12 0 21 3 2024 4 nil -25200)
|
|
:to-equal "Late March"))
|
|
|
|
(it "should say 'Late October' for October 25th"
|
|
(expect (fuzzy-clock-format-time 'part-of-month 12 0 25 10 2024 5 nil -25200)
|
|
:to-equal "Late October"))
|
|
|
|
(it "should say 'Late December' for December 31st"
|
|
(expect (fuzzy-clock-format-time 'part-of-month 12 0 31 12 2024 2 nil -25200)
|
|
:to-equal "Late December")))
|
|
|
|
(describe "Level 8: Month fuzziness"
|
|
;; At this level, time is expressed as the month name
|
|
;; Test all 12 months
|
|
|
|
(it "should say 'January' for month 1"
|
|
(expect (fuzzy-clock-format-time 'month 12 0 15 1 2024 1 nil -25200)
|
|
:to-equal "January"))
|
|
|
|
(it "should say 'February' for month 2"
|
|
(expect (fuzzy-clock-format-time 'month 12 0 15 2 2024 4 nil -25200)
|
|
:to-equal "February"))
|
|
|
|
(it "should say 'March' for month 3"
|
|
(expect (fuzzy-clock-format-time 'month 12 0 15 3 2024 5 nil -25200)
|
|
:to-equal "March"))
|
|
|
|
(it "should say 'April' for month 4"
|
|
(expect (fuzzy-clock-format-time 'month 12 0 15 4 2024 1 nil -25200)
|
|
:to-equal "April"))
|
|
|
|
(it "should say 'May' for month 5"
|
|
(expect (fuzzy-clock-format-time 'month 12 0 15 5 2024 3 nil -25200)
|
|
:to-equal "May"))
|
|
|
|
(it "should say 'June' for month 6"
|
|
(expect (fuzzy-clock-format-time 'month 12 0 15 6 2024 6 nil -25200)
|
|
:to-equal "June"))
|
|
|
|
(it "should say 'July' for month 7"
|
|
(expect (fuzzy-clock-format-time 'month 12 0 15 7 2024 1 nil -25200)
|
|
:to-equal "July"))
|
|
|
|
(it "should say 'August' for month 8"
|
|
(expect (fuzzy-clock-format-time 'month 12 0 15 8 2024 4 nil -25200)
|
|
:to-equal "August"))
|
|
|
|
(it "should say 'September' for month 9"
|
|
(expect (fuzzy-clock-format-time 'month 12 0 15 9 2024 0 nil -25200)
|
|
:to-equal "September"))
|
|
|
|
(it "should say 'October' for month 10"
|
|
(expect (fuzzy-clock-format-time 'month 12 0 15 10 2024 2 nil -25200)
|
|
:to-equal "October"))
|
|
|
|
(it "should say 'November' for month 11"
|
|
(expect (fuzzy-clock-format-time 'month 12 0 15 11 2024 5 nil -25200)
|
|
:to-equal "November"))
|
|
|
|
(it "should say 'December' for month 12"
|
|
(expect (fuzzy-clock-format-time 'month 12 0 15 12 2024 0 nil -25200)
|
|
:to-equal "December")))
|
|
|
|
(describe "Level 9: Part of season fuzziness"
|
|
;; At this level, time is expressed as part of the current season
|
|
;; Seasons are: Winter (12,1,2), Spring (3,4,5), Summer (6,7,8), Fall (9,10,11)
|
|
;; First month = Early, Second month = Middle, Third month = Late
|
|
|
|
(it "should say 'Early Winter' in December"
|
|
(expect (fuzzy-clock-format-time 'part-of-season 12 0 15 12 2024 0 nil -25200)
|
|
:to-equal "Early Winter"))
|
|
|
|
(it "should say 'Middle Winter' in January"
|
|
(expect (fuzzy-clock-format-time 'part-of-season 12 0 15 1 2025 3 nil -25200)
|
|
:to-equal "Middle Winter"))
|
|
|
|
(it "should say 'Late Winter' in February"
|
|
(expect (fuzzy-clock-format-time 'part-of-season 12 0 15 2 2025 6 nil -25200)
|
|
:to-equal "Late Winter"))
|
|
|
|
(it "should say 'Early Spring' in March"
|
|
(expect (fuzzy-clock-format-time 'part-of-season 12 0 15 3 2025 6 nil -25200)
|
|
:to-equal "Early Spring"))
|
|
|
|
(it "should say 'Middle Spring' in April"
|
|
(expect (fuzzy-clock-format-time 'part-of-season 12 0 15 4 2025 2 nil -25200)
|
|
:to-equal "Middle Spring"))
|
|
|
|
(it "should say 'Late Spring' in May"
|
|
(expect (fuzzy-clock-format-time 'part-of-season 12 0 15 5 2025 4 nil -25200)
|
|
:to-equal "Late Spring"))
|
|
|
|
(it "should say 'Early Summer' in June"
|
|
(expect (fuzzy-clock-format-time 'part-of-season 12 0 15 6 2025 0 nil -25200)
|
|
:to-equal "Early Summer"))
|
|
|
|
(it "should say 'Middle Summer' in July"
|
|
(expect (fuzzy-clock-format-time 'part-of-season 12 0 15 7 2025 2 nil -25200)
|
|
:to-equal "Middle Summer"))
|
|
|
|
(it "should say 'Late Summer' in August"
|
|
(expect (fuzzy-clock-format-time 'part-of-season 12 0 15 8 2025 5 nil -25200)
|
|
:to-equal "Late Summer"))
|
|
|
|
(it "should say 'Early Fall' in September"
|
|
(expect (fuzzy-clock-format-time 'part-of-season 12 0 15 9 2025 1 nil -25200)
|
|
:to-equal "Early Fall"))
|
|
|
|
(it "should say 'Middle Fall' in October"
|
|
(expect (fuzzy-clock-format-time 'part-of-season 12 0 30 10 2025 4 nil -25200)
|
|
:to-equal "Middle Fall"))
|
|
|
|
(it "should say 'Late Fall' in November"
|
|
(expect (fuzzy-clock-format-time 'part-of-season 12 0 15 11 2025 6 nil -25200)
|
|
:to-equal "Late Fall")))
|
|
|
|
(describe "Level 10: Part of year fuzziness"
|
|
;; At this level, time is expressed as part of the year
|
|
;; Months 1-4 = Early, Months 5-8 = Middle, Months 9-12 = Late
|
|
|
|
(it "should say 'Early 2024' in January"
|
|
(expect (fuzzy-clock-format-time 'part-of-year 12 0 15 1 2024 1 nil -25200)
|
|
:to-equal "Early 2024"))
|
|
|
|
(it "should say 'Early 2025' in February"
|
|
(expect (fuzzy-clock-format-time 'part-of-year 12 0 15 2 2025 6 nil -25200)
|
|
:to-equal "Early 2025"))
|
|
|
|
(it "should say 'Early 2024' in March"
|
|
(expect (fuzzy-clock-format-time 'part-of-year 12 0 15 3 2024 5 nil -25200)
|
|
:to-equal "Early 2024"))
|
|
|
|
(it "should say 'Early 2025' in April"
|
|
(expect (fuzzy-clock-format-time 'part-of-year 12 0 15 4 2025 2 nil -25200)
|
|
:to-equal "Early 2025"))
|
|
|
|
(it "should say 'Middle 2024' in May"
|
|
(expect (fuzzy-clock-format-time 'part-of-year 12 0 15 5 2024 3 nil -25200)
|
|
:to-equal "Middle 2024"))
|
|
|
|
(it "should say 'Middle 2025' in June"
|
|
(expect (fuzzy-clock-format-time 'part-of-year 12 0 15 6 2025 0 nil -25200)
|
|
:to-equal "Middle 2025"))
|
|
|
|
(it "should say 'Middle 2024' in July"
|
|
(expect (fuzzy-clock-format-time 'part-of-year 12 0 15 7 2024 1 nil -25200)
|
|
:to-equal "Middle 2024"))
|
|
|
|
(it "should say 'Middle 2025' in August"
|
|
(expect (fuzzy-clock-format-time 'part-of-year 12 0 15 8 2025 5 nil -25200)
|
|
:to-equal "Middle 2025"))
|
|
|
|
(it "should say 'Late 2024' in September"
|
|
(expect (fuzzy-clock-format-time 'part-of-year 12 0 15 9 2024 0 nil -25200)
|
|
:to-equal "Late 2024"))
|
|
|
|
(it "should say 'Late 2025' in October"
|
|
(expect (fuzzy-clock-format-time 'part-of-year 12 0 15 10 2025 3 nil -25200)
|
|
:to-equal "Late 2025"))
|
|
|
|
(it "should say 'Late 2024' in November"
|
|
(expect (fuzzy-clock-format-time 'part-of-year 12 0 15 11 2024 5 nil -25200)
|
|
:to-equal "Late 2024"))
|
|
|
|
(it "should say 'Late 2025' in December"
|
|
(expect (fuzzy-clock-format-time 'part-of-year 12 0 15 12 2025 1 nil -25200)
|
|
:to-equal "Late 2025")))
|
|
|
|
(describe "Level 11: Year fuzziness"
|
|
;; At this level, time is expressed as just the year
|
|
|
|
(it "should say '2024' for any date in 2024"
|
|
(expect (fuzzy-clock-format-time 'year 12 0 15 6 2024 6 nil -25200)
|
|
:to-equal "2024"))
|
|
|
|
(it "should say '2025' for any date in 2025"
|
|
(expect (fuzzy-clock-format-time 'year 12 0 15 1 2025 3 nil -25200)
|
|
:to-equal "2025"))
|
|
|
|
(it "should say '2026' for any date in 2026"
|
|
(expect (fuzzy-clock-format-time 'year 12 0 30 10 2026 4 nil -25200)
|
|
:to-equal "2026")))
|
|
|
|
(describe "Season helper function (fuzzy-clock-format-season)"
|
|
;; Tests for the standalone season formatting function
|
|
|
|
(it "should say 'Winter' in December"
|
|
(expect (fuzzy-clock-format-season 12)
|
|
:to-equal "Winter"))
|
|
|
|
(it "should say 'Winter' in January"
|
|
(expect (fuzzy-clock-format-season 1)
|
|
:to-equal "Winter"))
|
|
|
|
(it "should say 'Winter' in February"
|
|
(expect (fuzzy-clock-format-season 2)
|
|
:to-equal "Winter"))
|
|
|
|
(it "should say 'Spring' in March"
|
|
(expect (fuzzy-clock-format-season 3)
|
|
:to-equal "Spring"))
|
|
|
|
(it "should say 'Spring' in April"
|
|
(expect (fuzzy-clock-format-season 4)
|
|
:to-equal "Spring"))
|
|
|
|
(it "should say 'Spring' in May"
|
|
(expect (fuzzy-clock-format-season 5)
|
|
:to-equal "Spring"))
|
|
|
|
(it "should say 'Summer' in June"
|
|
(expect (fuzzy-clock-format-season 6)
|
|
:to-equal "Summer"))
|
|
|
|
(it "should say 'Summer' in July"
|
|
(expect (fuzzy-clock-format-season 7)
|
|
:to-equal "Summer"))
|
|
|
|
(it "should say 'Summer' in August"
|
|
(expect (fuzzy-clock-format-season 8)
|
|
:to-equal "Summer"))
|
|
|
|
(it "should say 'Fall' in September"
|
|
(expect (fuzzy-clock-format-season 9)
|
|
:to-equal "Fall"))
|
|
|
|
(it "should say 'Fall' in October"
|
|
(expect (fuzzy-clock-format-season 10)
|
|
:to-equal "Fall"))
|
|
|
|
(it "should say 'Fall' in November"
|
|
(expect (fuzzy-clock-format-season 11)
|
|
:to-equal "Fall"))))
|
|
|
|
(describe "Fuzzy Clock Mode-line Integration"
|
|
;; Acceptance tests for mode-line integration
|
|
;; The mode should be a global minor mode that displays fuzzy time
|
|
|
|
(describe "fuzzy-clock-mode global minor mode"
|
|
(it "should be defined as a command"
|
|
(expect (fboundp 'fuzzy-clock-mode) :to-be-truthy))
|
|
|
|
(it "should have a mode variable that starts as nil"
|
|
(expect (boundp 'fuzzy-clock-mode) :to-be-truthy)
|
|
(expect fuzzy-clock-mode :to-be nil))
|
|
|
|
(it "should enable the mode when called"
|
|
(fuzzy-clock-mode 1)
|
|
(expect fuzzy-clock-mode :to-be-truthy))
|
|
|
|
(it "should disable the mode when called with -1"
|
|
(fuzzy-clock-mode 1) ; Enable first
|
|
(fuzzy-clock-mode -1) ; Then disable
|
|
(expect fuzzy-clock-mode :to-be nil)))
|
|
|
|
(describe "mode-line display"
|
|
(it "should mark fuzzy-clock-string as risky-local-variable for mode-line display"
|
|
;; Mode-line variables must be marked as risky to be evaluated safely in the mode-line
|
|
;; This prevents the "*invalid*" error when the variable is displayed
|
|
(expect (get 'fuzzy-clock-string 'risky-local-variable) :to-be t))
|
|
|
|
(it "should add fuzzy time string to global-mode-string when enabled"
|
|
(fuzzy-clock-mode -1) ; Ensure it's disabled first
|
|
(expect (member '(:eval fuzzy-clock-string) global-mode-string) :to-be nil)
|
|
(fuzzy-clock-mode 1)
|
|
(expect (member '(:eval fuzzy-clock-string) global-mode-string) :not :to-be nil))
|
|
|
|
(it "should remove fuzzy time string from global-mode-string when disabled"
|
|
(fuzzy-clock-mode 1) ; Enable first
|
|
(expect (member '(:eval fuzzy-clock-string) global-mode-string) :not :to-be nil)
|
|
(fuzzy-clock-mode -1) ; Disable
|
|
(expect (member '(:eval fuzzy-clock-string) global-mode-string) :to-be nil))
|
|
|
|
(it "should populate fuzzy-clock-string with current time when enabled"
|
|
(fuzzy-clock-mode 1)
|
|
(expect fuzzy-clock-string :not :to-be nil)
|
|
(expect (stringp fuzzy-clock-string) :to-be-truthy))
|
|
|
|
(it "should format fuzzy-clock-string with leading space for mode-line display"
|
|
(fuzzy-clock-mode 1)
|
|
(expect fuzzy-clock-string :not :to-be nil)
|
|
(expect (string-prefix-p " " fuzzy-clock-string) :to-be-truthy)
|
|
(expect (stringp fuzzy-clock-string) :to-be-truthy))
|
|
|
|
(it "should use :eval construct for mode-line display"
|
|
;; ACCEPTANCE TEST: This verifies we're using the correct mode-line construct.
|
|
;; Mode-lines require (:eval VARIABLE) not just 'VARIABLE for proper display.
|
|
;; The bare symbol 'fuzzy-clock-string doesn't evaluate in mode-line context.
|
|
(fuzzy-clock-mode 1)
|
|
;; Find the fuzzy-clock entry in global-mode-string
|
|
(let ((found-entry (seq-find
|
|
(lambda (entry)
|
|
(and (listp entry)
|
|
(eq (car entry) :eval)
|
|
(eq (cadr entry) 'fuzzy-clock-string)))
|
|
global-mode-string)))
|
|
(expect found-entry :not :to-be nil)
|
|
(expect (car found-entry) :to-equal :eval)
|
|
(expect (cadr found-entry) :to-equal 'fuzzy-clock-string))))
|
|
|
|
(describe "fuzziness configuration"
|
|
(it "should have a customizable fuzziness level variable"
|
|
(expect (boundp 'fuzzy-clock-fuzziness) :to-be-truthy)))
|
|
|
|
(describe "auto-update functionality"
|
|
(it "should have a customizable update interval"
|
|
(expect (boundp 'fuzzy-clock-update-interval) :to-be-truthy))
|
|
|
|
(it "should create a timer when mode is enabled"
|
|
(fuzzy-clock-mode -1) ; Ensure disabled
|
|
(fuzzy-clock-mode 1) ; Enable
|
|
(expect (boundp 'fuzzy-clock-timer) :to-be-truthy)
|
|
(expect fuzzy-clock-timer :not :to-be nil))
|
|
|
|
(it "should cancel the timer when mode is disabled"
|
|
(fuzzy-clock-mode 1) ; Enable
|
|
(expect fuzzy-clock-timer :not :to-be nil)
|
|
(fuzzy-clock-mode -1) ; Disable
|
|
(expect fuzzy-clock-timer :to-be nil))))
|
|
|
|
(describe "Fuzzy Clock Buffer Display"
|
|
;; Tests for dedicated buffer display
|
|
|
|
(describe "fuzzy-clock-display-buffer command"
|
|
(it "should be defined as a command"
|
|
(expect (fboundp 'fuzzy-clock-display-buffer) :to-be-truthy))
|
|
|
|
(it "should create or switch to a buffer named *Fuzzy Clock*"
|
|
(when (get-buffer "*Fuzzy Clock*")
|
|
(kill-buffer "*Fuzzy Clock*"))
|
|
(fuzzy-clock-display-buffer)
|
|
(expect (get-buffer "*Fuzzy Clock*") :not :to-be nil)
|
|
(expect (buffer-name (current-buffer)) :to-equal "*Fuzzy Clock*"))
|
|
|
|
(it "should display the current fuzzy time in the buffer"
|
|
(when (get-buffer "*Fuzzy Clock*")
|
|
(kill-buffer "*Fuzzy Clock*"))
|
|
(fuzzy-clock-display-buffer)
|
|
(with-current-buffer "*Fuzzy Clock*"
|
|
(let ((content (buffer-string)))
|
|
(expect (> (length content) 0) :to-be-truthy))))))
|
|
|
|
(describe "Fuzzy Clock Minibuffer Display"
|
|
;; Tests for minibuffer display command
|
|
|
|
(describe "fuzzy-clock-show command"
|
|
(it "should be defined as a command"
|
|
(expect (fboundp 'fuzzy-clock-show) :to-be-truthy))))
|
|
|
|
(provide 'fuzzy-clock-test)
|
|
|
|
;;; fuzzy-clock-test.el ends here
|