use std::path::{Path, PathBuf};
use std::fs;
use std::process::Command;
use tempfile::TempDir;
use jbuild::interactive;
#[path = "support/config.rs"]
pub mod config;
pub use config::*;
pub use performance_utils::*;
pub use project_utils::*;
pub use assertions::*;
pub fn create_test_dir() -> TempDir {
TempDir::new().expect("Failed to create test directory")
}
pub fn create_maven_project(base_dir: &Path) {
let src_main_java = base_dir.join("src").join("main").join("java");
fs::create_dir_all(&src_main_java).expect("Failed to create Maven directory structure");
let pom_content = r#"<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>test-project</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>"#;
fs::write(base_dir.join("pom.xml"), pom_content)
.expect("Failed to write pom.xml");
let java_content = r#"
package com.test;
/**
* Test class for Maven project
*/
public class TestApp {
public static void main(String[] args) {
System.out.println("Hello from jbuild test!");
}
public String getMessage() {
return "Test message";
}
}
"#;
fs::write(src_main_java.join("TestApp.java"), java_content)
.expect("Failed to write Java file");
}
pub fn create_gradle_project(base_dir: &Path) {
let src_main_java = base_dir.join("src").join("main").join("java");
fs::create_dir_all(&src_main_java).expect("Failed to create Gradle directory structure");
let gradle_content = r#"
plugins {
java
application
}
group = 'com.test'
version = '1.0.0'
java {
sourceCompatibility = '11'
targetCompatibility = '11'
}
application {
mainClass = 'com.test.TestApp'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.slf4j:slf4j-api:1.7.32'
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.2'
}
test {
useJUnitPlatform()
}
"#;
fs::write(base_dir.join("build.gradle"), gradle_content)
.expect("Failed to write build.gradle");
let java_content = r#"
package com.test;
/**
* Test class for Gradle project
*/
public class TestApp {
public static void main(String[] args) {
System.out.println("Hello from jbuild test!");
}
public String getMessage() {
return "Test message";
}
}
"#;
fs::write(src_main_java.join("TestApp.java"), java_content)
.expect("Failed to write Java file");
}
pub fn create_minimal_project(base_dir: &Path) {
let src_main_java = base_dir.join("src").join("main").join("java");
fs::create_dir_all(&src_main_java).expect("Failed to create minimal directory structure");
let pom_content = r#"<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>minimal-project</artifactId>
<version>1.0.0</version>
</project>"#;
fs::write(base_dir.join("pom.xml"), pom_content)
.expect("Failed to write minimal pom.xml");
let java_content = "public class Test {}";
fs::write(src_main_java.join("Test.java"), java_content)
.expect("Failed to write minimal Java file");
}
pub fn run_jbuild_command(args: &[&str], current_dir: Option<&Path>) -> std::process::Output {
let mut cmd = Command::new("cargo");
cmd.args(&["run", "--bin", "jbuild"]);
cmd.args(args);
if let Some(dir) = current_dir {
cmd.current_dir(dir);
}
cmd.output().expect("Failed to execute jbuild command")
}
pub fn command_succeeds(args: &[&str], current_dir: Option<&Path>) -> bool {
let output = run_jbuild_command(args, current_dir);
output.status.success()
}
pub fn command_contains(args: &[&str], current_dir: Option<&Path>, expected_text: &str) -> bool {
let output = run_jbuild_command(args, current_dir);
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
stdout.contains(expected_text) || stderr.contains(expected_text)
}
pub fn create_test_metrics() -> interactive::BuildMetrics {
let mut metrics = interactive::BuildMetrics::new();
metrics.processed_dependencies = 10;
metrics.total_dependencies = 100;
metrics.memory_usage_mb = 512;
metrics.cpu_usage_percent = 25.0;
metrics.compilation_files = 5;
metrics.test_files = 2;
metrics
}
pub fn create_test_profile_report() -> interactive::ProfileReport {
use std::time::Duration;
use chrono::Local;
interactive::ProfileReport {
build_time: Duration::from_secs(5),
success: true,
error_count: 1,
phases: vec![
("Dependencies".to_string(), Duration::from_millis(1000)),
("Compilation".to_string(), Duration::from_millis(3000)),
("Testing".to_string(), Duration::from_millis(1000)),
],
timestamp: Local::now(),
}
}
#[macro_export]
macro_rules! assert_ok {
($result:expr) => {
match $result {
Ok(_) => {},
Err(e) => panic!("Expected Ok, got Err: {}", e),
}
};
}
#[macro_export]
macro_rules! assert_err {
($result:expr) => {
match $result {
Err(_) => {},
Ok(_) => panic!("Expected Err, got Ok"),
}
};
}
#[macro_export]
macro_rules! assert_in_range {
($value:expr, $min:expr, $max:expr) => {
assert!($value >= $min && $value <= $max,
"Value {} is not in range [{}, {}]", $value, $min, $max);
};
}
pub mod performance_utils {
use std::time::Instant;
pub fn measure_time<F>(f: F) -> std::time::Duration
where
F: FnOnce(),
{
let start = Instant::now();
f();
start.elapsed()
}
pub fn average_time<F>(f: F, iterations: usize) -> std::time::Duration
where
F: Fn(),
{
let total_time: std::time::Duration = (0..iterations)
.map(|_| measure_time(|| f()))
.sum();
total_time / iterations as u32
}
}
pub mod project_utils {
use super::*;
pub fn create_multi_source_project(base_dir: &Path) {
let src_main_java = base_dir.join("src").join("main").join("java");
let src_test_java = base_dir.join("src").join("test").join("java");
fs::create_dir_all(&src_main_java).expect("Failed to create main source directory");
fs::create_dir_all(&src_test_java).expect("Failed to create test source directory");
let main_class_content = r#"
package com.test;
public class MainApp {
public static void main(String[] args) {
System.out.println("Main application");
}
}
"#;
fs::write(src_main_java.join("MainApp.java"), main_class_content)
.expect("Failed to write main class");
let service_class_content = r#"
package com.test;
public class Service {
public String process(String input) {
return "Processed: " + input;
}
}
"#;
fs::write(src_main_java.join("Service.java"), service_class_content)
.expect("Failed to write service class");
let test_class_content = r#"
package com.test;
import org.junit.Test;
import static org.junit.Assert.*;
public class ServiceTest {
@Test
public void testProcess() {
Service service = new Service();
String result = service.process("test");
assertEquals("Processed: test", result);
}
}
"#;
fs::write(src_test_java.join("ServiceTest.java"), test_class_content)
.expect("Failed to write test class");
}
pub fn create_large_project(base_dir: &Path, num_files: usize) {
let src_main_java = base_dir.join("src").join("main").join("java");
fs::create_dir_all(&src_main_java).expect("Failed to create large project directory");
let pom_content = r#"<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>large-project</artifactId>
<version>1.0.0</version>
</project>"#;
fs::write(base_dir.join("pom.xml"), pom_content)
.expect("Failed to write large project pom.xml");
for i in 0..num_files {
let java_content = format!(r#"
package com.test;
/**
* Test class {}
*/
public class TestClass{{
public String getMessage() {{
return "Message from TestClass{}";
}}
public int process(int value) {{
return value * 2;
}}
}}
"#, i, i);
fs::write(src_main_java.join(format!("TestClass{}.java", i)), java_content)
.expect(&format!("Failed to write TestClass{}.java", i));
}
}
}
pub mod assertions {
use super::*;
pub fn assert_contains_ignore_case(output: &str, expected: &str) {
let output_lower = output.to_lowercase();
let expected_lower = expected.to_lowercase();
assert!(output_lower.contains(&expected_lower),
"Output '{}' does not contain '{}'", output, expected);
}
pub fn assert_non_empty_output(args: &[&str], current_dir: Option<&Path>) {
let output = run_jbuild_command(args, current_dir);
assert!(!output.stdout.is_empty() || !output.stderr.is_empty(),
"Command produced no output");
}
}