1+ /**
2+ * Unit tests for IsoDatetime
3+ *
4+ * AI Usage:
5+ * - This code was originally generated using
6+ * 1. OpenAI/GPT OSS 120b on Roo Code
7+ * 2. Gemini 2.5 Flash and 2.5 Pro
8+ * then modified to fix incorrect implementations and fit project needs.
9+ * The first commit contains these corrections so that all code committed
10+ * works as designed.
11+ */
112import { describe , test , expect } from '@jest/globals' ;
213import { IsoDatetime } from './IsoDatetime.js' ;
314
@@ -60,6 +71,9 @@ describe('IsoDatetime.parse – valid inputs', () => {
6071
6172describe ( 'IsoDatetime.parse – invalid inputs' , ( ) => {
6273 const invalid = [
74+ '2025-03-01' , // date only
75+ '2025-03' , // month only
76+ '2025' , // year only
6377 '2025-03-01 12:34:56Z' , // no 'T' separator
6478 '2025-03-01T12:34Z' , // missing seconds
6579 '2025-03-01T12:34:56.789' , // missing Z
@@ -97,54 +111,76 @@ describe('IsoDatetime.toString – formatting', () => {
97111 } ) ;
98112} ) ;
99113
114+
115+ describe ( 'IsoDatetime.toIsoDate' , ( ) => {
116+ const tests = [
117+ { input : '2025-03-01T12:34:56Z' , expected : '2025-03-01' } ,
118+ { input : '2025-03-01T12:34:56.001Z' , expected : '2025-03-01' } ,
119+ { input : '2025-03-01T12:34:56+02:00' , expected : '2025-03-01' } ,
120+ { input : '2025-03-01T12:34:56-04:30' , expected : '2025-03-01' } ,
121+ ] ;
122+
123+ tests . forEach ( ( { input, expected } ) => {
124+ test ( `converts an IsoDatetime(${ input } ) to its IsoDate equivalent` , ( ) => {
125+ const isoDatetime = IsoDatetime . parse ( input ) ;
126+ const isoDate = isoDatetime . toIsoDate ( ) ;
127+ expect ( isoDate . toString ( ) ) . toBe ( expected ) ;
128+ } ) ;
129+ } ) ;
130+ } ) ;
131+
100132describe ( 'IsoDatetime.getNextDay – day increments and decrements' , ( ) => {
133+ test ( 'regular date: March 4 +1 day => March 5' , ( ) => {
134+ const dt = IsoDatetime . parse ( '2024-03-04T00:00:00Z' ) ;
135+ expect ( dt . getNextDay ( ) ) . toEqual ( IsoDatetime . parse ( '2024-03-05T00:00:00Z' ) ) ;
136+ } ) ;
101137 test ( 'leap year: Feb 28 +1 day => Feb 29' , ( ) => {
102138 const dt = IsoDatetime . parse ( '2024-02-28T00:00:00Z' ) ;
103- expect ( dt . getNextDay ( ) ) . toBe ( '2024-02-29T00:00:00Z' ) ;
139+ expect ( dt . getNextDay ( ) ) . toEqual ( IsoDatetime . parse ( '2024-02-29T00:00:00Z' ) ) ;
104140 } ) ;
105141
106142 test ( 'non‑leap year: Feb 28 +1 day => Mar 01' , ( ) => {
107143 const dt = IsoDatetime . parse ( '2025-02-28T00:00:00Z' ) ;
108- expect ( dt . getNextDay ( 1 ) ) . toBe ( '2025-03-01T00:00:00Z' ) ;
144+ expect ( dt . getNextDay ( 1 ) ) . toEqual ( IsoDatetime . parse ( '2025-03-01T00:00:00Z' ) ) ;
109145 } ) ;
110146
111147 test ( 'leap day: Feb 29 +1 day => Mar 01' , ( ) => {
112148 const dt = IsoDatetime . parse ( '2024-02-29T00:00:00Z' ) ;
113- expect ( dt . getNextDay ( 1 ) ) . toBe ( '2024-03-01T00:00:00Z' ) ;
149+ expect ( dt . getNextDay ( 1 ) ) . toEqual ( IsoDatetime . parse ( '2024-03-01T00:00:00Z' ) ) ;
114150 } ) ;
115151
116152 test ( 'month boundary: Jan 31 +1 day => Feb 01' , ( ) => {
117153 const dt = IsoDatetime . parse ( '2025-01-31T00:00:00Z' ) ;
118- expect ( dt . getNextDay ( 1 ) ) . toBe ( '2025-02-01T00:00:00Z' ) ;
154+ expect ( dt . getNextDay ( 1 ) ) . toEqual ( IsoDatetime . parse ( '2025-02-01T00:00:00Z' ) ) ;
119155 } ) ;
120156
121157 test ( 'year boundary: Dec 31 +1 day => Jan 01 of next year' , ( ) => {
122158 const dt = IsoDatetime . parse ( '2025-12-31T00:00:00Z' ) ;
123- expect ( dt . getNextDay ( 1 ) ) . toBe ( '2026-01-01T00:00:00Z' ) ;
159+ expect ( dt . getNextDay ( 1 ) ) . toEqual ( IsoDatetime . parse ( '2026-01-01T00:00:00Z' ) ) ;
124160 } ) ;
125161
126162 test ( 'century non‑leap year (1900): Feb 28 +1 day => Mar 01' , ( ) => {
127163 const dt = IsoDatetime . parse ( '1900-02-28T00:00:00Z' ) ;
128- expect ( dt . getNextDay ( 1 ) ) . toBe ( '1900-03-01T00:00:00Z' ) ;
164+ expect ( dt . getNextDay ( 1 ) ) . toEqual ( IsoDatetime . parse ( '1900-03-01T00:00:00Z' ) ) ;
129165 } ) ;
130166
131167 test ( 'century leap year (2000): Feb 28 +1 day => Feb 29' , ( ) => {
132168 const dt = IsoDatetime . parse ( '2000-02-28T00:00:00Z' ) ;
133- expect ( dt . getNextDay ( 1 ) ) . toBe ( '2000-02-29T00:00:00Z' ) ;
169+ expect ( dt . getNextDay ( 1 ) ) . toEqual ( IsoDatetime . parse ( '2000-02-29T00:00:00Z' ) ) ;
134170 } ) ;
135171
136172 test ( 'negative increment: Mar 01 -1 day => Feb 28 (non‑leap year)' , ( ) => {
137173 const dt = IsoDatetime . parse ( '2025-03-01T00:00:00Z' ) ;
138- expect ( dt . getNextDay ( - 1 ) ) . toBe ( '2025-02-28T00:00:00Z' ) ;
174+ expect ( dt . getNextDay ( - 1 ) ) . toEqual ( IsoDatetime . parse ( '2025-02-28T00:00:00Z' ) ) ;
139175 } ) ;
140176
141177 test ( 'negative increment: Mar 01 -1 day => Feb 28 (leap year)' , ( ) => {
142178 const dt = IsoDatetime . parse ( '2024-03-01T00:00:00Z' ) ;
143- expect ( dt . getNextDay ( - 1 ) ) . toBe ( '2024-02-29T00:00:00Z' ) ;
179+ expect ( dt . getNextDay ( - 1 ) ) . toEqual ( IsoDatetime . parse ( '2024-02-29T00:00:00Z' ) ) ;
144180 } ) ;
145181
146182 test ( 'negative crossing year: Jan 01 -1 day => Dec 31 of previous year' , ( ) => {
147183 const dt = IsoDatetime . parse ( '2025-01-01T00:00:00Z' ) ;
148- expect ( dt . getNextDay ( - 1 ) ) . toBe ( '2024-12-31T00:00:00Z' ) ;
184+ expect ( dt . getNextDay ( - 1 ) ) . toEqual ( IsoDatetime . parse ( '2024-12-31T00:00:00Z' ) ) ;
149185 } ) ;
150- } ) ;
186+ } ) ;
0 commit comments