Skip to content

Commit e648737

Browse files
committed
v1.1
1 parent 18984aa commit e648737

File tree

6 files changed

+151
-3
lines changed

6 files changed

+151
-3
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,6 @@ build/
4040
.cursor/
4141

4242
/release-
43-
release-*/
43+
release-*/
44+
.DS_Store
45+
bin/main/META-INF/services/edu.stevens.swe.research.java.cli.analyzer.spi.AnalyzerTask

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,33 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.1.0] - 2024-05-30
9+
10+
### ✨ New Features
11+
- **JUnit Lifecycle Annotation Detection**: Added support for detecting and extracting JUnit lifecycle methods
12+
- `@Before`/`@BeforeEach`: Methods executed before each test
13+
- `@BeforeAll`/`@BeforeClass`: Methods executed once before all tests
14+
- `@After`/`@AfterEach`: Methods executed after each test
15+
- `@AfterAll`/`@AfterClass`: Methods executed once after all tests
16+
- Supports both JUnit 4 and JUnit 5 annotations
17+
- Lifecycle method source code is included in JSON output with field names: `beforeMethods`, `beforeAllMethods`, `afterMethods`, `afterAllMethods`
18+
19+
### 🔧 Technical Enhancements
20+
- Enhanced `TestCaseAnalyzer` with `extractLifecycleMethods()` function
21+
- Added `extractMethodSourceCode()` helper method for consistent source code extraction
22+
- Extended `AnalysisResult` class with new fields for lifecycle methods
23+
24+
### 📋 Updated Output Format
25+
```json
26+
{
27+
"beforeMethods": ["@BeforeEach source code"],
28+
"beforeAllMethods": ["@BeforeAll/@BeforeClass source code"],
29+
"afterMethods": ["@AfterEach source code"],
30+
"afterAllMethods": ["@AfterAll/@AfterClass source code"],
31+
// ... existing fields
32+
}
33+
```
34+
835
## [1.0.1] - 2024-05-30
936

1037
### 🐛 Bug Fixes

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ application {
1717
}
1818

1919
group = 'edu.stevens'
20-
version = '1.0.1'
20+
version = '1.1.0'
2121

2222
dependencies {
2323
// Use JitPack dependency for release builds

src/main/java/edu/stevens/swe/research/java/cli/Main.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import edu.stevens.swe.research.java.cli.analyzer.TaskResult;
1616
import edu.stevens.swe.research.java.cli.analyzer.ResultFormatter;
1717

18-
@Command(name = "analyzer", mixinStandardHelpOptions = true, version = "Analyzer CLI 1.0",
18+
@Command(name = "analyzer", mixinStandardHelpOptions = true, version = "Analyzer CLI 1.1",
1919
description = "Analyzes Java source code based on specified tasks.")
2020
public class Main implements Callable<Integer> {
2121

src/main/java/edu/stevens/swe/research/java/cli/analyzer/core/TestCaseAnalyzer.java

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ public static class AnalysisResult {
3838
public String testClassName = "";
3939
public String testCaseName = "";
4040
public String projectName = "";
41+
public List<String> beforeMethods = new ArrayList<>();
42+
public List<String> beforeAllMethods = new ArrayList<>();
43+
public List<String> afterMethods = new ArrayList<>();
44+
public List<String> afterAllMethods = new ArrayList<>();
4145

4246
// Helper to create the JSON filename
4347
public String getJsonFileName() {
@@ -89,6 +93,9 @@ public AnalysisResult analyzeTestCase(CompilationUnit testCu, MethodDeclaration
8993
}
9094
}
9195

96+
// Extract lifecycle methods (@Before, @BeforeAll, @After, @AfterAll) from the test class
97+
extractLifecycleMethods(testCu, result, originalFileSource);
98+
9299
// Perform DFS-like analysis for parsed_statements_sequence and production_function_implementations
93100
dfsAnalyze(testCu, testMethodDeclaration, 0, result, result.testClassName + "." + result.testCaseName + getParameters(testMethodDeclaration.resolveBinding()), originalFileSource);
94101
return result;
@@ -432,4 +439,74 @@ public String getSourceFilePathForClass(String className, String sourceRootPath)
432439
System.err.println("Warning: Source file not found for class " + className + " under roots: " + potentialSourceRoots);
433440
return null;
434441
}
442+
443+
private void extractLifecycleMethods(CompilationUnit testCu, AnalysisResult result, String originalFileSource) {
444+
// Get all type declarations in the compilation unit
445+
for (Object type : testCu.types()) {
446+
if (type instanceof TypeDeclaration) {
447+
TypeDeclaration typeDecl = (TypeDeclaration) type;
448+
449+
// Get all methods in the type
450+
for (MethodDeclaration method : typeDecl.getMethods()) {
451+
// Check for lifecycle annotations
452+
for (Object modifier : method.modifiers()) {
453+
if (modifier instanceof Annotation) {
454+
Annotation annotation = (Annotation) modifier;
455+
String annotationName = annotation.getTypeName().getFullyQualifiedName();
456+
457+
String methodSourceCode = extractMethodSourceCode(method, originalFileSource);
458+
459+
// Check for @Before annotations (JUnit 4 and 5)
460+
if ("Before".equals(annotationName) ||
461+
"org.junit.Before".equals(annotationName) ||
462+
"org.junit.jupiter.api.BeforeEach".equals(annotationName) ||
463+
"BeforeEach".equals(annotationName)) {
464+
result.beforeMethods.add(methodSourceCode);
465+
System.out.println(" Found @Before method: " + method.getName().getIdentifier());
466+
}
467+
468+
// Check for @BeforeAll annotations (JUnit 5)
469+
else if ("BeforeAll".equals(annotationName) ||
470+
"org.junit.jupiter.api.BeforeAll".equals(annotationName) ||
471+
"BeforeClass".equals(annotationName) ||
472+
"org.junit.BeforeClass".equals(annotationName)) {
473+
result.beforeAllMethods.add(methodSourceCode);
474+
System.out.println(" Found @BeforeAll/@BeforeClass method: " + method.getName().getIdentifier());
475+
}
476+
477+
// Check for @After annotations (JUnit 4 and 5)
478+
else if ("After".equals(annotationName) ||
479+
"org.junit.After".equals(annotationName) ||
480+
"org.junit.jupiter.api.AfterEach".equals(annotationName) ||
481+
"AfterEach".equals(annotationName)) {
482+
result.afterMethods.add(methodSourceCode);
483+
System.out.println(" Found @After method: " + method.getName().getIdentifier());
484+
}
485+
486+
// Check for @AfterAll annotations (JUnit 5)
487+
else if ("AfterAll".equals(annotationName) ||
488+
"org.junit.jupiter.api.AfterAll".equals(annotationName) ||
489+
"AfterClass".equals(annotationName) ||
490+
"org.junit.AfterClass".equals(annotationName)) {
491+
result.afterAllMethods.add(methodSourceCode);
492+
System.out.println(" Found @AfterAll/@AfterClass method: " + method.getName().getIdentifier());
493+
}
494+
}
495+
}
496+
}
497+
}
498+
}
499+
}
500+
501+
private String extractMethodSourceCode(MethodDeclaration method, String originalFileSource) {
502+
int startPos = method.getStartPosition();
503+
int length = method.getLength();
504+
505+
if (startPos >= 0 && length > 0 && (startPos + length) <= originalFileSource.length()) {
506+
return originalFileSource.substring(startPos, startPos + length);
507+
} else {
508+
System.err.println("Warning: Invalid start/length for lifecycle method source code extraction. Method: " + method.getName().getIdentifier());
509+
return "// Error extracting source code for " + method.getName().getIdentifier();
510+
}
511+
}
435512
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package edu.stevens.swe.research.java.cli.analyzer.core;
2+
3+
import org.junit.jupiter.api.BeforeEach;
4+
import org.junit.jupiter.api.AfterEach;
5+
import org.junit.jupiter.api.BeforeAll;
6+
import org.junit.jupiter.api.AfterAll;
7+
import org.junit.jupiter.api.Test;
8+
9+
public class TestCaseAnalyzerTest {
10+
11+
@BeforeAll
12+
static void setUpBeforeClass() {
13+
System.out.println("Setting up before all tests");
14+
}
15+
16+
@BeforeEach
17+
void setUp() {
18+
System.out.println("Setting up before each test");
19+
}
20+
21+
@AfterEach
22+
void tearDown() {
23+
System.out.println("Cleaning up after each test");
24+
}
25+
26+
@AfterAll
27+
static void tearDownAfterClass() {
28+
System.out.println("Cleaning up after all tests");
29+
}
30+
31+
@Test
32+
void testLifecycleMethodDetection() {
33+
// This test method contains lifecycle annotations in the class
34+
System.out.println("Running test method");
35+
}
36+
37+
@Test
38+
void testAnotherMethod() {
39+
// Another test method to verify multiple tests work
40+
System.out.println("Running another test method");
41+
}
42+
}

0 commit comments

Comments
 (0)