2026-01-29 10:05:44 +00:00
|
|
|
"""Test cases for evaluating JavaScript/TypeScript code replacement strategies.
|
2026-01-15 02:29:20 +00:00
|
|
|
|
|
|
|
|
Each test case includes:
|
|
|
|
|
- original_source: The original JS/TS code
|
|
|
|
|
- function_name: Name of the function to replace
|
|
|
|
|
- start_line, end_line: Line numbers of the function (1-indexed)
|
|
|
|
|
- new_function: The replacement function code
|
|
|
|
|
- expected_result: What the output should look like
|
|
|
|
|
- description: What edge case this tests
|
|
|
|
|
"""
|
|
|
|
|
|
2026-01-29 11:08:46 +00:00
|
|
|
from __future__ import annotations
|
|
|
|
|
|
2026-01-15 02:29:20 +00:00
|
|
|
from dataclasses import dataclass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
|
|
class ReplacementTestCase:
|
|
|
|
|
name: str
|
|
|
|
|
description: str
|
|
|
|
|
original_source: str
|
|
|
|
|
function_name: str
|
|
|
|
|
start_line: int
|
|
|
|
|
end_line: int
|
|
|
|
|
new_function: str
|
|
|
|
|
expected_result: str
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Test cases covering various JavaScript/TypeScript patterns
|
|
|
|
|
TEST_CASES = [
|
|
|
|
|
# ===========================================
|
|
|
|
|
# BASIC CASES
|
|
|
|
|
# ===========================================
|
|
|
|
|
ReplacementTestCase(
|
|
|
|
|
name="simple_function",
|
|
|
|
|
description="Basic named function declaration",
|
2026-01-29 10:05:44 +00:00
|
|
|
original_source="""function add(a, b) {
|
2026-01-15 02:29:20 +00:00
|
|
|
return a + b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function multiply(a, b) {
|
|
|
|
|
return a * b;
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
function_name="add",
|
|
|
|
|
start_line=1,
|
|
|
|
|
end_line=3,
|
2026-01-29 10:05:44 +00:00
|
|
|
new_function="""function add(a, b) {
|
2026-01-15 02:29:20 +00:00
|
|
|
// Optimized version
|
|
|
|
|
return a + b | 0;
|
2026-01-29 10:05:44 +00:00
|
|
|
}""",
|
|
|
|
|
expected_result="""function add(a, b) {
|
2026-01-15 02:29:20 +00:00
|
|
|
// Optimized version
|
|
|
|
|
return a + b | 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function multiply(a, b) {
|
|
|
|
|
return a * b;
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
),
|
|
|
|
|
ReplacementTestCase(
|
|
|
|
|
name="arrow_function_const",
|
|
|
|
|
description="Arrow function assigned to const",
|
2026-01-29 10:05:44 +00:00
|
|
|
original_source="""const square = (x) => {
|
2026-01-15 02:29:20 +00:00
|
|
|
return x * x;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const cube = (x) => x * x * x;
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
function_name="square",
|
|
|
|
|
start_line=1,
|
|
|
|
|
end_line=3,
|
2026-01-29 10:05:44 +00:00
|
|
|
new_function="""const square = (x) => {
|
2026-01-15 02:29:20 +00:00
|
|
|
return x ** 2;
|
2026-01-29 10:05:44 +00:00
|
|
|
};""",
|
|
|
|
|
expected_result="""const square = (x) => {
|
2026-01-15 02:29:20 +00:00
|
|
|
return x ** 2;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const cube = (x) => x * x * x;
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
),
|
|
|
|
|
ReplacementTestCase(
|
|
|
|
|
name="arrow_function_oneliner",
|
|
|
|
|
description="Single-line arrow function",
|
2026-01-29 10:05:44 +00:00
|
|
|
original_source="""const double = x => x * 2;
|
2026-01-15 02:29:20 +00:00
|
|
|
const triple = x => x * 3;
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
function_name="double",
|
|
|
|
|
start_line=1,
|
|
|
|
|
end_line=1,
|
2026-01-29 10:05:44 +00:00
|
|
|
new_function="""const double = x => x << 1;""",
|
|
|
|
|
expected_result="""const double = x => x << 1;
|
2026-01-15 02:29:20 +00:00
|
|
|
const triple = x => x * 3;
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
),
|
|
|
|
|
# ===========================================
|
|
|
|
|
# CLASS METHODS
|
|
|
|
|
# ===========================================
|
|
|
|
|
ReplacementTestCase(
|
|
|
|
|
name="class_method",
|
|
|
|
|
description="Method inside a class",
|
2026-01-29 10:05:44 +00:00
|
|
|
original_source="""class Calculator {
|
2026-01-15 02:29:20 +00:00
|
|
|
constructor(value) {
|
|
|
|
|
this.value = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
add(n) {
|
|
|
|
|
return this.value + n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
multiply(n) {
|
|
|
|
|
return this.value * n;
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
function_name="add",
|
|
|
|
|
start_line=6,
|
|
|
|
|
end_line=8,
|
2026-01-29 10:05:44 +00:00
|
|
|
new_function=""" add(n) {
|
2026-01-15 02:29:20 +00:00
|
|
|
// Optimized addition
|
|
|
|
|
return (this.value + n) | 0;
|
2026-01-29 10:05:44 +00:00
|
|
|
}""",
|
|
|
|
|
expected_result="""class Calculator {
|
2026-01-15 02:29:20 +00:00
|
|
|
constructor(value) {
|
|
|
|
|
this.value = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
add(n) {
|
|
|
|
|
// Optimized addition
|
|
|
|
|
return (this.value + n) | 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
multiply(n) {
|
|
|
|
|
return this.value * n;
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
),
|
|
|
|
|
ReplacementTestCase(
|
|
|
|
|
name="static_method",
|
|
|
|
|
description="Static method in class",
|
2026-01-29 10:05:44 +00:00
|
|
|
original_source="""class MathUtils {
|
2026-01-15 02:29:20 +00:00
|
|
|
static fibonacci(n) {
|
|
|
|
|
if (n <= 1) return n;
|
|
|
|
|
return MathUtils.fibonacci(n - 1) + MathUtils.fibonacci(n - 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static factorial(n) {
|
|
|
|
|
if (n <= 1) return 1;
|
|
|
|
|
return n * MathUtils.factorial(n - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
function_name="fibonacci",
|
|
|
|
|
start_line=2,
|
|
|
|
|
end_line=5,
|
2026-01-29 10:05:44 +00:00
|
|
|
new_function=""" static fibonacci(n) {
|
2026-01-15 02:29:20 +00:00
|
|
|
// Memoized version
|
|
|
|
|
const memo = [0, 1];
|
|
|
|
|
for (let i = 2; i <= n; i++) {
|
|
|
|
|
memo[i] = memo[i-1] + memo[i-2];
|
|
|
|
|
}
|
|
|
|
|
return memo[n];
|
2026-01-29 10:05:44 +00:00
|
|
|
}""",
|
|
|
|
|
expected_result="""class MathUtils {
|
2026-01-15 02:29:20 +00:00
|
|
|
static fibonacci(n) {
|
|
|
|
|
// Memoized version
|
|
|
|
|
const memo = [0, 1];
|
|
|
|
|
for (let i = 2; i <= n; i++) {
|
|
|
|
|
memo[i] = memo[i-1] + memo[i-2];
|
|
|
|
|
}
|
|
|
|
|
return memo[n];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static factorial(n) {
|
|
|
|
|
if (n <= 1) return 1;
|
|
|
|
|
return n * MathUtils.factorial(n - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
),
|
|
|
|
|
# ===========================================
|
|
|
|
|
# ASYNC FUNCTIONS
|
|
|
|
|
# ===========================================
|
|
|
|
|
ReplacementTestCase(
|
|
|
|
|
name="async_function",
|
|
|
|
|
description="Async function declaration",
|
2026-01-29 10:05:44 +00:00
|
|
|
original_source="""async function fetchData(url) {
|
2026-01-15 02:29:20 +00:00
|
|
|
const response = await fetch(url);
|
|
|
|
|
return response.json();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function postData(url, data) {
|
|
|
|
|
const response = await fetch(url, { method: 'POST', body: JSON.stringify(data) });
|
|
|
|
|
return response.json();
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
function_name="fetchData",
|
|
|
|
|
start_line=1,
|
|
|
|
|
end_line=4,
|
2026-01-29 10:05:44 +00:00
|
|
|
new_function="""async function fetchData(url) {
|
2026-01-15 02:29:20 +00:00
|
|
|
// With caching
|
|
|
|
|
const cached = cache.get(url);
|
|
|
|
|
if (cached) return cached;
|
|
|
|
|
const response = await fetch(url);
|
|
|
|
|
const data = await response.json();
|
|
|
|
|
cache.set(url, data);
|
|
|
|
|
return data;
|
2026-01-29 10:05:44 +00:00
|
|
|
}""",
|
|
|
|
|
expected_result="""async function fetchData(url) {
|
2026-01-15 02:29:20 +00:00
|
|
|
// With caching
|
|
|
|
|
const cached = cache.get(url);
|
|
|
|
|
if (cached) return cached;
|
|
|
|
|
const response = await fetch(url);
|
|
|
|
|
const data = await response.json();
|
|
|
|
|
cache.set(url, data);
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function postData(url, data) {
|
|
|
|
|
const response = await fetch(url, { method: 'POST', body: JSON.stringify(data) });
|
|
|
|
|
return response.json();
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
),
|
|
|
|
|
# ===========================================
|
|
|
|
|
# EDGE CASES: COMMENTS & WHITESPACE
|
|
|
|
|
# ===========================================
|
|
|
|
|
ReplacementTestCase(
|
|
|
|
|
name="function_with_jsdoc",
|
|
|
|
|
description="Function with JSDoc comment above it",
|
2026-01-29 10:05:44 +00:00
|
|
|
original_source="""/**
|
2026-01-15 02:29:20 +00:00
|
|
|
* Calculates the sum of two numbers.
|
|
|
|
|
* @param {number} a - First number
|
|
|
|
|
* @param {number} b - Second number
|
|
|
|
|
* @returns {number} The sum
|
|
|
|
|
*/
|
|
|
|
|
function sum(a, b) {
|
|
|
|
|
return a + b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function diff(a, b) {
|
|
|
|
|
return a - b;
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
function_name="sum",
|
|
|
|
|
start_line=7, # Function starts after JSDoc
|
|
|
|
|
end_line=9,
|
2026-01-29 10:05:44 +00:00
|
|
|
new_function="""function sum(a, b) {
|
2026-01-15 02:29:20 +00:00
|
|
|
return (a + b) | 0;
|
2026-01-29 10:05:44 +00:00
|
|
|
}""",
|
|
|
|
|
expected_result="""/**
|
2026-01-15 02:29:20 +00:00
|
|
|
* Calculates the sum of two numbers.
|
|
|
|
|
* @param {number} a - First number
|
|
|
|
|
* @param {number} b - Second number
|
|
|
|
|
* @returns {number} The sum
|
|
|
|
|
*/
|
|
|
|
|
function sum(a, b) {
|
|
|
|
|
return (a + b) | 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function diff(a, b) {
|
|
|
|
|
return a - b;
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
),
|
|
|
|
|
ReplacementTestCase(
|
|
|
|
|
name="inline_comments",
|
|
|
|
|
description="Function with inline comments",
|
2026-01-29 10:05:44 +00:00
|
|
|
original_source="""function process(data) {
|
2026-01-15 02:29:20 +00:00
|
|
|
// Validate input
|
|
|
|
|
if (!data) return null;
|
|
|
|
|
|
|
|
|
|
// Transform data
|
|
|
|
|
const result = data.map(x => x * 2); // double each value
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
function_name="process",
|
|
|
|
|
start_line=1,
|
|
|
|
|
end_line=9,
|
2026-01-29 10:05:44 +00:00
|
|
|
new_function="""function process(data) {
|
2026-01-15 02:29:20 +00:00
|
|
|
if (!data) return null;
|
|
|
|
|
return data.map(x => x << 1);
|
2026-01-29 10:05:44 +00:00
|
|
|
}""",
|
|
|
|
|
expected_result="""function process(data) {
|
2026-01-15 02:29:20 +00:00
|
|
|
if (!data) return null;
|
|
|
|
|
return data.map(x => x << 1);
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
),
|
|
|
|
|
# ===========================================
|
|
|
|
|
# NESTED FUNCTIONS
|
|
|
|
|
# ===========================================
|
|
|
|
|
ReplacementTestCase(
|
|
|
|
|
name="function_with_nested",
|
|
|
|
|
description="Function containing nested functions",
|
2026-01-29 10:05:44 +00:00
|
|
|
original_source="""function outer(x) {
|
2026-01-15 02:29:20 +00:00
|
|
|
function inner(y) {
|
|
|
|
|
return y * 2;
|
|
|
|
|
}
|
|
|
|
|
return inner(x) + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function other() {
|
|
|
|
|
return 42;
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
function_name="outer",
|
|
|
|
|
start_line=1,
|
|
|
|
|
end_line=6,
|
2026-01-29 10:05:44 +00:00
|
|
|
new_function="""function outer(x) {
|
2026-01-15 02:29:20 +00:00
|
|
|
const inner = y => y << 1;
|
|
|
|
|
return inner(x) + 1;
|
2026-01-29 10:05:44 +00:00
|
|
|
}""",
|
|
|
|
|
expected_result="""function outer(x) {
|
2026-01-15 02:29:20 +00:00
|
|
|
const inner = y => y << 1;
|
|
|
|
|
return inner(x) + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function other() {
|
|
|
|
|
return 42;
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
),
|
|
|
|
|
# ===========================================
|
|
|
|
|
# TYPESCRIPT SPECIFIC
|
|
|
|
|
# ===========================================
|
|
|
|
|
ReplacementTestCase(
|
|
|
|
|
name="typescript_typed_function",
|
|
|
|
|
description="TypeScript function with type annotations",
|
2026-01-29 10:05:44 +00:00
|
|
|
original_source="""function greet(name: string): string {
|
2026-01-15 02:29:20 +00:00
|
|
|
return `Hello, ${name}!`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function farewell(name: string): string {
|
|
|
|
|
return `Goodbye, ${name}!`;
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
function_name="greet",
|
|
|
|
|
start_line=1,
|
|
|
|
|
end_line=3,
|
2026-01-29 10:05:44 +00:00
|
|
|
new_function="""function greet(name: string): string {
|
2026-01-15 02:29:20 +00:00
|
|
|
return 'Hello, ' + name + '!';
|
2026-01-29 10:05:44 +00:00
|
|
|
}""",
|
|
|
|
|
expected_result="""function greet(name: string): string {
|
2026-01-15 02:29:20 +00:00
|
|
|
return 'Hello, ' + name + '!';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function farewell(name: string): string {
|
|
|
|
|
return `Goodbye, ${name}!`;
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
),
|
|
|
|
|
ReplacementTestCase(
|
|
|
|
|
name="typescript_generic",
|
|
|
|
|
description="TypeScript generic function",
|
2026-01-29 10:05:44 +00:00
|
|
|
original_source="""function identity<T>(arg: T): T {
|
2026-01-15 02:29:20 +00:00
|
|
|
return arg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function first<T>(arr: T[]): T | undefined {
|
|
|
|
|
return arr[0];
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
function_name="identity",
|
|
|
|
|
start_line=1,
|
|
|
|
|
end_line=3,
|
2026-01-29 10:05:44 +00:00
|
|
|
new_function="""function identity<T>(arg: T): T {
|
2026-01-15 02:29:20 +00:00
|
|
|
// Direct return
|
|
|
|
|
return arg;
|
2026-01-29 10:05:44 +00:00
|
|
|
}""",
|
|
|
|
|
expected_result="""function identity<T>(arg: T): T {
|
2026-01-15 02:29:20 +00:00
|
|
|
// Direct return
|
|
|
|
|
return arg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function first<T>(arr: T[]): T | undefined {
|
|
|
|
|
return arr[0];
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
),
|
|
|
|
|
ReplacementTestCase(
|
|
|
|
|
name="typescript_interface_method",
|
|
|
|
|
description="TypeScript class implementing interface",
|
2026-01-29 10:05:44 +00:00
|
|
|
original_source="""interface Processor {
|
2026-01-15 02:29:20 +00:00
|
|
|
process(data: number[]): number[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class ArrayProcessor implements Processor {
|
|
|
|
|
process(data: number[]): number[] {
|
|
|
|
|
return data.map(x => x * 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
transform(data: number[]): number[] {
|
|
|
|
|
return data.filter(x => x > 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
function_name="process",
|
|
|
|
|
start_line=6,
|
|
|
|
|
end_line=8,
|
2026-01-29 10:05:44 +00:00
|
|
|
new_function=""" process(data: number[]): number[] {
|
2026-01-15 02:29:20 +00:00
|
|
|
const result = new Array(data.length);
|
|
|
|
|
for (let i = 0; i < data.length; i++) {
|
|
|
|
|
result[i] = data[i] << 1;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
2026-01-29 10:05:44 +00:00
|
|
|
}""",
|
|
|
|
|
expected_result="""interface Processor {
|
2026-01-15 02:29:20 +00:00
|
|
|
process(data: number[]): number[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class ArrayProcessor implements Processor {
|
|
|
|
|
process(data: number[]): number[] {
|
|
|
|
|
const result = new Array(data.length);
|
|
|
|
|
for (let i = 0; i < data.length; i++) {
|
|
|
|
|
result[i] = data[i] << 1;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
transform(data: number[]): number[] {
|
|
|
|
|
return data.filter(x => x > 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
),
|
|
|
|
|
# ===========================================
|
|
|
|
|
# EXPORT PATTERNS
|
|
|
|
|
# ===========================================
|
|
|
|
|
ReplacementTestCase(
|
|
|
|
|
name="exported_function",
|
|
|
|
|
description="Exported function declaration",
|
2026-01-29 10:05:44 +00:00
|
|
|
original_source="""export function calculate(a, b) {
|
2026-01-15 02:29:20 +00:00
|
|
|
return a + b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function subtract(a, b) {
|
|
|
|
|
return a - b;
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
function_name="calculate",
|
|
|
|
|
start_line=1,
|
|
|
|
|
end_line=3,
|
2026-01-29 10:05:44 +00:00
|
|
|
new_function="""export function calculate(a, b) {
|
2026-01-15 02:29:20 +00:00
|
|
|
return (a + b) | 0;
|
2026-01-29 10:05:44 +00:00
|
|
|
}""",
|
|
|
|
|
expected_result="""export function calculate(a, b) {
|
2026-01-15 02:29:20 +00:00
|
|
|
return (a + b) | 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function subtract(a, b) {
|
|
|
|
|
return a - b;
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
),
|
|
|
|
|
ReplacementTestCase(
|
|
|
|
|
name="default_export",
|
|
|
|
|
description="Default exported function",
|
2026-01-29 10:05:44 +00:00
|
|
|
original_source="""export default function main(args) {
|
2026-01-15 02:29:20 +00:00
|
|
|
return args.reduce((a, b) => a + b, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function helper(x) {
|
|
|
|
|
return x * 2;
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
function_name="main",
|
|
|
|
|
start_line=1,
|
|
|
|
|
end_line=3,
|
2026-01-29 10:05:44 +00:00
|
|
|
new_function="""export default function main(args) {
|
2026-01-15 02:29:20 +00:00
|
|
|
let sum = 0;
|
|
|
|
|
for (const arg of args) sum += arg;
|
|
|
|
|
return sum;
|
2026-01-29 10:05:44 +00:00
|
|
|
}""",
|
|
|
|
|
expected_result="""export default function main(args) {
|
2026-01-15 02:29:20 +00:00
|
|
|
let sum = 0;
|
|
|
|
|
for (const arg of args) sum += arg;
|
|
|
|
|
return sum;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function helper(x) {
|
|
|
|
|
return x * 2;
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
),
|
|
|
|
|
# ===========================================
|
|
|
|
|
# DECORATORS (TypeScript/Experimental JS)
|
|
|
|
|
# ===========================================
|
|
|
|
|
ReplacementTestCase(
|
|
|
|
|
name="decorated_method",
|
|
|
|
|
description="Method with decorators",
|
2026-01-29 10:05:44 +00:00
|
|
|
original_source="""class Service {
|
2026-01-15 02:29:20 +00:00
|
|
|
@log
|
|
|
|
|
@memoize
|
|
|
|
|
compute(x: number): number {
|
|
|
|
|
return x * x;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
other(): void {
|
|
|
|
|
console.log('other');
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
function_name="compute",
|
|
|
|
|
start_line=4, # Method starts after decorators
|
|
|
|
|
end_line=6,
|
2026-01-29 10:05:44 +00:00
|
|
|
new_function=""" compute(x: number): number {
|
2026-01-15 02:29:20 +00:00
|
|
|
return x ** 2;
|
2026-01-29 10:05:44 +00:00
|
|
|
}""",
|
|
|
|
|
expected_result="""class Service {
|
2026-01-15 02:29:20 +00:00
|
|
|
@log
|
|
|
|
|
@memoize
|
|
|
|
|
compute(x: number): number {
|
|
|
|
|
return x ** 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
other(): void {
|
|
|
|
|
console.log('other');
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
),
|
|
|
|
|
# ===========================================
|
|
|
|
|
# FIRST/LAST FUNCTION EDGE CASES
|
|
|
|
|
# ===========================================
|
|
|
|
|
ReplacementTestCase(
|
|
|
|
|
name="first_function_in_file",
|
|
|
|
|
description="Replacing the very first function in file",
|
2026-01-29 10:05:44 +00:00
|
|
|
original_source="""function first() {
|
2026-01-15 02:29:20 +00:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function second() {
|
|
|
|
|
return 2;
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
function_name="first",
|
|
|
|
|
start_line=1,
|
|
|
|
|
end_line=3,
|
2026-01-29 10:05:44 +00:00
|
|
|
new_function="""function first() {
|
2026-01-15 02:29:20 +00:00
|
|
|
return 1 | 0;
|
2026-01-29 10:05:44 +00:00
|
|
|
}""",
|
|
|
|
|
expected_result="""function first() {
|
2026-01-15 02:29:20 +00:00
|
|
|
return 1 | 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function second() {
|
|
|
|
|
return 2;
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
),
|
|
|
|
|
ReplacementTestCase(
|
|
|
|
|
name="last_function_in_file",
|
|
|
|
|
description="Replacing the last function in file",
|
2026-01-29 10:05:44 +00:00
|
|
|
original_source="""function first() {
|
2026-01-15 02:29:20 +00:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function last() {
|
|
|
|
|
return 999;
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
function_name="last",
|
|
|
|
|
start_line=5,
|
|
|
|
|
end_line=7,
|
2026-01-29 10:05:44 +00:00
|
|
|
new_function="""function last() {
|
2026-01-15 02:29:20 +00:00
|
|
|
return 1000;
|
2026-01-29 10:05:44 +00:00
|
|
|
}""",
|
|
|
|
|
expected_result="""function first() {
|
2026-01-15 02:29:20 +00:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function last() {
|
|
|
|
|
return 1000;
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
),
|
|
|
|
|
ReplacementTestCase(
|
|
|
|
|
name="only_function_in_file",
|
|
|
|
|
description="Replacing the only function in file",
|
2026-01-29 10:05:44 +00:00
|
|
|
original_source="""function only() {
|
2026-01-15 02:29:20 +00:00
|
|
|
return 42;
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
function_name="only",
|
|
|
|
|
start_line=1,
|
|
|
|
|
end_line=3,
|
2026-01-29 10:05:44 +00:00
|
|
|
new_function="""function only() {
|
2026-01-15 02:29:20 +00:00
|
|
|
return 42 | 0;
|
2026-01-29 10:05:44 +00:00
|
|
|
}""",
|
|
|
|
|
expected_result="""function only() {
|
2026-01-15 02:29:20 +00:00
|
|
|
return 42 | 0;
|
|
|
|
|
}
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
),
|
|
|
|
|
# ===========================================
|
|
|
|
|
# INDENTATION PRESERVATION
|
|
|
|
|
# ===========================================
|
|
|
|
|
ReplacementTestCase(
|
|
|
|
|
name="deeply_nested_method",
|
|
|
|
|
description="Method with deep indentation",
|
2026-01-29 10:05:44 +00:00
|
|
|
original_source="""const module = {
|
2026-01-15 02:29:20 +00:00
|
|
|
submodule: {
|
|
|
|
|
handler: {
|
|
|
|
|
process(data) {
|
|
|
|
|
return data.map(x => x * 2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
function_name="process",
|
|
|
|
|
start_line=4,
|
|
|
|
|
end_line=6,
|
2026-01-29 10:05:44 +00:00
|
|
|
new_function=""" process(data) {
|
2026-01-15 02:29:20 +00:00
|
|
|
return data.map(x => x << 1);
|
2026-01-29 10:05:44 +00:00
|
|
|
}""",
|
|
|
|
|
expected_result="""const module = {
|
2026-01-15 02:29:20 +00:00
|
|
|
submodule: {
|
|
|
|
|
handler: {
|
|
|
|
|
process(data) {
|
|
|
|
|
return data.map(x => x << 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
2026-01-29 10:05:44 +00:00
|
|
|
""",
|
2026-01-15 02:29:20 +00:00
|
|
|
),
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
2026-01-29 13:56:50 +00:00
|
|
|
def get_test_cases() -> list[ReplacementTestCase]:
|
2026-01-15 02:29:20 +00:00
|
|
|
"""Return all test cases."""
|
|
|
|
|
return TEST_CASES
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_test_case_by_name(name: str) -> ReplacementTestCase | None:
|
|
|
|
|
"""Get a specific test case by name."""
|
|
|
|
|
for tc in TEST_CASES:
|
|
|
|
|
if tc.name == name:
|
|
|
|
|
return tc
|
|
|
|
|
return None
|