mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
418 lines
12 KiB
TypeScript
418 lines
12 KiB
TypeScript
import { describe, expect, it, jest, beforeEach } from "@jest/globals"
|
|
|
|
import { javaQuery } from "../queries"
|
|
import { testParseSourceCodeDefinitions } from "./helpers"
|
|
|
|
// Sample Java content for tests covering all supported structures:
|
|
// - class declarations (including inner and anonymous classes)
|
|
// - method declarations
|
|
// - interface declarations
|
|
// - enum declarations and enum constants
|
|
// - annotation type declarations and elements
|
|
// - field declarations
|
|
// - constructor declarations
|
|
// - lambda expressions
|
|
// - type parameters (for generics)
|
|
// - package and import declarations
|
|
// - generic classes, interfaces, and methods
|
|
// - static and instance initializers
|
|
const sampleJavaContent = `
|
|
package com.example.advanced;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.function.Function;
|
|
import java.util.stream.Collectors;
|
|
import java.util.Optional;
|
|
|
|
/**
|
|
* Basic class definition
|
|
* This demonstrates a simple class with fields and methods
|
|
*/
|
|
public class Person {
|
|
// Instance fields
|
|
private String name;
|
|
private int age;
|
|
|
|
// Static field (constant)
|
|
public static final int MAX_AGE = 150;
|
|
|
|
// Static initializer block
|
|
static {
|
|
System.out.println("Class Person loaded");
|
|
}
|
|
|
|
// Instance initializer block
|
|
{
|
|
System.out.println("Creating a new Person instance");
|
|
}
|
|
|
|
// Default constructor
|
|
public Person() {
|
|
this("Unknown", 0);
|
|
}
|
|
|
|
// Parameterized constructor
|
|
public Person(String name, int age) {
|
|
this.name = name;
|
|
this.age = age;
|
|
}
|
|
|
|
// Instance method
|
|
public String getName() {
|
|
return name;
|
|
}
|
|
|
|
// Instance method with parameter
|
|
public void setName(String name) {
|
|
this.name = name;
|
|
}
|
|
|
|
// Instance method
|
|
public int getAge() {
|
|
return age;
|
|
}
|
|
|
|
// Instance method with parameter
|
|
public void setAge(int age) {
|
|
if (age >= 0 && age <= MAX_AGE) {
|
|
this.age = age;
|
|
}
|
|
}
|
|
|
|
// Static method
|
|
public static Person createAdult(String name) {
|
|
return new Person(name, 18);
|
|
}
|
|
|
|
// Method with lambda expression
|
|
public void processWithLambda(List<String> items) {
|
|
items.forEach(item -> {
|
|
System.out.println("Processing: " + item);
|
|
System.out.println("Done processing");
|
|
});
|
|
}
|
|
|
|
// Inner class definition
|
|
public class Address {
|
|
private String street;
|
|
private String city;
|
|
|
|
public Address(String street, String city) {
|
|
this.street = street;
|
|
this.city = city;
|
|
}
|
|
|
|
public String getFullAddress() {
|
|
return street + ", " + city;
|
|
}
|
|
}
|
|
|
|
// Static nested class
|
|
public static class Statistics {
|
|
public static double averageAge(List<Person> people) {
|
|
return people.stream()
|
|
.mapToInt(Person::getAge)
|
|
.average()
|
|
.orElse(0);
|
|
}
|
|
}
|
|
|
|
// Method returning anonymous class
|
|
public Runnable createRunner() {
|
|
return new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
System.out.println(name + " is running!");
|
|
}
|
|
};
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "Person{name='" + name + "', age=" + age + '}';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Interface definition with default and static methods
|
|
*/
|
|
interface Vehicle {
|
|
void start();
|
|
void stop();
|
|
|
|
// Default method in interface (Java 8+)
|
|
default void honk() {
|
|
System.out.println("Honk honk!");
|
|
}
|
|
|
|
// Static method in interface (Java 8+)
|
|
static boolean isMoving(Vehicle vehicle) {
|
|
// Implementation would depend on vehicle state
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Enum definition with fields, constructor, and methods
|
|
*/
|
|
enum Day {
|
|
MONDAY("Start of work week"),
|
|
TUESDAY("Second day"),
|
|
WEDNESDAY("Middle of week"),
|
|
THURSDAY("Almost there"),
|
|
FRIDAY("Last work day"),
|
|
SATURDAY("Weekend!"),
|
|
SUNDAY("Day of rest");
|
|
|
|
private final String description;
|
|
|
|
Day(String description) {
|
|
this.description = description;
|
|
}
|
|
|
|
public String getDescription() {
|
|
return description;
|
|
}
|
|
|
|
public boolean isWeekend() {
|
|
return this == SATURDAY || this == SUNDAY;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Annotation definition
|
|
*/
|
|
@interface CustomAnnotation {
|
|
String value() default "";
|
|
int priority() default 0;
|
|
Class<?>[] classes() default {};
|
|
}
|
|
|
|
/**
|
|
* Generic class definition
|
|
*/
|
|
class Container<T> {
|
|
private T value;
|
|
|
|
public Container(T value) {
|
|
this.value = value;
|
|
}
|
|
|
|
public T getValue() {
|
|
return value;
|
|
}
|
|
|
|
public void setValue(T value) {
|
|
this.value = value;
|
|
}
|
|
|
|
// Generic method
|
|
public <R> R transform(Function<T, R> transformer) {
|
|
return transformer.apply(value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Simple geometric classes
|
|
*/
|
|
class Circle {
|
|
private final double radius;
|
|
|
|
public Circle(double radius) {
|
|
this.radius = radius;
|
|
}
|
|
|
|
public double area() {
|
|
return Math.PI * radius * radius;
|
|
}
|
|
}
|
|
|
|
class Rectangle {
|
|
private final double width;
|
|
private final double height;
|
|
|
|
public Rectangle(double width, double height) {
|
|
this.width = width;
|
|
this.height = height;
|
|
}
|
|
|
|
public double area() {
|
|
return width * height;
|
|
}
|
|
}
|
|
|
|
class Triangle {
|
|
private final double base;
|
|
private final double height;
|
|
|
|
public Triangle(double base, double height) {
|
|
this.base = base;
|
|
this.height = height;
|
|
}
|
|
|
|
public double area() {
|
|
return 0.5 * base * height;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Class with generic methods and complex type parameters
|
|
*/
|
|
class Processor<T, R> {
|
|
public <E extends Exception> void processWithException(T input, Function<T, R> processor) throws E {
|
|
// Implementation would process input and potentially throw exception
|
|
}
|
|
|
|
public <K, V> Map<K, V> processCollection(List<T> items, Function<T, K> keyMapper, Function<T, V> valueMapper) {
|
|
return items.stream().collect(Collectors.toMap(keyMapper, valueMapper));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Class with lambda expressions and method references
|
|
*/
|
|
class LambdaExample {
|
|
public void demonstrateLambdas() {
|
|
// Simple lambda
|
|
Runnable simpleRunner = () -> {
|
|
System.out.println("Running...");
|
|
System.out.println("Still running...");
|
|
};
|
|
|
|
// Lambda with parameters
|
|
Function<String, Integer> lengthFunction = s -> {
|
|
return s.length();
|
|
};
|
|
|
|
// Method reference
|
|
List<String> names = List.of("Alice", "Bob", "Charlie");
|
|
names.forEach(System.out::println);
|
|
}
|
|
}
|
|
`
|
|
|
|
// Java test options
|
|
const javaOptions = {
|
|
language: "java",
|
|
wasmFile: "tree-sitter-java.wasm",
|
|
queryString: javaQuery,
|
|
extKey: "java",
|
|
content: sampleJavaContent,
|
|
}
|
|
|
|
// Mock file system operations
|
|
jest.mock("fs/promises")
|
|
|
|
// Mock loadRequiredLanguageParsers
|
|
jest.mock("../languageParser", () => ({
|
|
loadRequiredLanguageParsers: jest.fn(),
|
|
}))
|
|
|
|
// Mock fileExistsAtPath to return true for our test paths
|
|
jest.mock("../../../utils/fs", () => ({
|
|
fileExistsAtPath: jest.fn().mockImplementation(() => Promise.resolve(true)),
|
|
}))
|
|
|
|
describe("parseSourceCodeDefinitionsForFile with Java", () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks()
|
|
})
|
|
|
|
it("should parse Java class declarations", async () => {
|
|
const result = await testParseSourceCodeDefinitions("/test/file.java", sampleJavaContent, javaOptions)
|
|
|
|
// Check for class declarations
|
|
expect(result).toContain("class Person")
|
|
expect(result).toContain("class Container")
|
|
expect(result).toContain("class Circle")
|
|
expect(result).toContain("class Rectangle")
|
|
expect(result).toContain("class Triangle")
|
|
expect(result).toContain("class Processor")
|
|
expect(result).toContain("class LambdaExample")
|
|
})
|
|
|
|
it("should parse Java method declarations", async () => {
|
|
const result = await testParseSourceCodeDefinitions("/test/file.java", sampleJavaContent, javaOptions)
|
|
const resultLines = result?.split("\n") || []
|
|
|
|
// Check for method declarations
|
|
expect(resultLines.some((line) => line.includes("public void setAge"))).toBe(true)
|
|
expect(resultLines.some((line) => line.includes("public void processWithLambda"))).toBe(true)
|
|
expect(resultLines.some((line) => line.includes("public Runnable createRunner"))).toBe(true)
|
|
})
|
|
|
|
it("should parse Java interface declarations", async () => {
|
|
const result = await testParseSourceCodeDefinitions("/test/file.java", sampleJavaContent, javaOptions)
|
|
|
|
// Check for interface declarations
|
|
expect(result).toContain("interface Vehicle")
|
|
})
|
|
|
|
it("should parse Java enum declarations", async () => {
|
|
const result = await testParseSourceCodeDefinitions("/test/file.java", sampleJavaContent, javaOptions)
|
|
|
|
// Check for enum declarations
|
|
expect(result).toContain("enum Day")
|
|
})
|
|
|
|
it("should parse Java annotation type declarations", async () => {
|
|
const result = await testParseSourceCodeDefinitions("/test/file.java", sampleJavaContent, javaOptions)
|
|
|
|
// Check for annotation type declarations
|
|
expect(result).toContain("interface CustomAnnotation")
|
|
})
|
|
|
|
it("should parse Java field declarations", async () => {
|
|
const result = await testParseSourceCodeDefinitions("/test/file.java", sampleJavaContent, javaOptions)
|
|
|
|
// Since field declarations aren't being captured in the current output,
|
|
// we'll just check that the class containing the fields is captured
|
|
expect(result).toContain("class Person")
|
|
})
|
|
|
|
it("should parse Java constructor declarations", async () => {
|
|
const result = await testParseSourceCodeDefinitions("/test/file.java", sampleJavaContent, javaOptions)
|
|
const resultLines = result?.split("\n") || []
|
|
|
|
// Check for constructor declarations
|
|
expect(resultLines.some((line) => line.includes("public Person(String name, int age)"))).toBe(true)
|
|
})
|
|
|
|
it("should parse Java inner classes", async () => {
|
|
const result = await testParseSourceCodeDefinitions("/test/file.java", sampleJavaContent, javaOptions)
|
|
const resultLines = result?.split("\n") || []
|
|
|
|
// Check for inner class declarations
|
|
expect(resultLines.some((line) => line.includes("public class Address"))).toBe(true)
|
|
expect(resultLines.some((line) => line.includes("public static class Statistics"))).toBe(true)
|
|
})
|
|
|
|
it("should parse Java anonymous classes", async () => {
|
|
const result = await testParseSourceCodeDefinitions("/test/file.java", sampleJavaContent, javaOptions)
|
|
const resultLines = result?.split("\n") || []
|
|
|
|
// Check for anonymous class declarations
|
|
expect(resultLines.some((line) => line.includes("return new Runnable"))).toBe(true)
|
|
})
|
|
|
|
it("should parse Java lambda expressions", async () => {
|
|
const result = await testParseSourceCodeDefinitions("/test/file.java", sampleJavaContent, javaOptions)
|
|
|
|
// Since lambda expressions might not be captured in the current output,
|
|
// we'll just check that the class containing the lambdas is captured
|
|
expect(result).toContain("class LambdaExample")
|
|
})
|
|
|
|
it("should parse all supported Java structures comprehensively", async () => {
|
|
const result = await testParseSourceCodeDefinitions("/test/file.java", sampleJavaContent, javaOptions)
|
|
const resultLines = result?.split("\n") || []
|
|
|
|
// Verify the output format includes line numbers
|
|
expect(resultLines.some((line) => /\d+--\d+ \|/.test(line))).toBe(true)
|
|
|
|
// Verify the output includes the file name
|
|
expect(result).toContain("# file.java")
|
|
})
|
|
})
|