@@ -49,6 +49,31 @@ const LOOP_INDEX = parseInt(process.env.CODEFLASH_LOOP_INDEX || '1', 10);
4949const TEST_ITERATION = process . env . CODEFLASH_TEST_ITERATION || '0' ;
5050const TEST_MODULE = process . env . CODEFLASH_TEST_MODULE || '' ;
5151
52+ // Random seed for reproducible test runs
53+ // Both original and optimized runs use the same seed to get identical "random" values
54+ const RANDOM_SEED = parseInt ( process . env . CODEFLASH_RANDOM_SEED || '0' , 10 ) ;
55+
56+ /**
57+ * Seeded random number generator using mulberry32 algorithm.
58+ * This provides reproducible "random" numbers given a fixed seed.
59+ */
60+ function createSeededRandom ( seed ) {
61+ let state = seed ;
62+ return function ( ) {
63+ state |= 0 ;
64+ state = state + 0x6D2B79F5 | 0 ;
65+ let t = Math . imul ( state ^ state >>> 15 , 1 | state ) ;
66+ t = t + Math . imul ( t ^ t >>> 7 , 61 | t ) ^ t ;
67+ return ( ( t ^ t >>> 14 ) >>> 0 ) / 4294967296 ;
68+ } ;
69+ }
70+
71+ // Override Math.random with seeded version if seed is provided
72+ if ( RANDOM_SEED !== 0 ) {
73+ const seededRandom = createSeededRandom ( RANDOM_SEED ) ;
74+ Math . random = seededRandom ;
75+ }
76+
5277// Looping configuration for performance benchmarking
5378const MIN_LOOPS = parseInt ( process . env . CODEFLASH_MIN_LOOPS || '5' , 10 ) ;
5479const MAX_LOOPS = parseInt ( process . env . CODEFLASH_MAX_LOOPS || '100000' , 10 ) ;
@@ -301,12 +326,10 @@ function capture(funcName, lineId, fn, ...args) {
301326 // Get relative path from cwd and convert to module-style path
302327 const path = require ( 'path' ) ;
303328 const relativePath = path . relative ( process . cwd ( ) , currentTestPath ) ;
304- // Convert to module-style path (e.g., "tests/test_foo.test.js" -> "test_foo.test")
305- // Strip the leading "tests/" directory to match what Jest's junit XML produces
306- // and what module_name_from_file_path(test_file, tests_root) generates
329+ // Convert to Python module-style path (e.g., "tests/test_foo.test.js" -> "tests.test_foo.test")
330+ // This matches what Jest's junit XML produces
307331 testModulePath = relativePath
308332 . replace ( / \\ / g, '/' ) // Handle Windows paths
309- . replace ( / ^ t e s t s \/ / , '' ) // Strip leading "tests/" directory
310333 . replace ( / \. j s $ / , '' ) // Remove .js extension
311334 . replace ( / \. t e s t $ / , '.test' ) // Keep .test suffix
312335 . replace ( / \/ / g, '.' ) ; // Convert path separators to dots
@@ -406,11 +429,9 @@ function capturePerf(funcName, lineId, fn, ...args) {
406429 // Get relative path from cwd and convert to module-style path
407430 const path = require ( 'path' ) ;
408431 const relativePath = path . relative ( process . cwd ( ) , currentTestPath ) ;
409- // Convert to module-style path (e.g., "tests/test_foo.test.js" -> "test_foo.test")
410- // Strip leading "tests/" to match XML module path format
432+ // Convert to Python module-style path (e.g., "tests/test_foo.test.js" -> "tests.test_foo.test")
411433 testModulePath = relativePath
412434 . replace ( / \\ / g, '/' )
413- . replace ( / ^ t e s t s \/ / , '' ) // Strip leading "tests/" directory
414435 . replace ( / \. j s $ / , '' )
415436 . replace ( / \. t e s t $ / , '.test' )
416437 . replace ( / \/ / g, '.' ) ;
@@ -548,11 +569,9 @@ function capturePerfLooped(funcName, lineId, fn, ...args) {
548569 // Get relative path from cwd and convert to module-style path
549570 const path = require ( 'path' ) ;
550571 const relativePath = path . relative ( process . cwd ( ) , currentTestPath ) ;
551- // Convert to module-style path (e.g., "tests/test_foo.test.js" -> "test_foo.test")
552- // Strip leading "tests/" to match XML module path format
572+ // Convert to Python module-style path (e.g., "tests/test_foo.test.js" -> "tests.test_foo.test")
553573 testModulePath = relativePath
554574 . replace ( / \\ / g, '/' )
555- . replace ( / ^ t e s t s \/ / , '' ) // Strip leading "tests/" directory
556575 . replace ( / \. j s $ / , '' )
557576 . replace ( / \. t e s t $ / , '.test' )
558577 . replace ( / \/ / g, '.' ) ;
@@ -638,8 +657,8 @@ function capturePerfLooped(funcName, lineId, fn, ...args) {
638657 break ;
639658 }
640659
641- // Stop if we've reached min loops AND exceeded a reasonable portion of time
642- if ( loopCount >= MIN_LOOPS && elapsedMs >= TARGET_DURATION_MS * 0.8 ) {
660+ // Stop if we've reached min loops AND exceeded time limit
661+ if ( loopCount >= MIN_LOOPS && elapsedMs >= TARGET_DURATION_MS ) {
643662 break ;
644663 }
645664
0 commit comments