diff --git a/languages/java/tasks.json b/languages/java/tasks.json index ac2bfe8..b3b4b6f 100644 --- a/languages/java/tasks.json +++ b/languages/java/tasks.json @@ -1,7 +1,7 @@ [ { "label": "Run $ZED_CUSTOM_java_class_name", - "command": "pkg=\"${ZED_CUSTOM_java_package_name:}\"; cls=\"$ZED_CUSTOM_java_class_name\"; if [ -n \"$pkg\" ]; then c=\"$pkg.$cls\"; else c=\"$cls\"; fi; if [ -f pom.xml ]; then [ -f ./mvnw ] && CMD=\"./mvnw\" || CMD=\"mvn\"; $CMD clean compile exec:java -Dexec.mainClass=\"$c\"; elif [ -f build.gradle ] || [ -f build.gradle.kts ]; then [ -f ./gradlew ] && CMD=\"./gradlew\" || CMD=\"gradle\"; $CMD run -PmainClass=\"$c\"; else find . -name '*.java' -not -path './bin/*' -not -path './target/*' -not -path './build/*' -print0 | xargs -0 javac -d bin && java -cp bin \"$c\"; fi;", + "command": "pkg=\"$ZED_CUSTOM_java_package_name\"; cls=\"$ZED_CUSTOM_java_class_name\"; if [ -n \"$pkg\" ]; then c=\"$pkg.$cls\"; else c=\"$cls\"; fi; f=\"$ZED_FILE\"; p=\"$PWD\"; d=$(dirname \"${f#$p/}\"); if [ -f pom.xml ]; then m=\".\"; md=\"$d\"; while [ \"$md\" != \".\" ] && [ \"$md\" != \"/\" ]; do if [ -f \"$md/pom.xml\" ]; then m=\"$md\"; break; fi; md=$(dirname \"$md\"); done; [ -f ./mvnw ] && CMD=\"./mvnw\" || CMD=\"mvn\"; if [ \"$m\" = \".\" ]; then $CMD clean test-compile exec:java -Dexec.mainClass=\"$c\" -Dexec.classpathScope=test; else $CMD clean test-compile -pl \"$m\" -am && $CMD exec:java -pl \"$m\" -Dexec.mainClass=\"$c\" -Dexec.classpathScope=test; fi; elif [ -f build.gradle ] || [ -f build.gradle.kts ] || [ -f settings.gradle ] || [ -f settings.gradle.kts ]; then m=\".\"; md=\"$d\"; while [ \"$md\" != \".\" ] && [ \"$md\" != \"/\" ]; do if [ -f \"$md/build.gradle\" ] || [ -f \"$md/build.gradle.kts\" ]; then m=\"$md\"; break; fi; md=$(dirname \"$md\"); done; if [ \"$m\" = \".\" ]; then mp=\"\"; else mp=\":$(echo \"$m\" | tr '/' ':')\"; fi; [ -f ./gradlew ] && CMD=\"./gradlew\" || CMD=\"gradle\"; $CMD ${mp}:run -PmainClass=\"$c\"; else find . -name '*.java' -not -path './bin/*' -not -path './target/*' -not -path './build/*' -print0 | xargs -0 javac -d bin && java -cp bin \"$c\"; fi;", "use_new_terminal": false, "reveal": "always", "tags": ["java-main"], @@ -14,7 +14,7 @@ }, { "label": "$ZED_CUSTOM_java_class_name.${ZED_CUSTOM_java_outer_class_name:}.$ZED_CUSTOM_java_method_name", - "command": "package=\"$ZED_CUSTOM_java_package_name\"; outer=\"${ZED_CUSTOM_java_outer_class_name:}\"; inner=\"$ZED_CUSTOM_java_class_name\"; method=\"$ZED_CUSTOM_java_method_name\"; sep=\"$\"; if [ -n \"$outer\" ]; then c=\"$outer$sep$inner\"; else c=\"$inner\"; fi; if [ -f pom.xml ]; then [ -f ./mvnw ] && CMD=\"./mvnw\" || CMD=\"mvn\"; $CMD clean test -Dtest=\"$package.$c#$method\"; elif [ -f build.gradle ] || [ -f build.gradle.kts ]; then [ -f ./gradlew ] && CMD=\"./gradlew\" || CMD=\"gradle\"; $CMD test --tests \"$package.$c.$method\"; else >&2 echo 'No build tool found'; exit 1; fi;", + "command": "package=\"$ZED_CUSTOM_java_package_name\"; outer=\"${ZED_CUSTOM_java_outer_class_name:}\"; inner=\"$ZED_CUSTOM_java_class_name\"; method=\"$ZED_CUSTOM_java_method_name\"; sep=\"$\"; if [ -n \"$outer\" ]; then c=\"$outer$sep$inner\"; else c=\"$inner\"; fi; f=\"$ZED_FILE\"; p=\"$PWD\"; d=$(dirname \"${f#$p/}\"); if [ -f pom.xml ]; then m=\".\"; md=\"$d\"; while [ \"$md\" != \".\" ] && [ \"$md\" != \"/\" ]; do if [ -f \"$md/pom.xml\" ]; then m=\"$md\"; break; fi; md=$(dirname \"$md\"); done; [ -f ./mvnw ] && CMD=\"./mvnw\" || CMD=\"mvn\"; if [ \"$m\" = \".\" ]; then $CMD clean test -Dtest=\"$package.$c#$method\"; else $CMD clean test-compile -pl \"$m\" -am && $CMD test -pl \"$m\" -Dtest=\"$package.$c#$method\"; fi; elif [ -f build.gradle ] || [ -f build.gradle.kts ] || [ -f settings.gradle ] || [ -f settings.gradle.kts ]; then m=\".\"; md=\"$d\"; while [ \"$md\" != \".\" ] && [ \"$md\" != \"/\" ]; do if [ -f \"$md/build.gradle\" ] || [ -f \"$md/build.gradle.kts\" ]; then m=\"$md\"; break; fi; md=$(dirname \"$md\"); done; if [ \"$m\" = \".\" ]; then mp=\"\"; else mp=\":$(echo \"$m\" | tr '/' ':')\"; fi; [ -f ./gradlew ] && CMD=\"./gradlew\" || CMD=\"gradle\"; $CMD ${mp}:test --tests \"$package.$c.$method\"; else >&2 echo 'No build tool found'; exit 1; fi;", "use_new_terminal": false, "reveal": "always", "tags": ["java-test-method", "java-test-method-nested"], @@ -27,7 +27,7 @@ }, { "label": "Test class $ZED_CUSTOM_java_class_name", - "command": "package=\"$ZED_CUSTOM_java_package_name\"; outer=\"${ZED_CUSTOM_java_outer_class_name:}\"; inner=\"$ZED_CUSTOM_java_class_name\"; sep=\"$\"; if [ -n \"$outer\" ]; then c=\"$outer$sep$inner\"; else c=\"$inner\"; fi; if [ -f pom.xml ]; then [ -f ./mvnw ] && CMD=\"./mvnw\" || CMD=\"mvn\"; $CMD clean test -Dtest=\"$package.$c\"; elif [ -f build.gradle ] || [ -f build.gradle.kts ]; then [ -f ./gradlew ] && CMD=\"./gradlew\" || CMD=\"gradle\"; $CMD test --tests \"$package.$c\"; else >&2 echo 'No build tool found'; exit 1; fi;", + "command": "package=\"$ZED_CUSTOM_java_package_name\"; outer=\"${ZED_CUSTOM_java_outer_class_name:}\"; inner=\"$ZED_CUSTOM_java_class_name\"; sep=\"$\"; if [ -n \"$outer\" ]; then c=\"$outer$sep$inner\"; else c=\"$inner\"; fi; f=\"$ZED_FILE\"; p=\"$PWD\"; d=$(dirname \"${f#$p/}\"); if [ -f pom.xml ]; then m=\".\"; md=\"$d\"; while [ \"$md\" != \".\" ] && [ \"$md\" != \"/\" ]; do if [ -f \"$md/pom.xml\" ]; then m=\"$md\"; break; fi; md=$(dirname \"$md\"); done; [ -f ./mvnw ] && CMD=\"./mvnw\" || CMD=\"mvn\"; if [ \"$m\" = \".\" ]; then $CMD clean test -Dtest=\"$package.$c\"; else $CMD clean test-compile -pl \"$m\" -am && $CMD test -pl \"$m\" -Dtest=\"$package.$c\"; fi; elif [ -f build.gradle ] || [ -f build.gradle.kts ] || [ -f settings.gradle ] || [ -f settings.gradle.kts ]; then m=\".\"; md=\"$d\"; while [ \"$md\" != \".\" ] && [ \"$md\" != \"/\" ]; do if [ -f \"$md/build.gradle\" ] || [ -f \"$md/build.gradle.kts\" ]; then m=\"$md\"; break; fi; md=$(dirname \"$md\"); done; if [ \"$m\" = \".\" ]; then mp=\"\"; else mp=\":$(echo \"$m\" | tr '/' ':')\"; fi; [ -f ./gradlew ] && CMD=\"./gradlew\" || CMD=\"gradle\"; $CMD ${mp}:test --tests \"$package.$c\"; else >&2 echo 'No build tool found'; exit 1; fi;", "use_new_terminal": false, "reveal": "always", "tags": ["java-test-class", "java-test-class-nested"], @@ -40,7 +40,7 @@ }, { "label": "Run tests", - "command": "if [ -f pom.xml ]; then [ -f ./mvnw ] && CMD=\"./mvnw\" || CMD=\"mvn\"; $CMD clean test; elif [ -f build.gradle ] || [ -f build.gradle.kts ]; then [ -f ./gradlew ] && CMD=\"./gradlew\" || CMD=\"gradle\"; $CMD test; else >&2 echo 'No build tool found'; exit 1; fi;", + "command": "f=\"$ZED_FILE\"; p=\"$PWD\"; d=$(dirname \"${f#$p/}\"); if [ -f pom.xml ]; then m=\".\"; md=\"$d\"; while [ \"$md\" != \".\" ] && [ \"$md\" != \"/\" ]; do if [ -f \"$md/pom.xml\" ]; then m=\"$md\"; break; fi; md=$(dirname \"$md\"); done; [ -f ./mvnw ] && CMD=\"./mvnw\" || CMD=\"mvn\"; if [ \"$m\" = \".\" ]; then $CMD clean test; else $CMD clean test-compile -pl \"$m\" -am && $CMD test -pl \"$m\"; fi; elif [ -f build.gradle ] || [ -f build.gradle.kts ] || [ -f settings.gradle ] || [ -f settings.gradle.kts ]; then m=\".\"; md=\"$d\"; while [ \"$md\" != \".\" ] && [ \"$md\" != \"/\" ]; do if [ -f \"$md/build.gradle\" ] || [ -f \"$md/build.gradle.kts\" ]; then m=\"$md\"; break; fi; md=$(dirname \"$md\"); done; if [ \"$m\" = \".\" ]; then mp=\"\"; else mp=\":$(echo \"$m\" | tr '/' ':')\"; fi; [ -f ./gradlew ] && CMD=\"./gradlew\" || CMD=\"gradle\"; $CMD ${mp}:test; else >&2 echo 'No build tool found'; exit 1; fi;", "use_new_terminal": false, "reveal": "always", "shell": { diff --git a/tests/task_verification_test.rs b/tests/task_verification_test.rs new file mode 100644 index 0000000..1f8d79b --- /dev/null +++ b/tests/task_verification_test.rs @@ -0,0 +1,222 @@ +use serde_json::Value; +use std::fs; +use std::path::{Path, PathBuf}; + +fn setup_mock_project( + temp_dir: &Path, + project_type: &str, + is_multi: bool, +) -> (PathBuf, PathBuf) { + let module_dir = if is_multi { + temp_dir.join("module-a") + } else { + temp_dir.to_path_buf() + }; + + let package_dir = if project_type == "maven" && is_multi { + module_dir.join("src/test/java/com/example") + } else { + module_dir.join("src/main/java/com/example") + }; + + fs::create_dir_all(&package_dir).unwrap(); + + let bin_dir = temp_dir.join("bin"); + fs::create_dir_all(&bin_dir).unwrap(); + + if project_type == "maven" { + fs::File::create(temp_dir.join("pom.xml")).unwrap(); + if is_multi { + fs::File::create(module_dir.join("pom.xml")).unwrap(); + } + let mvn_mock = bin_dir.join("mvn"); + fs::write(&mvn_mock, "#!/bin/sh\necho \"MVN_CALLED: $@\"").unwrap(); + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + fs::set_permissions(&mvn_mock, fs::Permissions::from_mode(0o755)).unwrap(); + } + } else { + fs::File::create(temp_dir.join("settings.gradle")).unwrap(); + if is_multi { + fs::File::create(module_dir.join("build.gradle")).unwrap(); + } + let gradle_mock = bin_dir.join("gradle"); + fs::write(&gradle_mock, "#!/bin/sh\necho \"GRADLE_CALLED: $@\"").unwrap(); + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + fs::set_permissions(&gradle_mock, fs::Permissions::from_mode(0o755)).unwrap(); + } + } + + let zed_file = package_dir.join("Main.java"); + fs::File::create(&zed_file).unwrap(); + + (zed_file, bin_dir) +} + +#[test] +fn test_maven_multi_module_command_logic() { + use std::process::Command as StdCommand; + + let tasks_json = fs::read_to_string("languages/java/tasks.json").expect("Failed to read tasks.json"); + let tasks: Value = serde_json::from_str(&tasks_json).expect("Failed to parse tasks.json"); + let mut run_command = tasks[0]["command"].as_str().expect("Command is not a string").to_string(); + + run_command = run_command.replace("${ZED_CUSTOM_java_outer_class_name:}", "${ZED_CUSTOM_java_outer_class_name:-}"); + + let temp_dir = std::env::temp_dir().join("zed_java_test_maven_logic_integration"); + if temp_dir.exists() { + fs::remove_dir_all(&temp_dir).unwrap(); + } + fs::create_dir_all(&temp_dir).unwrap(); + + let (zed_file, bin_dir) = setup_mock_project(&temp_dir, "maven", true); + + let old_path = std::env::var("PATH").unwrap_or_default(); + let new_path = format!("{}:{}", bin_dir.to_string_lossy(), old_path); + + let output = StdCommand::new("sh") + .arg("-c") + .arg(&run_command) + .env("ZED_FILE", zed_file.to_string_lossy().to_string()) + .env("PWD", temp_dir.to_string_lossy().to_string()) + .env("ZED_CUSTOM_java_package_name", "com.example") + .env("ZED_CUSTOM_java_class_name", "Main") + .env("PATH", new_path) + .current_dir(&temp_dir) + .output() + .expect("Failed to execute shell command"); + + let stdout = String::from_utf8_lossy(&output.stdout); + + assert!(stdout.contains("MVN_CALLED: clean test-compile -pl module-a -am"), "Should build submodule with dependencies. Got: {}", stdout); + assert!(stdout.contains("MVN_CALLED: exec:java -pl module-a"), "Should run only the submodule. Got: {}", stdout); + assert!(stdout.contains("-Dexec.classpathScope=test"), "Should use test classpath scope. Got: {}", stdout); + + fs::remove_dir_all(&temp_dir).unwrap(); +} + +#[test] +fn test_maven_multi_module_test_method_logic() { + use std::process::Command as StdCommand; + + let tasks_json = fs::read_to_string("languages/java/tasks.json").expect("Failed to read tasks.json"); + let tasks: Value = serde_json::from_str(&tasks_json).expect("Failed to parse tasks.json"); + let mut test_command = tasks[1]["command"].as_str().expect("Command is not a string").to_string(); + + test_command = test_command.replace("${ZED_CUSTOM_java_outer_class_name:}", "${ZED_CUSTOM_java_outer_class_name:-}"); + + let temp_dir = std::env::temp_dir().join("zed_java_test_maven_method_logic_integration"); + if temp_dir.exists() { + fs::remove_dir_all(&temp_dir).unwrap(); + } + fs::create_dir_all(&temp_dir).unwrap(); + + let (zed_file, bin_dir) = setup_mock_project(&temp_dir, "maven", true); + + let old_path = std::env::var("PATH").unwrap_or_default(); + let new_path = format!("{}:{}", bin_dir.to_string_lossy(), old_path); + + let output = StdCommand::new("sh") + .arg("-c") + .arg(&test_command) + .env("ZED_FILE", zed_file.to_string_lossy().to_string()) + .env("PWD", temp_dir.to_string_lossy().to_string()) + .env("ZED_CUSTOM_java_package_name", "com.example") + .env("ZED_CUSTOM_java_class_name", "Main") + .env("ZED_CUSTOM_java_method_name", "shouldPersist") + .env("PATH", new_path) + .current_dir(&temp_dir) + .output() + .expect("Failed to execute shell command"); + + let stdout = String::from_utf8_lossy(&output.stdout); + + assert!(stdout.contains("MVN_CALLED: clean test-compile -pl module-a -am"), "Should build submodule with dependencies. Got: {}", stdout); + assert!(stdout.contains("MVN_CALLED: test -pl module-a -Dtest=com.example.Main#shouldPersist"), "Should run only the submodule test. Got: {}", stdout); + + fs::remove_dir_all(&temp_dir).unwrap(); +} + +#[test] +fn test_gradle_multi_module_command_logic() { + use std::process::Command as StdCommand; + + let tasks_json = fs::read_to_string("languages/java/tasks.json").expect("Failed to read tasks.json"); + let tasks: Value = serde_json::from_str(&tasks_json).expect("Failed to parse tasks.json"); + let mut run_command = tasks[0]["command"].as_str().expect("Command is not a string").to_string(); + + run_command = run_command.replace("${ZED_CUSTOM_java_outer_class_name:}", "${ZED_CUSTOM_java_outer_class_name:-}"); + + let temp_dir = std::env::temp_dir().join("zed_java_test_gradle_logic_integration"); + if temp_dir.exists() { + fs::remove_dir_all(&temp_dir).unwrap(); + } + fs::create_dir_all(&temp_dir).unwrap(); + + let (zed_file, bin_dir) = setup_mock_project(&temp_dir, "gradle", true); + + let old_path = std::env::var("PATH").unwrap_or_default(); + let new_path = format!("{}:{}", bin_dir.to_string_lossy(), old_path); + + let output = StdCommand::new("sh") + .arg("-c") + .arg(&run_command) + .env("ZED_FILE", zed_file.to_string_lossy().to_string()) + .env("PWD", temp_dir.to_string_lossy().to_string()) + .env("ZED_CUSTOM_java_package_name", "com.example") + .env("ZED_CUSTOM_java_class_name", "Main") + .env("PATH", new_path) + .current_dir(&temp_dir) + .output() + .expect("Failed to execute shell command"); + + let stdout = String::from_utf8_lossy(&output.stdout); + + assert!(stdout.contains("GRADLE_CALLED: :module-a:run"), "Should run with correct module path. Got: {}", stdout); + + fs::remove_dir_all(&temp_dir).unwrap(); +} + +#[test] +fn test_gradle_multi_module_test_method_logic() { + use std::process::Command as StdCommand; + + let tasks_json = fs::read_to_string("languages/java/tasks.json").expect("Failed to read tasks.json"); + let tasks: Value = serde_json::from_str(&tasks_json).expect("Failed to parse tasks.json"); + let mut test_command = tasks[1]["command"].as_str().expect("Command is not a string").to_string(); + + test_command = test_command.replace("${ZED_CUSTOM_java_outer_class_name:}", "${ZED_CUSTOM_java_outer_class_name:-}"); + + let temp_dir = std::env::temp_dir().join("zed_java_test_gradle_method_logic_integration"); + if temp_dir.exists() { + fs::remove_dir_all(&temp_dir).unwrap(); + } + fs::create_dir_all(&temp_dir).unwrap(); + + let (zed_file, bin_dir) = setup_mock_project(&temp_dir, "gradle", true); + + let old_path = std::env::var("PATH").unwrap_or_default(); + let new_path = format!("{}:{}", bin_dir.to_string_lossy(), old_path); + + let output = StdCommand::new("sh") + .arg("-c") + .arg(&test_command) + .env("ZED_FILE", zed_file.to_string_lossy().to_string()) + .env("PWD", temp_dir.to_string_lossy().to_string()) + .env("ZED_CUSTOM_java_package_name", "com.example") + .env("ZED_CUSTOM_java_class_name", "Main") + .env("ZED_CUSTOM_java_method_name", "shouldPersist") + .env("PATH", new_path) + .current_dir(&temp_dir) + .output() + .expect("Failed to execute shell command"); + + let stdout = String::from_utf8_lossy(&output.stdout); + + assert!(stdout.contains("GRADLE_CALLED: :module-a:test --tests com.example.Main.shouldPersist"), "Should run submodule test with correct path. Got: {}", stdout); + + fs::remove_dir_all(&temp_dir).unwrap(); +}