Skip to content

Commit 127a7eb

Browse files
committed
Add tests for including fules from the root dir of exercise
1 parent 7965bc0 commit 127a7eb

File tree

2 files changed

+92
-3
lines changed

2 files changed

+92
-3
lines changed

crates/tmc-langs-plugins/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,16 @@ impl PluginType {
306306
delegate_plugin_type!(self, find_project_dir_in_archive(archive))
307307
}
308308

309+
pub fn safe_find_project_dir_in_archive<R: Read + Seek>(
310+
self,
311+
archive: &mut Archive<R>,
312+
) -> Result<PathBuf, TmcError> {
313+
Ok(delegate_plugin_type!(
314+
self,
315+
safe_find_project_dir_in_archive(archive)
316+
))
317+
}
318+
309319
pub fn get_available_points(self, exercise_path: &Path) -> Result<Vec<String>, TmcError> {
310320
delegate_plugin_type!(self, get_available_points(exercise_path))
311321
}

crates/tmc-langs/src/submission_packaging.rs

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -314,10 +314,10 @@ fn extract_with_filter<F: Fn(&Path) -> bool>(
314314
let file = file_util::open_file(archive)?;
315315
let mut zip = Archive::new(file, compression)?;
316316
let project_dir_in_archive = if naive {
317-
PathBuf::new()
317+
Ok(PathBuf::new())
318318
} else {
319-
plugin.find_project_dir_in_archive(&mut zip)?
320-
};
319+
plugin.safe_find_project_dir_in_archive(&mut zip)
320+
}?;
321321

322322
let mut iter = zip.iter()?;
323323
loop {
@@ -783,4 +783,83 @@ mod test {
783783
.exists()
784784
);
785785
}
786+
787+
#[test]
788+
fn includes_files_in_root_dir_from_exercise() {
789+
init();
790+
791+
let temp = tempfile::tempdir().unwrap();
792+
let clone_root = temp.path().join("some_course");
793+
file_util::create_dir_all(&clone_root).unwrap();
794+
795+
// Copy the Maven exercise to our temp directory
796+
let src_clone = Path::new(MAVEN_CLONE);
797+
file_util::copy(src_clone, &clone_root).unwrap();
798+
799+
let exercise_dir = clone_root.join("MavenExercise");
800+
801+
// Create a file in the root directory of the exercise (simulating repo file)
802+
let repo_file_path = exercise_dir.join("foo.txt");
803+
file_util::write_to_file(b"repohello", &repo_file_path).unwrap();
804+
805+
// Create a submission zip that also has foo.txt but with different content
806+
// We need to create a proper Maven project structure that the plugin can understand
807+
let sub_zip_path = temp.path().join("submission.zip");
808+
let sub_zip_file = file_util::create_file(&sub_zip_path).unwrap();
809+
let mut zw = zip::ZipWriter::new(sub_zip_file);
810+
let opts = SimpleFileOptions::default();
811+
812+
// Create the Maven project structure
813+
zw.add_directory("MavenExercise", opts).unwrap();
814+
zw.add_directory("MavenExercise/src", opts).unwrap();
815+
zw.add_directory("MavenExercise/src/main", opts).unwrap();
816+
zw.add_directory("MavenExercise/src/main/java", opts)
817+
.unwrap();
818+
819+
// Add the student's modified file
820+
zw.start_file("MavenExercise/foo.txt", opts).unwrap();
821+
std::io::Write::write_all(&mut zw, b"submissionhello").unwrap();
822+
823+
// Add a source file
824+
zw.start_file("MavenExercise/src/main/java/SimpleStuff.java", opts)
825+
.unwrap();
826+
std::io::Write::write_all(&mut zw, b"public class SimpleStuff { }").unwrap();
827+
828+
zw.finish().unwrap();
829+
830+
let output_arch = temp.path().join("out.tar");
831+
prepare_submission(
832+
PrepareSubmission {
833+
archive: &sub_zip_path,
834+
compression: Compression::Zip,
835+
extract_naively: false,
836+
},
837+
&output_arch,
838+
false,
839+
TmcParams::new(),
840+
&exercise_dir,
841+
None,
842+
Compression::Tar,
843+
)
844+
.unwrap();
845+
assert!(output_arch.exists());
846+
847+
// Unpack and verify that foo.txt content is from the repo, not submission
848+
let output_file = file_util::open_file(&output_arch).unwrap();
849+
let mut archive = tar::Archive::new(output_file);
850+
let output_extracted = temp.path().join("output");
851+
archive.unpack(&output_extracted).unwrap();
852+
853+
// Verify foo.txt exists and has content from repo, not submission
854+
let foo_file = output_extracted.join("some_course/MavenExercise/foo.txt");
855+
assert!(
856+
foo_file.exists(),
857+
"foo.txt should be included in the archive"
858+
);
859+
let content = fs::read_to_string(foo_file).unwrap();
860+
assert_eq!(
861+
content, "repohello",
862+
"Should use repo content, not submission content"
863+
);
864+
}
786865
}

0 commit comments

Comments
 (0)