diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/ListExercisesCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/ListExercisesCommand.java index fdf0353c..88b21f57 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/ListExercisesCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/ListExercisesCommand.java @@ -10,7 +10,6 @@ import fi.helsinki.cs.tmc.cli.io.EnvironmentUtil; import fi.helsinki.cs.tmc.cli.io.ExternalsUtil; import fi.helsinki.cs.tmc.cli.io.Io; -import fi.helsinki.cs.tmc.cli.io.WorkDir; import fi.helsinki.cs.tmc.core.domain.Course; import fi.helsinki.cs.tmc.core.domain.Exercise; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/admin/AdminCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/admin/AdminCommand.java new file mode 100644 index 00000000..256f19a2 --- /dev/null +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/admin/AdminCommand.java @@ -0,0 +1,382 @@ +package fi.helsinki.cs.tmc.cli.command.admin; + +import fi.helsinki.cs.tmc.cli.core.AbstractCommand; +import fi.helsinki.cs.tmc.cli.core.CliContext; +import fi.helsinki.cs.tmc.cli.core.Command; +import fi.helsinki.cs.tmc.cli.io.Io; + +import fi.helsinki.cs.tmc.langs.LanguagePlugin; +import fi.helsinki.cs.tmc.langs.abstraction.ValidationResult; +import fi.helsinki.cs.tmc.langs.domain.ExerciseDesc; +import fi.helsinki.cs.tmc.langs.domain.ExercisePackagingConfiguration; +import fi.helsinki.cs.tmc.langs.domain.Filer; +import fi.helsinki.cs.tmc.langs.domain.FilterFileTreeVisitor; +import fi.helsinki.cs.tmc.langs.domain.GeneralDirectorySkipper; +import fi.helsinki.cs.tmc.langs.domain.NoLanguagePluginFoundException; +import fi.helsinki.cs.tmc.langs.domain.RunResult; +import fi.helsinki.cs.tmc.langs.util.ProjectType; +import fi.helsinki.cs.tmc.langs.util.TaskExecutor; + +import com.google.common.base.Optional; +import com.google.gson.Gson; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Options; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +/*TODO split this command to multiple admin commands */ +@Command(name = "admin", desc = "The admin command") +public class AdminCommand extends AbstractCommand { + + private static final Logger logger = LoggerFactory.getLogger(AdminCommand.class); + private static final String HELP_TEXT = + "Usage: tmc admin []\n\n" + + "Commands:\n" + + "checkstyle --exercise= --output= --locale=\n" + + " Run checkstyle or similar plugin to project if applicable.\n" + + "help\n" + + " Display help information.\n" + + "prepare-solutions --exercise= --output=\n" + + " Prepare a presentable solution from the original.\n" + + "prepare-stubs --exercise= -- output= --locale=\n" + + " Prepare a stub exercise from the original.\n" + + "run-tests --exercise= --output=\n" + + " Run the tests for the exercise.\n" + + "scan-exercise --exercise= --output=\n" + + " Produce an exercise description of an exercise directory.\n" + + "find-exercises --exercise= --output=\n" + + " Produce list of found exercises.\n" + + "get-exercise-packaging-configuration --exercise= --output=\n" + + " Returns configuration of under which folders student and nonstudent" + + " files are located.\n" + + "clean --exercise=\n" + + " Produce list of found exercises."; +// + "prepare-submission --clonePath --submissionPath --output=PATH" +// + " Prepares from submission and solution project for which the tests" +// + " can be run in sandbox"; + + private Io io; + private TaskExecutor executor; + + private Path exercisePath; + private Path outputPath; + private Locale locale; + + @Override + public void getOptions(Options options) { + options.addOption("e", "exercise", true, "Path to exercise"); + options.addOption("o", "output", true, "Output path for the sub-command"); + options.addOption("l", "locale", true, "Locale of the exercise?"); + } + + @Override + public void run(CliContext context, CommandLine args) { + this.io = context.getIo(); + String[] stringArguments = args.getArgs(); + + if (stringArguments.length == 0) { + io.errorln("You have to give some sub-command."); + printUsage(context); + return; + } + + if (!context.loadBackendWithoutLogin()) { + return; + } + + this.executor = context.getTmcLangs(); + String subCommand = stringArguments[0]; + if (args.hasOption("exercise")) { + this.exercisePath = Paths.get(args.getOptionValue("exercise")); + } + if (args.hasOption("output")) { + this.outputPath = Paths.get(args.getOptionValue("output")); + } + if (args.hasOption("locale")) { + this.locale = new Locale(args.getOptionValue("locale")); + } + runSubCommand(subCommand); + } + + private void runSubCommand(String subCommand) { + switch (subCommand) { + case "help": + printHelp(); + break; + case "checkstyle": + runCheckCodeStyle(); + break; + case "scan-exercise": + runScanExercise(); + break; + case "find-exercises": + runFindExercises(); + break; + case "run-tests": + runTests(); + break; + case "prepare-stubs": + runPrepareStubs(); + break; + case "prepare-solutions": + runPrepareSolutions(); + break; + case "get-exercise-packaging-configuration": + runGetExercisePackagingConfiguration(); + break; + case "clean": + runClean(); + break; + default: + printHelp(); + break; + } + } + + private void runCheckCodeStyle() { + if (this.exercisePath == null || this.outputPath == null || this.locale == null) { + io.errorln("Checkstyle command expects exercise path, output path and locale."); + return; + } + ValidationResult validationResult; + try { + validationResult = + executor.runCheckCodeStyle(this.exercisePath, this.locale); + } catch (NoLanguagePluginFoundException e) { + logger.error( + "No suitable language plugin for project at {}", this.exercisePath, e); + io.errorln( + "ERROR: Could not find suitable language plugin for the given exercise " + + "path."); + return; + } + + try { + writeObjectIntoJsonFormat(validationResult, this.outputPath); + io.println("Codestyle report can be found at " + this.outputPath); + } catch (IOException e) { + logger.error("Could not write result into {}", this.outputPath, e); + io.errorln("ERROR: Could not write the results to the given file."); + } + } + + private void runScanExercise() { + if (this.exercisePath == null || this.outputPath == null) { + io.errorln("ScanExercise command expects exercise path and output path."); + return; + } + String exerciseName = this.exercisePath.toFile().getName(); + Optional exerciseDesc; + try { + exerciseDesc = executor.scanExercise(this.exercisePath, exerciseName); + + if (exerciseDesc == null || !exerciseDesc.isPresent()) { + logger.error("Absent exercise description after running scanExercise"); + io.errorln("ERROR: Could not scan the exercises."); + return; + } + } catch (NoLanguagePluginFoundException e) { + logger.error( + "No suitable language plugin for project at {}", this.exercisePath, e); + io.errorln( + "ERROR: Could not find suitable language plugin for the given " + + "exercise path."); + return; + } + + try { + writeObjectIntoJsonFormat(exerciseDesc.get(), this.outputPath); + io.println( + "Exercises scanned successfully, results can be found in " + + this.outputPath); + } catch (IOException e) { + logger.error("Could not write output to {}", this.outputPath, e); + io.errorln("ERROR: Could not write the results to the given file."); + } + } + + private void runFindExercises() { + if (this.exercisePath == null || this.outputPath == null) { + io.errorln("FindExercises command expects exercise path and output path."); + return; + } + Path clonePath = this.exercisePath; + final Set exercises = new HashSet<>(); + Filer exerciseMatchingFiler = + new Filer() { + + @Override + public FileVisitResult decideOnDirectory(Path directory) { + if (executor.isExerciseRootDirectory(directory)) { + exercises.add(directory.toString()); + return FileVisitResult.SKIP_SUBTREE; + } + return FileVisitResult.CONTINUE; + } + + @Override + public void visitFile(Path source, Path relativePath) {} + }; + new FilterFileTreeVisitor() + .addSkipper(new GeneralDirectorySkipper()) + .setClonePath(clonePath) + .setStartPath(clonePath) + .setFiler(exerciseMatchingFiler) + .traverse(); + + try { + writeObjectIntoJsonFormat(exercises, this.outputPath); + io.println("Results can be found in " + this.outputPath); + } catch (IOException e) { + logger.error("Could not write output to {}", this.outputPath, e); + io.errorln("ERROR: Could not write the results to the given file."); + } + } + + private void runTests() { + if (this.exercisePath == null || this.outputPath == null) { + io.errorln("RunTests command expects exercise path and output path."); + return; + } + RunResult runResult; + try { + runResult = executor.runTests(this.exercisePath); + } catch (NoLanguagePluginFoundException e) { + logger.error( + "No suitable language plugin for project at {}", this.exercisePath, e); + io.errorln( + "ERROR: Could not find suitable language plugin for the given " + + "exercise path."); + return; + } + + try { + writeObjectIntoJsonFormat(runResult, this.outputPath); + io.println("Test results can be found in " + this.outputPath); + } catch (IOException e) { + logger.error("Could not write output to {}", this.outputPath, e); + io.errorln("ERROR: Could not write the results to the given file."); + } + } + + private void runPrepareStubs() { + if (this.exercisePath == null || this.outputPath == null || this.locale == null) { + io.errorln("RunTests command expects exercise path, output path and locale."); + return; + } + try { + executor.prepareStubs( + findExerciseDirectoriesAndGetLanguagePlugins(), + this.exercisePath, + this.outputPath); + } catch (NoLanguagePluginFoundException e) { + logger.error( + "No suitable language plugin for project at {}", this.exercisePath, e); + io.errorln( + "ERROR: Could not find suitable language plugin for the given " + + "exercise path."); + } + } + + private void runClean() { + try { + executor.clean(this.exercisePath); + } catch (NoLanguagePluginFoundException e) { + logger.error( + "No suitable language plugin for project at {}", this.exercisePath, e); + io.errorln( + "ERROR: Could not find suitable language plugin for the given " + + "exercise path."); + } + } + + private void runPrepareSolutions() { + try { + executor.prepareSolutions( + findExerciseDirectoriesAndGetLanguagePlugins(), + this.exercisePath, + this.outputPath); + } catch (NoLanguagePluginFoundException e) { + logger.error( + "No suitable language plugin for project at {}", this.exercisePath, e); + io.errorln( + "ERROR: Could not find suitable language plugin for the given " + + "exercise path."); + } + } + + private void runGetExercisePackagingConfiguration() { + ExercisePackagingConfiguration configuration; + try { + configuration = executor.getExercisePackagingConfiguration(this.exercisePath); + } catch (NoLanguagePluginFoundException e) { + logger.error( + "No suitable language plugin for project at {}", this.exercisePath, e); + io.errorln( + "ERROR: Could not find suitable language plugin for the given " + + "exercise path."); + return; + } + + try { + writeObjectIntoJsonFormat(configuration, this.outputPath); + io.println("Results can be found in " + this.outputPath); + } catch (IOException e) { + logger.error("Could not write output to {}", this.outputPath, e); + io.errorln("ERROR: Could not write the results to the given file."); + } + } + + private Map findExerciseDirectoriesAndGetLanguagePlugins() { + final Map map = new HashMap<>(); + Filer exerciseMatchingFiler = + new Filer() { + + @Override + public FileVisitResult decideOnDirectory(Path directory) { + if (executor.isExerciseRootDirectory(directory)) { + try { + map.put( + directory, + ProjectType.getProjectType(directory).getLanguagePlugin()); + } catch (NoLanguagePluginFoundException ex) { + throw new IllegalStateException(ex); + } + return FileVisitResult.SKIP_SUBTREE; + } + return FileVisitResult.CONTINUE; + } + + @Override + public void visitFile(Path source, Path relativePath) {} + }; + new FilterFileTreeVisitor() + .addSkipper(new GeneralDirectorySkipper()) + .setClonePath(this.exercisePath) + .setStartPath(this.exercisePath) + .setFiler(exerciseMatchingFiler) + .traverse(); + return map; + } + + private static void writeObjectIntoJsonFormat(Object obj, Path outputFile) throws IOException { + try (FileWriter writer = new FileWriter(outputFile.toAbsolutePath().toFile())) { + writer.write(new Gson().toJson(obj)); + } + } + + private void printHelp() { + io.println(HELP_TEXT); + } +} \ No newline at end of file diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/admin/TestAdminCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/admin/TestAdminCommand.java deleted file mode 100644 index b0f09851..00000000 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/admin/TestAdminCommand.java +++ /dev/null @@ -1,28 +0,0 @@ -package fi.helsinki.cs.tmc.cli.command.admin; - -import fi.helsinki.cs.tmc.cli.core.AbstractCommand; -import fi.helsinki.cs.tmc.cli.core.CliContext; -import fi.helsinki.cs.tmc.cli.core.Command; -import fi.helsinki.cs.tmc.cli.io.Io; - -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.Options; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@Command(name = "admin", desc = "The test command") -public class TestAdminCommand extends AbstractCommand { - - private static final Logger logger = LoggerFactory.getLogger(TestAdminCommand.class); - private Io io; - - @Override - public void getOptions(Options options) { } - - @Override - public void run(CliContext context, CommandLine args) { - this.io = context.getIo(); - - io.println("test"); - } -} \ No newline at end of file diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/core/CliContext.java b/src/main/java/fi/helsinki/cs/tmc/cli/core/CliContext.java index 459a302f..9f827f45 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/core/CliContext.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/core/CliContext.java @@ -26,6 +26,7 @@ public class CliContext { private Application application; private TmcCore tmcCore; private Settings settings; + private TaskExecutor tmcLangs; /* cached values */ private boolean hasLogin; @@ -42,6 +43,10 @@ public CliContext(Io io, TmcCore core) { } public CliContext(Io io, TmcCore core, WorkDir workDir) { + this(io, core, workDir, null); + } + + public CliContext(Io io, TmcCore core, WorkDir workDir, TaskExecutor executor) { inTest = (io != null); if (!inTest) { io = new TerminalIo(System.in); @@ -52,6 +57,7 @@ public CliContext(Io io, TmcCore core, WorkDir workDir) { this.properties = SettingsIo.loadProperties(); this.settings = new Settings(); this.tmcCore = core; + this.tmcLangs = executor; this.hasLogin = (core != null); this.courseInfo = null; } @@ -171,6 +177,15 @@ public TmcCore getTmcCore() { return this.tmcCore; } + /* TODO this may not work in tests currently + */ + public TaskExecutor getTmcLangs() { + if (this.tmcLangs == null) { + throw new RuntimeException("The loadBackend* method was NOT called"); + } + return this.tmcLangs; + } + /** * Initialize the tmc-core and other cached info. * Use this method if you need i @@ -219,11 +234,9 @@ public void useAccount(Account account) { } private void createTmcCore(Account account) { - TaskExecutor tmcLangs; - - tmcLangs = new TaskExecutorImpl(); + this.tmcLangs = new TaskExecutorImpl(); this.settings.setAccount(account); - this.tmcCore = new TmcCore(settings, tmcLangs); + this.tmcCore = new TmcCore(settings, this.tmcLangs); settings.setWorkDir(workDir); } diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/admin/AdminCommadTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/admin/AdminCommadTest.java new file mode 100644 index 00000000..00690428 --- /dev/null +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/admin/AdminCommadTest.java @@ -0,0 +1,140 @@ +package fi.helsinki.cs.tmc.cli.command.admin; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import fi.helsinki.cs.tmc.cli.Application; +import fi.helsinki.cs.tmc.cli.core.CliContext; +import fi.helsinki.cs.tmc.cli.io.TestIo; +import fi.helsinki.cs.tmc.core.TmcCore; + +import fi.helsinki.cs.tmc.langs.domain.ExerciseDesc; +import fi.helsinki.cs.tmc.langs.domain.NoLanguagePluginFoundException; +import fi.helsinki.cs.tmc.langs.domain.TestDesc; +import fi.helsinki.cs.tmc.langs.util.TaskExecutor; +import fi.helsinki.cs.tmc.langs.utils.TestUtils; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableList; + +import org.junit.Before; +import org.junit.Test; + +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Locale; + +public class AdminCommadTest { + + private Application app; + private CliContext ctx; + private TestIo io; + private TmcCore mockCore; + private TaskExecutor mockLangs; + + private static Path exercisePath; + + @Before + public void setUp() throws URISyntaxException { + exercisePath = + Paths.get( + AdminCommadTest.class + .getClassLoader() + .getResource("dummy-courses/admin_arith_funcs") + .toURI()); + io = new TestIo(); + mockCore = mock(TmcCore.class); + mockLangs = mock(TaskExecutor.class); + ctx = new CliContext(io, mockCore, null, mockLangs); + app = new Application(ctx); + } + +// @Test +// public void printsAnErrorMessageIfGivenCourseName() { +// String[] args = {"admin", "course"}; +// app.run(args); +// io.assertContains("Use in the course directory"); +// } + + @Test + public void testScanExercise() throws NoLanguagePluginFoundException { + final String outputPath = exercisePath + "/checkstyle.txt"; + + when(mockLangs.scanExercise(exercisePath, "admin_arith_funcs")) + .thenReturn( + Optional.of( + new ExerciseDesc( + "Name", ImmutableList.copyOf(new ArrayList())))); + + String[] args = { + "admin", "scan-exercise", "--exercise", exercisePath.toString(), "--output", outputPath + }; + app.run(args); + + verify(mockLangs).scanExercise(exercisePath, "admin_arith_funcs"); + io.assertContains( + "Exercises scanned successfully, results can be found in " + + outputPath + + "\n"); +// assertTrue( +// "Error output should be clean, but it was " + mio.getSysErr(), +// mio.getSysErr().isEmpty()); + } + + @Test + public void testRunTests() throws NoLanguagePluginFoundException { + final String outputPath = exercisePath + "/results.txt"; + + String[] args = { + "admin", "run-tests", "--exercise", exercisePath.toString(), "--output", outputPath + }; + app.run(args); + + verify(mockLangs).runTests(exercisePath); + io.assertContains("Test results can be found in " + outputPath + "\n"); +// assertTrue( +// "Error output should be clean, but it was " + mio.getSysErr(), +// mio.getSysErr().isEmpty()); + } + + @Test + public void testRunCheckCodeStyle() throws NoLanguagePluginFoundException { + final String outputPath = exercisePath + "/exercises.txt"; + + String[] args = { + "admin", "checkstyle", + "--exercise", exercisePath.toString(), + "--output", outputPath, + "--locale", "en" + }; + app.run(args); + + verify(mockLangs).runCheckCodeStyle(exercisePath, new Locale("en")); + io.assertContains("Codestyle report can be found at " + outputPath + "\n"); +// assertTrue( +// "Error output should be clean, but it was " + mio.getSysErr(), +// mio.getSysErr().isEmpty()); + } + + @Test + public void testPrepareStub() { + + String[] args = {"prepare-stub", "--exercise", exercisePath.toString()}; + app.run(args); + + // Mockito.verify(executor).prepareStub(stubPath); + } + + @Test + public void testPrepareSolution() { + + String[] args = {"admin", "prepareSolution", "--exercise", exercisePath.toString()}; + app.run(args); + + // Why is this commented out? + // Mockito.verify(executor).prepareSolution(solutionPath); + } +} diff --git a/src/test/resources/dummy-courses/admin_arith_funcs/build.xml b/src/test/resources/dummy-courses/admin_arith_funcs/build.xml new file mode 100644 index 00000000..dbd84a08 --- /dev/null +++ b/src/test/resources/dummy-courses/admin_arith_funcs/build.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + Builds, tests, and runs the project admin_arith_funcs. + + + diff --git a/src/test/resources/dummy-courses/admin_arith_funcs/manifest.mf b/src/test/resources/dummy-courses/admin_arith_funcs/manifest.mf new file mode 100644 index 00000000..328e8e5b --- /dev/null +++ b/src/test/resources/dummy-courses/admin_arith_funcs/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + diff --git a/src/test/resources/dummy-courses/admin_arith_funcs/nbproject/build-impl.xml b/src/test/resources/dummy-courses/admin_arith_funcs/nbproject/build-impl.xml new file mode 100644 index 00000000..f3ad890d --- /dev/null +++ b/src/test/resources/dummy-courses/admin_arith_funcs/nbproject/build-impl.xml @@ -0,0 +1,1042 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + Must select one file in the IDE or set profile.class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/dummy-courses/admin_arith_funcs/nbproject/genfiles.properties b/src/test/resources/dummy-courses/admin_arith_funcs/nbproject/genfiles.properties new file mode 100644 index 00000000..3e823e9f --- /dev/null +++ b/src/test/resources/dummy-courses/admin_arith_funcs/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=c2a9ffde +build.xml.script.CRC32=8bda9acc +build.xml.stylesheet.CRC32=28e38971@1.44.1.45 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=c2a9ffde +nbproject/build-impl.xml.script.CRC32=f0fe6139 +nbproject/build-impl.xml.stylesheet.CRC32=0ae3a408@1.44.1.45 diff --git a/src/test/resources/dummy-courses/admin_arith_funcs/nbproject/project.properties b/src/test/resources/dummy-courses/admin_arith_funcs/nbproject/project.properties new file mode 100644 index 00000000..4690c713 --- /dev/null +++ b/src/test/resources/dummy-courses/admin_arith_funcs/nbproject/project.properties @@ -0,0 +1,86 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=admin_arith_funcs +application.vendor= +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/admin_arith_funcs.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.edu-test-utils-0.4.1.jar=lib/edu-test-utils-0.4.1.jar +file.reference.junit-4.10.jar=lib/junit-4.10.jar +includes=** +jar.archive.disabled=${jnlp.enabled} +jar.compress=false +jar.index=${jnlp.enabled} +javac.classpath= +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.6 +javac.target=1.6 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${file.reference.junit-4.10.jar}:\ + ${file.reference.edu-test-utils-0.4.1.jar} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +jnlp.codebase.type=no.codebase +jnlp.descriptor=application +jnlp.enabled=false +jnlp.mixed.code=default +jnlp.offline-allowed=false +jnlp.signed=false +jnlp.signing= +jnlp.signing.alias= +jnlp.signing.keystore= +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/src/test/resources/dummy-courses/admin_arith_funcs/nbproject/project.xml b/src/test/resources/dummy-courses/admin_arith_funcs/nbproject/project.xml new file mode 100644 index 00000000..e9a3bc69 --- /dev/null +++ b/src/test/resources/dummy-courses/admin_arith_funcs/nbproject/project.xml @@ -0,0 +1,15 @@ + + + org.netbeans.modules.java.j2seproject + + + admin_arith_funcs + + + + + + + + + diff --git a/src/test/resources/dummy-courses/admin_arith_funcs/src/Arith.java b/src/test/resources/dummy-courses/admin_arith_funcs/src/Arith.java new file mode 100644 index 00000000..54f441a8 --- /dev/null +++ b/src/test/resources/dummy-courses/admin_arith_funcs/src/Arith.java @@ -0,0 +1,18 @@ + +public class Arith { + public static int add(int a, int b) { + return 0; + } + + public static int sub(int a, int b) { + return 0; + } + + public static int mul(int a, int b) { + return 0; + } + + public static int div(int a, int b) { + return 0; + } +} diff --git a/src/test/resources/dummy-courses/admin_arith_funcs/test/ArithTest.java b/src/test/resources/dummy-courses/admin_arith_funcs/test/ArithTest.java new file mode 100644 index 00000000..afc5519b --- /dev/null +++ b/src/test/resources/dummy-courses/admin_arith_funcs/test/ArithTest.java @@ -0,0 +1,31 @@ + +import fi.helsinki.cs.tmc.edutestutils.Points; +import org.junit.Test; +import static org.junit.Assert.*; + +public class ArithTest { + @Test + @Points("arith-funcs") + public void testAdd() { + assertEquals(7, Arith.add(3, 4)); + } + + @Test + @Points("arith-funcs") + public void testSub() { + assertEquals(-1, Arith.sub(3, 4)); + } + + @Test + @Points("arith-funcs") + public void testMul() { + assertEquals(12, Arith.mul(3, 4)); + } + + @Test + @Points("arith-funcs") + public void testDiv() { + assertEquals(0, Arith.div(3, 4)); + assertEquals(3, Arith.div(7, 2)); + } +}