Skip to content

Commit c0942b1

Browse files
authored
Merge pull request #1992 from codeflash-ai/fix/typescript-jest-config-require
Fix Jest runtime config failing to load TypeScript base configs
2 parents 755d0f2 + 8d1c5e8 commit c0942b1

2 files changed

Lines changed: 160 additions & 1 deletion

File tree

codeflash/languages/javascript/test_runner.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,11 @@ def _create_runtime_jest_config(base_config_path: Path | None, project_root: Pat
382382
else:
383383
module_dirs_line_no_base = ""
384384

385-
if base_config_path:
385+
# TypeScript configs (.ts) cannot be required from CommonJS modules
386+
# because Node.js cannot parse TypeScript syntax in require().
387+
# When the base config is TypeScript, we create a standalone config
388+
# instead of trying to extend it via require().
389+
if base_config_path and base_config_path.suffix != ".ts":
386390
require_path = f"./{base_config_path.name}"
387391
config_content = f"""// Auto-generated by codeflash - runtime config with test roots
388392
const baseConfig = require('{require_path}');
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
"""Test for TypeScript Jest config require bug.
2+
3+
Regression test for the issue where _create_runtime_jest_config generates
4+
code that tries to require('./jest.config.ts'), which fails because Node.js
5+
CommonJS cannot load TypeScript files directly.
6+
7+
Bug: https://github.com/codeflash-ai/codeflash/issues/XXX
8+
Affects: 18 out of 38 optimization runs in initial testing
9+
"""
10+
11+
import subprocess
12+
import tempfile
13+
from pathlib import Path
14+
15+
import pytest
16+
17+
18+
class TestTypeScriptJestConfigRequire:
19+
"""Test that runtime config correctly handles TypeScript base configs."""
20+
21+
def test_runtime_config_with_typescript_base_config_loads_without_error(self):
22+
"""Runtime config should NOT try to require .ts files directly.
23+
24+
When base_config_path points to jest.config.ts, the generated runtime
25+
config must not use require('./jest.config.ts') because Node.js cannot
26+
parse TypeScript syntax in CommonJS require().
27+
28+
This test creates a jest.config.ts file and verifies that the generated
29+
runtime config can be successfully loaded by Node.js without syntax errors.
30+
"""
31+
from codeflash.languages.javascript.test_runner import _create_runtime_jest_config
32+
33+
with tempfile.TemporaryDirectory() as tmpdir:
34+
project_path = Path(tmpdir).resolve()
35+
36+
# Create a TypeScript Jest config (realistic content with TS syntax)
37+
ts_config_path = project_path / "jest.config.ts"
38+
ts_config_content = """import { Config } from "jest"
39+
40+
const config: Config = {
41+
testEnvironment: 'node',
42+
testMatch: ['**/*.test.ts'],
43+
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
44+
}
45+
46+
export default config
47+
"""
48+
ts_config_path.write_text(ts_config_content, encoding="utf-8")
49+
50+
# Create runtime config with the TS base config
51+
test_dirs = {str(project_path / "test")}
52+
runtime_config_path = _create_runtime_jest_config(
53+
base_config_path=ts_config_path,
54+
project_root=project_path,
55+
test_dirs=test_dirs
56+
)
57+
58+
assert runtime_config_path is not None, "Runtime config should be created"
59+
assert runtime_config_path.exists(), "Runtime config file should exist"
60+
61+
# Read the generated content
62+
runtime_content = runtime_config_path.read_text(encoding="utf-8")
63+
64+
# CRITICAL CHECK: Should NOT contain require('./jest.config.ts')
65+
# This is the bug we're fixing
66+
assert "require('./jest.config.ts')" not in runtime_content, (
67+
"Runtime config should not try to require .ts files directly"
68+
)
69+
70+
# The config should handle TypeScript configs appropriately:
71+
# - Either omit the extension (let Node resolve to .js)
72+
# - Or use a TypeScript loader (ts-node)
73+
# - Or skip requiring TS configs entirely
74+
75+
# Verify the generated config can be loaded by Node.js without errors
76+
test_script = project_path / "test_load_config.js"
77+
test_script_content = f"""
78+
try {{
79+
const config = require('./{runtime_config_path.name}');
80+
console.log('SUCCESS');
81+
process.exit(0);
82+
}} catch (err) {{
83+
console.error('FAILED:', err.message);
84+
process.exit(1);
85+
}}
86+
"""
87+
test_script.write_text(test_script_content, encoding="utf-8")
88+
89+
result = subprocess.run(
90+
["node", str(test_script)],
91+
capture_output=True,
92+
text=True,
93+
cwd=project_path,
94+
timeout=5,
95+
)
96+
97+
assert result.returncode == 0, (
98+
f"Generated runtime config should load without errors.\n"
99+
f"Config path: {runtime_config_path}\n"
100+
f"Config content:\n{runtime_content}\n"
101+
f"Node output:\n{result.stdout}\n{result.stderr}"
102+
)
103+
assert "SUCCESS" in result.stdout
104+
105+
def test_runtime_config_with_js_base_config_works(self):
106+
"""Verify that .js base configs still work correctly (control test)."""
107+
from codeflash.languages.javascript.test_runner import _create_runtime_jest_config
108+
109+
with tempfile.TemporaryDirectory() as tmpdir:
110+
project_path = Path(tmpdir).resolve()
111+
112+
# Create a JavaScript Jest config
113+
js_config_path = project_path / "jest.config.js"
114+
js_config_content = """module.exports = {
115+
testEnvironment: 'node',
116+
testMatch: ['**/*.test.js'],
117+
}
118+
"""
119+
js_config_path.write_text(js_config_content, encoding="utf-8")
120+
121+
# Create runtime config with the JS base config
122+
test_dirs = {str(project_path / "test")}
123+
runtime_config_path = _create_runtime_jest_config(
124+
base_config_path=js_config_path,
125+
project_root=project_path,
126+
test_dirs=test_dirs
127+
)
128+
129+
assert runtime_config_path is not None
130+
assert runtime_config_path.exists()
131+
132+
# Verify it loads without errors
133+
test_script = project_path / "test_load_config.js"
134+
test_script_content = f"""
135+
try {{
136+
const config = require('./{runtime_config_path.name}');
137+
console.log('SUCCESS');
138+
process.exit(0);
139+
}} catch (err) {{
140+
console.error('FAILED:', err.message);
141+
process.exit(1);
142+
}}
143+
"""
144+
test_script.write_text(test_script_content, encoding="utf-8")
145+
146+
result = subprocess.run(
147+
["node", str(test_script)],
148+
capture_output=True,
149+
text=True,
150+
cwd=project_path,
151+
timeout=5,
152+
)
153+
154+
assert result.returncode == 0, f"JS config should load: {result.stderr}"
155+
assert "SUCCESS" in result.stdout

0 commit comments

Comments
 (0)