Skip to content

Commit

Permalink
Make each Target a single file
Browse files Browse the repository at this point in the history
  • Loading branch information
espertus committed Mar 4, 2024
1 parent 4a04731 commit 9221b2f
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 78 deletions.
71 changes: 40 additions & 31 deletions src/main/java/com/spertus/jacquard/common/Target.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
import com.spertus.jacquard.exceptions.ClientException;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* The target of a {@link Grader}, such as a file or a directory.
* The target of a {@link Grader}, which must be a file.
*/
public final class Target {
private static final String SUBMISSION_PATH_TEMPLATE =
Expand All @@ -21,33 +23,35 @@ public final class Target {
private final Path path;

private Target(final Path path) {
if (path.toFile().isDirectory()) {
throw new ClientException("The path argument must be to a file, not a directory.");
}
this.path = path;
}

/**
* Creates a target from a path, which could be to a file or directory.
* Creates a target from a path, which must be to a single file.
*
* @param path the path
* @return the target
* @throws ClientException if the path is to a directory rather than a file
*/
public static Target fromPath(final Path path) {
return new Target(path);
}

/**
* Creates a target from a relative path string. It does not matter whether
* Creates a target from a relative path string to a file. It does not matter whether
* forward slashes or backslashes are used as separators.
*
* @param s a relative path string
* @param s a relative path string to a file
* @return the target
*
* @deprecated Call {@link #fromClass(Class)} instead.
* @throws ClientException if the path is to a directory rather than a file
*/
@Deprecated()
public static Target fromPathString(final String s) {
// https://stackoverflow.com/a/40163941/631051
final Path absPath = FileSystems.getDefault().getPath(s).normalize().toAbsolutePath();
return new Target(absPath);
final Path path = FileSystems.getDefault().getPath(s).normalize().toAbsolutePath();
return fromPath(path);
}

/**
Expand Down Expand Up @@ -75,10 +79,10 @@ public static Target fromClass(Class<?> targetClass) {
* @param dir a relative directory string (ending with <code>/</code> or
* <code>\</code>)
* @param files the names of the files in the directory
* @return the target
* @return the targets
* @throws ClientException if dir does not end with a path separator
*/
private static List<Target> fromPathStrings(final String dir, final String... files) {
public static List<Target> fromPathStrings(final String dir, final String... files) {
if (!dir.endsWith("/") && !dir.endsWith("\\")) {
throw new ClientException("dir must end with a path separator (/ or \\)");
}
Expand All @@ -87,6 +91,28 @@ private static List<Target> fromPathStrings(final String dir, final String... fi
.collect(Collectors.toList());
}

/**
* Creates targets from all the files in the specified directory.
*
* @param dir a relative directory string
* @return the targets
* @throws ClientException if dir is not a directory or is not accessible
*/
public static List<Target> fromDirectory(final String dir) {
Path path = Paths.get(dir);
if (!path.toFile().isDirectory()) {
throw new ClientException("Argument to fromDirectory() must be a directory.");
}
try (Stream<Path> paths = Files.walk(path)) {
return paths
.filter(Files::isRegularFile)
.map(file -> fromPath(file.toAbsolutePath()))
.collect(Collectors.toList());
} catch (IOException e) {
throw new ClientException("Unable to access directory " + dir);
}
}

/**
* Gets the string representation of this target's absolute path.
*
Expand Down Expand Up @@ -115,40 +141,23 @@ public File toFile() {
}

/**
* Gets this target's directory. This is the target itself if it is a
* directory; otherwise, it is the parent directory of the file.
* Gets this target's directory.
*
* @return the directory
*/
public Path toDirectory() {
final File file = toFile();
if (file.isDirectory()) {
return file.toPath();
throw new RuntimeException("It should not be possible to have a Target that is a directory.");
} else {
return file.getParentFile().toPath();
}
}

// /**
// * Parses this target, if it is a file.
// *
// * @param autograder autograder (for language level)
// * @return the parsed file
// * @throws ClientException if this target is a directory
// */
// public CompilationUnit toCompilationUnit(Autograder autograder) {
// if (toFile().isDirectory()) {
// throw new ClientException("Cannot parse directory " + toPathString());
// }
// return Parser.parse(autograder.getJavaLevel(), toFile());
// }

@Override
public boolean equals(final Object o) {
if (o instanceof Target other) {
return this.toPath().equals(other.toPath()) &&
this.toFile().equals(other.toFile()) &&
this.toDirectory().equals(other.toDirectory());
return this.path.equals(other.path);
}
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/com/spertus/jacquard/PmdGraderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ public void testDirectory() {
MAX_PENALTY,
"category/java/documentation.xml",
"category/java/codestyle.xml");
Target target = Target.fromPathString("src/test/resources/good/");
List<Result> results = pmdGrader.grade(target); // lots of errors
List<Target> targets = Target.fromDirectory("src/test/resources/good/");
List<Result> results = pmdGrader.grade(targets); // lots of errors
TestUtilities.assertResultsMatch(results, 1, 0, MAX_PENALTY);
}

Expand Down
63 changes: 18 additions & 45 deletions src/test/java/com/spertus/jacquard/TargetTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.net.URISyntaxException;
import java.nio.file.*;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
Expand Down Expand Up @@ -59,49 +60,21 @@ public void testToDirectoryForResource() {
assertEquals(Paths.get(GOOD_RESOURCES_SUBDIR).toAbsolutePath(), mobTarget.toDirectory());
}

// @Test
// public void testToClassName() {
// assertEquals("Mob", mobTarget.toClassName());
// }
//
// @Test
// public void testToClassNameThrowsExceptionForNonJava() {
// assertThrows(ClientException.class,
// () -> TestUtilities.getTargetFromResource("invalid/NotJava.txt").toClassName());
// }
//
// @Test
// public void testToClassNameThrowsExceptionForDirectory() {
// assertThrows(ClientException.class,
// () -> Target.fromPathString(".").toClassName());
// }
//
// @Test
// public void testToClassNameWorksForUnparseable() throws URISyntaxException {
// assertEquals("Unparseable", TestUtilities.getTargetFromResource("invalid/Unparseable.java").toClassName());
// }
//
// @Test
// public void testToPackageName() {
// assertEquals("student", mobTarget.toPackageName());
// }
//
// @Test
// public void testToPackageNameThrowsExceptionForNonJava() {
// assertThrows(ClientException.class,
// () -> TestUtilities.getTargetFromResource("invalid/NotJava.txt").toPackageName());
// }
//
// @Test
// public void testToPackageNameThrowsExceptionForDirectory() {
// assertThrows(ClientException.class,
// () -> Target.fromPathString(".").toPackageName());
// }
//
// @Test
// public void testToPackageNameThrowsExceptionForUnparseable() {
// assertThrows(ClientException.class,
// () -> TestUtilities.getTargetFromResource("invalid/Unparseable.java").toPackageName());
// }
@Test
public void testFromDirectoryReturnsAllFiles() {
List<Target> targets = Target.fromDirectory("src/test/resources/good/");
assertEquals(12, targets.size());
}

}
@Test
public void testFromDirectoryRejectsFilePath() {
assertThrows(ClientException.class,
() -> Target.fromDirectory("src/test/resources/good/BadFormatting.java"));
}

@Test
public void testFromDirectoryRejectsBadPath() {
assertThrows(ClientException.class,
() -> Target.fromDirectory("src/test/resources/nosuchdir"));
}
}

0 comments on commit 9221b2f

Please sign in to comment.