Skip to content

Commit 0170ccb

Browse files
committed
update assertions
1 parent 198487b commit 0170ccb

7 files changed

Lines changed: 330 additions & 485 deletions

File tree

codeflash/languages/javascript/support.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1661,6 +1661,7 @@ def ensure_runtime_environment(self, project_root: Path) -> bool:
16611661
try:
16621662
result = subprocess.run(
16631663
["npm", "install", "--save-dev", str(local_package_path)],
1664+
check=False,
16641665
cwd=project_root,
16651666
capture_output=True,
16661667
text=True,

experiments/code_replacement/approach_a_jscodeshift.py

Lines changed: 48 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
"""
2-
Approach A: jscodeshift/recast via Node.js subprocess.
1+
"""Approach A: jscodeshift/recast via Node.js subprocess.
32
43
This approach:
54
1. Writes a jscodeshift transform script
@@ -30,6 +29,7 @@
3029
@dataclass
3130
class JsCodeshiftResult:
3231
"""Result from jscodeshift transformation."""
32+
3333
success: bool
3434
output: str
3535
error: Optional[str] = None
@@ -46,12 +46,7 @@ def __init__(self):
4646
def _check_node_available(self) -> bool:
4747
"""Check if Node.js is available."""
4848
try:
49-
result = subprocess.run(
50-
['node', '--version'],
51-
capture_output=True,
52-
text=True,
53-
timeout=5
54-
)
49+
result = subprocess.run(["node", "--version"], check=False, capture_output=True, text=True, timeout=5)
5550
return result.returncode == 0
5651
except (subprocess.SubprocessError, FileNotFoundError):
5752
return False
@@ -60,24 +55,14 @@ def _check_jscodeshift_available(self) -> bool:
6055
"""Check if jscodeshift is available via npx."""
6156
try:
6257
result = subprocess.run(
63-
['npx', 'jscodeshift', '--version'],
64-
capture_output=True,
65-
text=True,
66-
timeout=10
58+
["npx", "jscodeshift", "--version"], check=False, capture_output=True, text=True, timeout=10
6759
)
6860
return result.returncode == 0
6961
except (subprocess.SubprocessError, FileNotFoundError):
7062
return False
7163

72-
def _create_transform_script(
73-
self,
74-
function_name: str,
75-
new_source: str,
76-
start_line: int,
77-
end_line: int,
78-
) -> str:
79-
"""
80-
Create a jscodeshift transform script.
64+
def _create_transform_script(self, function_name: str, new_source: str, start_line: int, end_line: int) -> str:
65+
"""Create a jscodeshift transform script.
8166
8267
Args:
8368
function_name: Name of function to replace
@@ -87,11 +72,12 @@ def _create_transform_script(
8772
8873
Returns:
8974
JavaScript transform script
75+
9076
"""
9177
# Escape the new source for embedding in JS string
9278
escaped_source = json.dumps(new_source)
9379

94-
return f'''
80+
return f"""
9581
// jscodeshift transform to replace function by line number
9682
module.exports = function(fileInfo, api) {{
9783
const j = api.jscodeshift;
@@ -180,23 +166,17 @@ def _create_transform_script(
180166
181167
return root.toSource({{ quote: 'single' }});
182168
}};
183-
'''
184-
185-
def _create_simple_transform_script(
186-
self,
187-
start_line: int,
188-
end_line: int,
189-
new_source: str,
190-
) -> str:
191-
"""
192-
Create a simpler transform script that uses line-based replacement.
169+
"""
170+
171+
def _create_simple_transform_script(self, start_line: int, end_line: int, new_source: str) -> str:
172+
"""Create a simpler transform script that uses line-based replacement.
193173
194174
This fallback approach uses recast to parse, does line-based replacement,
195175
and uses recast to output (preserving formatting).
196176
"""
197177
escaped_source = json.dumps(new_source)
198178

199-
return f'''
179+
return f"""
200180
// Simple line-based replacement using recast for parsing/printing
201181
const recast = require('recast');
202182
@@ -237,18 +217,12 @@ def _create_simple_transform_script(
237217
238218
return [...before, ...adjustedNewLines, ...after].join('\\n');
239219
}};
240-
'''
220+
"""
241221

242222
def replace_function(
243-
self,
244-
source: str,
245-
function_name: str,
246-
new_function: str,
247-
start_line: int,
248-
end_line: int,
223+
self, source: str, function_name: str, new_function: str, start_line: int, end_line: int
249224
) -> JsCodeshiftResult:
250-
"""
251-
Replace a function using jscodeshift.
225+
"""Replace a function using jscodeshift.
252226
253227
Args:
254228
source: Original source code
@@ -259,31 +233,33 @@ def replace_function(
259233
260234
Returns:
261235
JsCodeshiftResult with success status and output
236+
262237
"""
263238
with tempfile.TemporaryDirectory() as tmpdir:
264239
tmpdir_path = Path(tmpdir)
265240

266241
# Write source file
267-
source_file = tmpdir_path / 'source.js'
242+
source_file = tmpdir_path / "source.js"
268243
source_file.write_text(source)
269244

270245
# Write transform script
271-
transform_file = tmpdir_path / 'transform.js'
272-
transform_script = self._create_transform_script(
273-
function_name, new_function, start_line, end_line
274-
)
246+
transform_file = tmpdir_path / "transform.js"
247+
transform_script = self._create_transform_script(function_name, new_function, start_line, end_line)
275248
transform_file.write_text(transform_script)
276249

277250
try:
278251
# Run jscodeshift
279252
result = subprocess.run(
280253
[
281-
'npx', 'jscodeshift',
282-
'-t', str(transform_file),
254+
"npx",
255+
"jscodeshift",
256+
"-t",
257+
str(transform_file),
283258
str(source_file),
284-
'--print', # Print output to stdout instead of modifying file
285-
'--dry', # Don't actually write
259+
"--print", # Print output to stdout instead of modifying file
260+
"--dry", # Don't actually write
286261
],
262+
check=False,
287263
capture_output=True,
288264
text=True,
289265
timeout=30,
@@ -298,40 +274,23 @@ def replace_function(
298274
# Fallback: read the file
299275
output = source_file.read_text()
300276

301-
return JsCodeshiftResult(
302-
success=True,
303-
output=output,
304-
)
305-
else:
306-
return JsCodeshiftResult(
307-
success=False,
308-
output=source, # Return original on failure
309-
error=f"jscodeshift failed with code {result.returncode}",
310-
stderr=result.stderr,
311-
)
312-
313-
except subprocess.TimeoutExpired:
277+
return JsCodeshiftResult(success=True, output=output)
314278
return JsCodeshiftResult(
315279
success=False,
316-
output=source,
317-
error="jscodeshift timed out",
280+
output=source, # Return original on failure
281+
error=f"jscodeshift failed with code {result.returncode}",
282+
stderr=result.stderr,
318283
)
284+
285+
except subprocess.TimeoutExpired:
286+
return JsCodeshiftResult(success=False, output=source, error="jscodeshift timed out")
319287
except Exception as e:
320-
return JsCodeshiftResult(
321-
success=False,
322-
output=source,
323-
error=str(e),
324-
)
288+
return JsCodeshiftResult(success=False, output=source, error=str(e))
325289

326290
def replace_function_simple(
327-
self,
328-
source: str,
329-
start_line: int,
330-
end_line: int,
331-
new_function: str,
291+
self, source: str, start_line: int, end_line: int, new_function: str
332292
) -> JsCodeshiftResult:
333-
"""
334-
Replace a function using simple line-based approach via Node.js.
293+
"""Replace a function using simple line-based approach via Node.js.
335294
336295
This is a fallback that still uses Node.js but with simpler logic.
337296
@@ -343,6 +302,7 @@ def replace_function_simple(
343302
344303
Returns:
345304
JsCodeshiftResult with success status and output
305+
346306
"""
347307
# For simplicity, let's just use the text-based approach
348308
# but run through Node.js for consistency testing
@@ -351,21 +311,13 @@ def replace_function_simple(
351311
replacer = TextBasedReplacer()
352312
result = replacer.replace_function(source, start_line, end_line, new_function)
353313

354-
return JsCodeshiftResult(
355-
success=True,
356-
output=result,
357-
)
314+
return JsCodeshiftResult(success=True, output=result)
358315

359316

360317
def replace_function_jscodeshift(
361-
source: str,
362-
function_name: str,
363-
new_function: str,
364-
start_line: int,
365-
end_line: int,
318+
source: str, function_name: str, new_function: str, start_line: int, end_line: int
366319
) -> str:
367-
"""
368-
Convenience function for jscodeshift replacement.
320+
"""Convenience function for jscodeshift replacement.
369321
370322
Args:
371323
source: Original source code
@@ -376,6 +328,7 @@ def replace_function_jscodeshift(
376328
377329
Returns:
378330
Modified source code (or original if failed)
331+
379332
"""
380333
replacer = JsCodeshiftReplacer()
381334
result = replacer.replace_function(source, function_name, new_function, start_line, end_line)
@@ -384,8 +337,6 @@ def replace_function_jscodeshift(
384337

385338
# Test the implementation
386339
if __name__ == "__main__":
387-
from test_cases import get_test_cases
388-
389340
replacer = JsCodeshiftReplacer()
390341

391342
# Check if jscodeshift is available
@@ -402,21 +353,15 @@ def replace_function_jscodeshift(
402353
print()
403354

404355
# Test with a simple case first
405-
simple_source = '''function add(a, b) {
356+
simple_source = """function add(a, b) {
406357
return a + b;
407358
}
408-
'''
409-
simple_new = '''function add(a, b) {
359+
"""
360+
simple_new = """function add(a, b) {
410361
return (a + b) | 0;
411-
}'''
412-
413-
result = replacer.replace_function(
414-
simple_source,
415-
"add",
416-
simple_new,
417-
start_line=1,
418-
end_line=3,
419-
)
362+
}"""
363+
364+
result = replacer.replace_function(simple_source, "add", simple_new, start_line=1, end_line=3)
420365

421366
print("Simple test result:")
422367
print(f" Success: {result.success}")

0 commit comments

Comments
 (0)