Skip to content

Commit

Permalink
Merge pull request #1 from Codium-ai/gentest
Browse files Browse the repository at this point in the history
Updated to Create Tests when they are missing
  • Loading branch information
davidparry authored Dec 24, 2024
2 parents d6fff94 + 7a75bfd commit a1bd11d
Show file tree
Hide file tree
Showing 26 changed files with 1,180 additions and 420 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ To include the plugin in your Gradle project, add the following to your `build.g

```groovy
plugins {
id 'ai.qodo.cover.plugin' version '0.0.1'
id 'ai.qodo.cover.plugin' version '0.0.2'
}
```

Expand Down
1 change: 1 addition & 0 deletions cover-agent-plugin/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
/build
.codiumai
/src/test/resources/jacocoTestReport.csv
/.qodo/
19 changes: 19 additions & 0 deletions cover-agent-plugin/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
## [0.0.2] - 2023-10-11

### Added

- **Automatic Test File Generation**: The plugin now automatically generates test files for source files that lack corresponding tests. This feature significantly reduces the manual effort required to bootstrap testing and improves overall test coverage. It intelligently detects the project's testing framework (JUnit, Spock, TestNG) and generates tests accordingly.
- **Improved Source File Matching**: Enhanced the logic for matching source files to existing test files, ensuring more accurate pairings and reducing false positives.
- **Dependency Management**: Introduced a `DependencyHelper` class to streamline the management of project dependencies, making it easier to locate and utilize required JAR files for testing and reporting.
- **New Utility Classes**: Added several utility classes (`ModelUtility`, `FrameworkCheck`, `SourceMatchResult`) to improve code organization, modularity, and reusability. These classes encapsulate specific functionalities, making the codebase cleaner and easier to maintain.
- **Test File Generation Feedback**: The plugin now provides more informative logging and feedback during test file generation, allowing developers to track the process and identify any potential issues.
- **Support for Multiple Test Frameworks**: Added support for detecting and using different test frameworks (JUnit3, JUnit4, JUnit5, TestNG, Spock), ensuring broader compatibility across Java projects.
- **Best Practices Documentation**: Created a comprehensive best practices document (`best_practices.md`) to guide users on effectively utilizing the plugin and adhering to recommended project structure and coding conventions.

### Changed

- **CoverAgent Refactoring**: Refactored the `CoverAgent` class to improve initialization, execution processes, and overall code structure. This refactoring enhances maintainability and sets the stage for future enhancements.
- **Enhanced Logging and Error Handling**: Improved logging and error handling mechanisms throughout the plugin, providing more detailed information for debugging and troubleshooting.
- **Updated Test Project Structure**: Updated the test project structure and resources to enhance testing coverage and demonstrate the plugin's capabilities more effectively.
- **Jacoco Reporting**: Switched to XML reporting for Jacoco, providing more structured and detailed coverage information.
- **Model Prompter Improvements**: Improved the `ModelPrompter` to handle a wider range of responses from the language model and provide more robust test file generation. It now uses a `ModelUtility` class for common operations like file reading and JSON extraction.
126 changes: 126 additions & 0 deletions cover-agent-plugin/best_practices.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@

### Best Practices for the Cover Agent Plugin Project

#### Gradle version 8.5 should only be used nothing older than this.

#### General Project Structure
- **Package Naming**: Use the reverse domain name convention for package names. For example, `ai.qodo.cover.plugin`.
- **Class Naming**: Use PascalCase for class names. For example, `CoverAgentBuilder`, `CoverAgentExecutor`.
- **Interface Naming**: Prefix interface names with an appropriate noun. For example, `CoverAgent`.
- **Development**: All requests to you are in the context for developing a Gradle Plugin and Gradle task. The classes that are implemented and will be run are the following:
```java
org.gradle.api.DefaultTask;
org.gradle.api.Plugin<Project>;
```

#### Gradle Plugin Development
- **Plugin Implementation**: Implement the `Plugin<Project>` interface for creating Gradle plugins. Ensure the `apply` method is overridden to configure the project.
```java
public class CoverAgentPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
// Plugin logic here
}
}
```
- **Task Registration**: Use `project.getTasks().register` to define tasks within the plugin.
```java
project.getTasks().register("coverAgentTask", CoverAgentTask.class, task -> {
task.setGroup("verification");
task.setDescription("Runs the cover agent task attempting to increase code coverage");
});
```

#### Builder Pattern
- **Builder Methods**: Use method chaining in builder classes for setting properties. Return `this` from each method.
```java
public CoverAgentBuilder apiKey(String apiKey) {
this.apiKey = apiKey;
return this;
}
```

#### Logging
- **Logger Usage**: Use Gradle's `Logger` for logging within plugin classes. Obtain the logger from the `Project` instance.
```java
private final Logger logger;

public CoverAgentV2(CoverAgentBuilder builder) {
this.logger = builder.getProject().getLogger();
}

@Override
public void init() {
logger.info("Init the new CoverAgentv2 {}", this);
}
```

#### Exception Handling
- **Custom Exceptions**: Use custom exceptions like `CoverError` for handling specific error scenarios.
```java
public String execute(Project project, String sourceFile, String testFile, ...) throws CoverError {
// Execution logic
if (result.getExitValue() != 0) {
throw new CoverError("An error occurred while executing coverage agent");
}
}
```

#### Testing
- **Testing Framework**: Use Spock for testing. Define tests in Groovy files with the `.groovy` extension.
```groovy
class CoverAgentExecutorSpec extends Specification {
def "Happy path calling the executor"() {
given:
// Setup code
when:
// Execution code
then:
// Assertions
}
}
```
- **Mocking**: Use Spock's mocking capabilities to mock dependencies and verify interactions.

#### Configuration and Environment
- **Environment Variables**: Use environment variables for sensitive data like API keys. Set them in the `ExecSpec` environment.
```java
execSpec.environment(WANDB_API_KEY, wanDBApiKey);
execSpec.environment(OPENAI_API_KEY, apiKey);
```

#### Code Coverage
- **JaCoCo Integration**: Ensure code coverage is measured using JaCoCo. Configure reports to be generated in a specified directory.

#### Documentation
- **Javadoc Comments**: Use Javadoc comments for public classes and methods to provide clear documentation.
```java
/**
* Builds a new instance of CoverAgentV2.
* @return a new CoverAgentV2 instance.
*/
public CoverAgent buildV2() {
return new CoverAgentV2(this);
}
```

#### Code Style
- **Consistent Indentation**: Use 4 spaces for indentation.
- **Line Length**: Keep line length to a maximum of 120 characters for better readability.

#### Version Control
- **Git Usage**: Use Git for version control. Ensure `.gitignore` is configured to exclude build directories and other non-essential files.

#### Dependency Management
- **Gradle Dependencies**: Declare dependencies in the `build.gradle` file. Use specific versions to ensure build consistency.

### Additional Best Practices

#### SOLID Principles
- **Single Responsibility Principle**: Ensure each class has a single responsibility and encapsulates only related functionalities.
- **Open/Closed Principle**: Design classes to be open for extension but closed for modification.
- **Liskov Substitution Principle**: Subtypes should be substitutable for their base types without altering the correctness of the program.
- **Interface Segregation Principle**: Prefer smaller, more specific interfaces over larger, general-purpose ones.
- **Dependency Inversion Principle**: Depend on abstractions, not on concrete implementations.
2 changes: 1 addition & 1 deletion cover-agent-plugin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ plugins {
}

group = 'ai.qodo'
version = '0.0.1'
version = '0.0.2'

repositories {
gradlePluginPortal()
Expand Down
Loading

0 comments on commit a1bd11d

Please sign in to comment.