@@ -24,7 +24,7 @@ describe("environment patching units", () => {
2424 const patchedMath = patchMath ( originalMath ) ;
2525
2626 expect ( ( ) => patchedMath . random ( ) ) . toThrow (
27- "Math.random() isn't currently supported within workflows" ,
27+ "Math.random() isn't yet supported within workflows" ,
2828 ) ;
2929 } ) ;
3030
@@ -110,7 +110,10 @@ describe("environment patching units", () => {
110110
111111 expect ( DeterministicDate . parse ) . toBe ( originalDate . parse ) ;
112112 expect ( DeterministicDate . UTC ) . toBe ( originalDate . UTC ) ;
113+
114+ // Prototype should be the same as original (no patching currently)
113115 expect ( DeterministicDate . prototype ) . toBe ( originalDate . prototype ) ;
116+ expect ( DeterministicDate . prototype . constructor ) . toBe ( DeterministicDate ) ;
114117 } ) ;
115118
116119 it ( "should not affect the original Date constructor" , ( ) => {
@@ -121,6 +124,167 @@ describe("environment patching units", () => {
121124 // Original Date should be unchanged
122125 expect ( Date . now ) . toBe ( originalNow ) ;
123126 } ) ;
127+
128+ describe ( "behavior validation vs original Date" , ( ) => {
129+ it ( "should produce identical outputs for specific dates" , ( ) => {
130+ const DeterministicDate = createDeterministicDate ( Date , mockGetGenerationState ) ;
131+
132+ // Test with specific timestamps
133+ const timestamps = [
134+ 0 , // Unix epoch
135+ 946684800000 , // Y2K
136+ 1640995200000 , // 2022-01-01
137+ 2023 , 0 , 15 , 10 , 30 , 45 , 123 // Feb 15, 2023 10:30:45.123
138+ ] ;
139+
140+ for ( const ts of [ timestamps [ 0 ] , timestamps [ 1 ] , timestamps [ 2 ] ] ) {
141+ const original = new Date ( ts ) ;
142+ const deterministic = new DeterministicDate ( ts ) ;
143+
144+ expect ( deterministic . getTime ( ) ) . toBe ( original . getTime ( ) ) ;
145+ expect ( deterministic . getFullYear ( ) ) . toBe ( original . getFullYear ( ) ) ;
146+ expect ( deterministic . getMonth ( ) ) . toBe ( original . getMonth ( ) ) ;
147+ expect ( deterministic . getDate ( ) ) . toBe ( original . getDate ( ) ) ;
148+ expect ( deterministic . getHours ( ) ) . toBe ( original . getHours ( ) ) ;
149+ expect ( deterministic . getMinutes ( ) ) . toBe ( original . getMinutes ( ) ) ;
150+ expect ( deterministic . getSeconds ( ) ) . toBe ( original . getSeconds ( ) ) ;
151+ expect ( deterministic . getMilliseconds ( ) ) . toBe ( original . getMilliseconds ( ) ) ;
152+ }
153+
154+ // Test with constructor args
155+ const original = new Date ( 2023 , 0 , 15 , 10 , 30 , 45 , 123 ) ;
156+ const deterministic = new DeterministicDate ( 2023 , 0 , 15 , 10 , 30 , 45 , 123 ) ;
157+
158+ expect ( deterministic . getFullYear ( ) ) . toBe ( original . getFullYear ( ) ) ;
159+ expect ( deterministic . getMonth ( ) ) . toBe ( original . getMonth ( ) ) ;
160+ expect ( deterministic . getDate ( ) ) . toBe ( original . getDate ( ) ) ;
161+ expect ( deterministic . getHours ( ) ) . toBe ( original . getHours ( ) ) ;
162+ expect ( deterministic . getMinutes ( ) ) . toBe ( original . getMinutes ( ) ) ;
163+ expect ( deterministic . getSeconds ( ) ) . toBe ( original . getSeconds ( ) ) ;
164+ expect ( deterministic . getMilliseconds ( ) ) . toBe ( original . getMilliseconds ( ) ) ;
165+ } ) ;
166+
167+ it ( "should produce identical string representations for deterministic dates" , ( ) => {
168+ const DeterministicDate = createDeterministicDate ( Date , mockGetGenerationState ) ;
169+
170+ const timestamp = 1640995200000 ; // 2022-01-01T00:00:00.000Z
171+ const original = new Date ( timestamp ) ;
172+ const deterministic = new DeterministicDate ( timestamp ) ;
173+
174+ expect ( deterministic . toISOString ( ) ) . toBe ( original . toISOString ( ) ) ;
175+ expect ( deterministic . toUTCString ( ) ) . toBe ( original . toUTCString ( ) ) ;
176+ expect ( deterministic . toDateString ( ) ) . toBe ( original . toDateString ( ) ) ;
177+ expect ( deterministic . toTimeString ( ) ) . toBe ( original . toTimeString ( ) ) ;
178+ expect ( deterministic . toJSON ( ) ) . toBe ( original . toJSON ( ) ) ;
179+ expect ( deterministic . valueOf ( ) ) . toBe ( original . valueOf ( ) ) ;
180+ expect ( deterministic . getTime ( ) ) . toBe ( original . getTime ( ) ) ;
181+ } ) ;
182+
183+ it ( "should handle UTC methods identically" , ( ) => {
184+ const DeterministicDate = createDeterministicDate ( Date , mockGetGenerationState ) ;
185+
186+ const timestamp = 1640995200123 ; // 2022-01-01T00:00:00.123Z
187+ const original = new Date ( timestamp ) ;
188+ const deterministic = new DeterministicDate ( timestamp ) ;
189+
190+ expect ( deterministic . getUTCFullYear ( ) ) . toBe ( original . getUTCFullYear ( ) ) ;
191+ expect ( deterministic . getUTCMonth ( ) ) . toBe ( original . getUTCMonth ( ) ) ;
192+ expect ( deterministic . getUTCDate ( ) ) . toBe ( original . getUTCDate ( ) ) ;
193+ expect ( deterministic . getUTCHours ( ) ) . toBe ( original . getUTCHours ( ) ) ;
194+ expect ( deterministic . getUTCMinutes ( ) ) . toBe ( original . getUTCMinutes ( ) ) ;
195+ expect ( deterministic . getUTCSeconds ( ) ) . toBe ( original . getUTCSeconds ( ) ) ;
196+ expect ( deterministic . getUTCMilliseconds ( ) ) . toBe ( original . getUTCMilliseconds ( ) ) ;
197+ expect ( deterministic . getUTCDay ( ) ) . toBe ( original . getUTCDay ( ) ) ;
198+ } ) ;
199+
200+ it ( "should handle static methods identically" , ( ) => {
201+ const DeterministicDate = createDeterministicDate ( Date , mockGetGenerationState ) ;
202+
203+ const dateString = "2023-01-15T10:30:45.123Z" ;
204+ const year = 2023 ;
205+ const month = 0 ; // January
206+ const day = 15 ;
207+ const hour = 10 ;
208+ const minute = 30 ;
209+ const second = 45 ;
210+ const ms = 123 ;
211+
212+ expect ( DeterministicDate . parse ( dateString ) ) . toBe ( Date . parse ( dateString ) ) ;
213+ expect ( DeterministicDate . UTC ( year , month , day , hour , minute , second , ms ) )
214+ . toBe ( Date . UTC ( year , month , day , hour , minute , second , ms ) ) ;
215+ } ) ;
216+
217+ it ( "should maintain Date compatibility" , ( ) => {
218+ const DeterministicDate = createDeterministicDate ( Date , mockGetGenerationState ) ;
219+
220+ const date = new DeterministicDate ( 2023 , 0 , 1 ) ;
221+
222+ // Should be an instance of Date (important for type compatibility)
223+ expect ( date instanceof Date ) . toBe ( true ) ;
224+
225+ // Should have all expected Date methods
226+ expect ( typeof date . getTime ) . toBe ( "function" ) ;
227+ expect ( typeof date . getFullYear ) . toBe ( "function" ) ;
228+ expect ( typeof date . toISOString ) . toBe ( "function" ) ;
229+ expect ( typeof date . getTimezoneOffset ) . toBe ( "function" ) ;
230+ expect ( typeof date . toLocaleString ) . toBe ( "function" ) ;
231+ } ) ;
232+
233+ it ( "should handle Date modification methods correctly" , ( ) => {
234+ const DeterministicDate = createDeterministicDate ( Date , mockGetGenerationState ) ;
235+
236+ const timestamp = 1640995200000 ; // 2022-01-01
237+ const original = new Date ( timestamp ) ;
238+ const deterministic = new DeterministicDate ( timestamp ) ;
239+
240+ // Test setters
241+ const newTime = 1641081600000 ; // 2022-01-02
242+ original . setTime ( newTime ) ;
243+ deterministic . setTime ( newTime ) ;
244+
245+ expect ( deterministic . getTime ( ) ) . toBe ( original . getTime ( ) ) ;
246+
247+ // Test setFullYear
248+ original . setFullYear ( 2024 ) ;
249+ deterministic . setFullYear ( 2024 ) ;
250+
251+ expect ( deterministic . getFullYear ( ) ) . toBe ( original . getFullYear ( ) ) ;
252+ expect ( deterministic . getTime ( ) ) . toBe ( original . getTime ( ) ) ;
253+ } ) ;
254+
255+ it ( "should have timezone and locale methods available for future patching" , ( ) => {
256+ const DeterministicDate = createDeterministicDate ( Date , mockGetGenerationState ) ;
257+ const date = new DeterministicDate ( 1640995200000 ) ; // 2022-01-01T00:00:00.000Z
258+
259+ // These methods exist but are not yet fully patched for determinism
260+ // They currently still use system timezone/locale settings
261+ expect ( typeof date . getTimezoneOffset ) . toBe ( "function" ) ;
262+ expect ( typeof date . toLocaleString ) . toBe ( "function" ) ;
263+ expect ( typeof date . toLocaleDateString ) . toBe ( "function" ) ;
264+ expect ( typeof date . toLocaleTimeString ) . toBe ( "function" ) ;
265+
266+ // The methods work but results depend on system settings
267+ const timezoneOffset = date . getTimezoneOffset ( ) ;
268+ const localeString = date . toLocaleString ( ) ;
269+ const localeDateString = date . toLocaleDateString ( ) ;
270+ const localeTimeString = date . toLocaleTimeString ( ) ;
271+
272+ expect ( typeof timezoneOffset ) . toBe ( "number" ) ;
273+ expect ( typeof localeString ) . toBe ( "string" ) ;
274+ expect ( typeof localeDateString ) . toBe ( "string" ) ;
275+ expect ( typeof localeTimeString ) . toBe ( "string" ) ;
276+
277+ // Should be consistent when called multiple times
278+ expect ( date . getTimezoneOffset ( ) ) . toBe ( timezoneOffset ) ;
279+ expect ( date . toLocaleString ( ) ) . toBe ( localeString ) ;
280+ expect ( date . toLocaleDateString ( ) ) . toBe ( localeDateString ) ;
281+ expect ( date . toLocaleTimeString ( ) ) . toBe ( localeTimeString ) ;
282+
283+ // TODO: These methods should be patched for full determinism:
284+ // - getTimezoneOffset() should return 0 (UTC)
285+ // - locale methods should use fixed locale (en-US) and UTC timezone
286+ } ) ;
287+ } ) ;
124288 } ) ;
125289
126290 describe ( "createConsole" , ( ) => {
0 commit comments