From 6c0fd7d0e2464a4b3f28a2b5ba5912651000ddb8 Mon Sep 17 00:00:00 2001 From: Aleksi Salmela Date: Sat, 9 Jul 2016 14:17:00 +0300 Subject: [PATCH 01/16] Rename some of the packages. --- pom.xml | 2 +- .../fi/helsinki/cs/tmc/cli/Application.java | 9 ++++---- .../cli/{tmcstuff => backend}/CourseInfo.java | 2 +- .../{tmcstuff => backend}/CourseInfoIo.java | 2 +- .../cli/{tmcstuff => backend}/Settings.java | 6 +++-- .../{tmcstuff => backend}/SettingsHolder.java | 2 +- .../cli/{tmcstuff => backend}/SettingsIo.java | 7 +++--- .../cli/{tmcstuff => backend}/TmcUtil.java | 5 ++-- .../cs/tmc/cli/command/DocumentCommand.java | 4 ++-- .../cli/command/DownloadExercisesCommand.java | 23 ++++++++++--------- .../cs/tmc/cli/command/HelpCommand.java | 6 ++--- ...ourseInfoCommand.java => InfoCommand.java} | 22 +++++++++--------- .../tmc/cli/command/ListCoursesCommand.java | 12 +++++----- .../tmc/cli/command/ListExercisesCommand.java | 13 +++++------ .../cs/tmc/cli/command/LoginCommand.java | 14 +++++------ .../cs/tmc/cli/command/LogoutCommand.java | 6 ++--- .../cs/tmc/cli/command/PasteCommand.java | 13 ++++++----- .../cs/tmc/cli/command/PropertiesCommand.java | 6 ++--- .../cs/tmc/cli/command/RunTestsCommand.java | 16 ++++++------- .../tmc/cli/command/ShellHelperCommand.java | 6 ++--- .../cs/tmc/cli/command/SubmitCommand.java | 21 +++++++++-------- .../cs/tmc/cli/command/UpdateCommand.java | 19 ++++++++------- .../{command => }/core/AbstractCommand.java | 6 ++--- .../cs/tmc/cli/{ => core}/CliContext.java | 14 ++++++----- .../tmc/cli/{command => }/core/Command.java | 2 +- .../core/CommandAnnotationProcessor.java | 13 ++++------- .../{command => }/core/CommandFactory.java | 7 ++---- ...Observer.java => CliProgressObserver.java} | 10 ++++---- .../cs/tmc/cli/{tmcstuff => io}/WorkDir.java | 5 ++-- .../{tmcstuff => shared}/ExerciseUpdater.java | 12 ++++++---- .../{tmcstuff => shared}/FeedbackHandler.java | 6 +++-- .../tmc/cli/{io => shared}/ResultPrinter.java | 8 +++++-- .../{TmcCliUpdater.java => AutoUpdater.java} | 12 +++++----- .../helsinki/cs/tmc/cli/ApplicationTest.java | 16 ++++++------- .../CourseInfoIoTest.java | 2 +- .../{tmcstuff => backend}/CourseInfoTest.java | 2 +- .../{tmcstuff => backend}/SettingsIoTest.java | 2 +- .../{tmcstuff => backend}/SettingsTest.java | 2 +- .../{tmcstuff => backend}/TmcUtilTest.java | 11 +++++---- .../tmc/cli/command/DocumentCommandTest.java | 2 +- .../command/DownloadExercisesCommandTest.java | 10 ++++---- .../cs/tmc/cli/command/HelpCommandTest.java | 2 +- ...oCommandTest.java => InfoCommandTest.java} | 9 ++++---- .../cli/command/ListCoursesCommandTest.java | 9 ++++---- .../cli/command/ListExercisesCommandTest.java | 7 +++--- .../cs/tmc/cli/command/LoginCommandTest.java | 11 +++++---- .../cs/tmc/cli/command/LogoutCommandTest.java | 4 ++-- .../cs/tmc/cli/command/PasteCommandTest.java | 11 +++++---- .../cli/command/PropertiesCommandTest.java | 2 +- .../tmc/cli/command/RunTestsCommandTest.java | 6 ++--- .../cli/command/ShellHelperCommandTest.java | 2 +- .../cs/tmc/cli/command/SubmitCommandTest.java | 10 ++++---- .../cs/tmc/cli/command/UpdateCommandTest.java | 13 ++++++----- .../core/AbstractCommandTest.java | 6 ++--- .../cs/tmc/cli/{ => core}/CliContextTest.java | 13 ++++++----- .../core/CommandAnnotationProcessorTest.java | 6 ++--- .../core/CommandFactoryTest.java | 3 +-- ...Test.java => CliProgressObserverTest.java} | 16 ++++++------- .../tmc/cli/{tmcstuff => io}/WorkDirTest.java | 6 ++++- .../ExerciseUpdaterTest.java | 5 ++-- .../FeedbackHandlerTest.java | 5 ++-- .../cli/{io => shared}/ResultPrinterTest.java | 5 +++- ...iUpdaterTest.java => AutoUpdaterTest.java} | 21 ++++++++--------- 63 files changed, 277 insertions(+), 253 deletions(-) rename src/main/java/fi/helsinki/cs/tmc/cli/{tmcstuff => backend}/CourseInfo.java (99%) rename src/main/java/fi/helsinki/cs/tmc/cli/{tmcstuff => backend}/CourseInfoIo.java (97%) rename src/main/java/fi/helsinki/cs/tmc/cli/{tmcstuff => backend}/Settings.java (97%) rename src/main/java/fi/helsinki/cs/tmc/cli/{tmcstuff => backend}/SettingsHolder.java (98%) rename src/main/java/fi/helsinki/cs/tmc/cli/{tmcstuff => backend}/SettingsIo.java (99%) rename src/main/java/fi/helsinki/cs/tmc/cli/{tmcstuff => backend}/TmcUtil.java (98%) rename src/main/java/fi/helsinki/cs/tmc/cli/command/{CourseInfoCommand.java => InfoCommand.java} (96%) rename src/main/java/fi/helsinki/cs/tmc/cli/{command => }/core/AbstractCommand.java (94%) rename src/main/java/fi/helsinki/cs/tmc/cli/{ => core}/CliContext.java (95%) rename src/main/java/fi/helsinki/cs/tmc/cli/{command => }/core/Command.java (89%) rename src/main/java/fi/helsinki/cs/tmc/cli/{command => }/core/CommandAnnotationProcessor.java (89%) rename src/main/java/fi/helsinki/cs/tmc/cli/{command => }/core/CommandFactory.java (94%) rename src/main/java/fi/helsinki/cs/tmc/cli/io/{TmcCliProgressObserver.java => CliProgressObserver.java} (94%) rename src/main/java/fi/helsinki/cs/tmc/cli/{tmcstuff => io}/WorkDir.java (98%) rename src/main/java/fi/helsinki/cs/tmc/cli/{tmcstuff => shared}/ExerciseUpdater.java (89%) rename src/main/java/fi/helsinki/cs/tmc/cli/{tmcstuff => shared}/FeedbackHandler.java (95%) rename src/main/java/fi/helsinki/cs/tmc/cli/{io => shared}/ResultPrinter.java (97%) rename src/main/java/fi/helsinki/cs/tmc/cli/updater/{TmcCliUpdater.java => AutoUpdater.java} (94%) rename src/test/java/fi/helsinki/cs/tmc/cli/{tmcstuff => backend}/CourseInfoIoTest.java (97%) rename src/test/java/fi/helsinki/cs/tmc/cli/{tmcstuff => backend}/CourseInfoTest.java (98%) rename src/test/java/fi/helsinki/cs/tmc/cli/{tmcstuff => backend}/SettingsIoTest.java (99%) rename src/test/java/fi/helsinki/cs/tmc/cli/{tmcstuff => backend}/SettingsTest.java (98%) rename src/test/java/fi/helsinki/cs/tmc/cli/{tmcstuff => backend}/TmcUtilTest.java (98%) rename src/test/java/fi/helsinki/cs/tmc/cli/command/{CourseInfoCommandTest.java => InfoCommandTest.java} (97%) rename src/test/java/fi/helsinki/cs/tmc/cli/{command => }/core/AbstractCommandTest.java (93%) rename src/test/java/fi/helsinki/cs/tmc/cli/{ => core}/CliContextTest.java (94%) rename src/test/java/fi/helsinki/cs/tmc/cli/{command => }/core/CommandAnnotationProcessorTest.java (99%) rename src/test/java/fi/helsinki/cs/tmc/cli/{command => }/core/CommandFactoryTest.java (96%) rename src/test/java/fi/helsinki/cs/tmc/cli/io/{TmcCliProgressObserverTest.java => CliProgressObserverTest.java} (83%) rename src/test/java/fi/helsinki/cs/tmc/cli/{tmcstuff => io}/WorkDirTest.java (98%) rename src/test/java/fi/helsinki/cs/tmc/cli/{tmcstuff => shared}/ExerciseUpdaterTest.java (95%) rename src/test/java/fi/helsinki/cs/tmc/cli/{tmcstuff => shared}/FeedbackHandlerTest.java (96%) rename src/test/java/fi/helsinki/cs/tmc/cli/{io => shared}/ResultPrinterTest.java (98%) rename src/test/java/fi/helsinki/cs/tmc/cli/updater/{TmcCliUpdaterTest.java => AutoUpdaterTest.java} (88%) diff --git a/pom.xml b/pom.xml index 48a52b74..644a5637 100644 --- a/pom.xml +++ b/pom.xml @@ -140,7 +140,7 @@ - fi.helsinki.cs.tmc.cli.command.core.CommandAnnotationProcessor + fi.helsinki.cs.tmc.cli.core.CommandAnnotationProcessor true diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/Application.java b/src/main/java/fi/helsinki/cs/tmc/cli/Application.java index 3093a098..8f2b506d 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/Application.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/Application.java @@ -1,13 +1,14 @@ package fi.helsinki.cs.tmc.cli; -import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand; -import fi.helsinki.cs.tmc.cli.command.core.CommandFactory; +import fi.helsinki.cs.tmc.cli.core.AbstractCommand; +import fi.helsinki.cs.tmc.cli.core.CliContext; +import fi.helsinki.cs.tmc.cli.core.CommandFactory; import fi.helsinki.cs.tmc.cli.io.Color; import fi.helsinki.cs.tmc.cli.io.EnvironmentUtil; import fi.helsinki.cs.tmc.cli.io.HelpGenerator; import fi.helsinki.cs.tmc.cli.io.Io; import fi.helsinki.cs.tmc.cli.io.ShutdownHandler; -import fi.helsinki.cs.tmc.cli.updater.TmcCliUpdater; +import fi.helsinki.cs.tmc.cli.updater.AutoUpdater; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.GnuParser; @@ -169,7 +170,7 @@ private boolean versionCheck() { public boolean runAutoUpdate() { Map properties = context.getProperties(); Date now = new Date(); - TmcCliUpdater update = TmcCliUpdater.createUpdater(io, + AutoUpdater update = AutoUpdater.createUpdater(io, EnvironmentUtil.getVersion(), EnvironmentUtil.isWindows()); boolean updated = update.run(); diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/CourseInfo.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfo.java similarity index 99% rename from src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/CourseInfo.java rename to src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfo.java index db74f38c..d5ea1df2 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/CourseInfo.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfo.java @@ -1,4 +1,4 @@ -package fi.helsinki.cs.tmc.cli.tmcstuff; +package fi.helsinki.cs.tmc.cli.backend; import fi.helsinki.cs.tmc.core.configuration.TmcSettings; import fi.helsinki.cs.tmc.core.domain.Course; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/CourseInfoIo.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoIo.java similarity index 97% rename from src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/CourseInfoIo.java rename to src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoIo.java index 933ade75..e6addd3a 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/CourseInfoIo.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoIo.java @@ -1,4 +1,4 @@ -package fi.helsinki.cs.tmc.cli.tmcstuff; +package fi.helsinki.cs.tmc.cli.backend; import com.google.gson.Gson; import org.slf4j.Logger; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/Settings.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/Settings.java similarity index 97% rename from src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/Settings.java rename to src/main/java/fi/helsinki/cs/tmc/cli/backend/Settings.java index 3ca4f004..3fbc975a 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/Settings.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/Settings.java @@ -1,6 +1,8 @@ -package fi.helsinki.cs.tmc.cli.tmcstuff; +package fi.helsinki.cs.tmc.cli.backend; import fi.helsinki.cs.tmc.cli.io.EnvironmentUtil; +import fi.helsinki.cs.tmc.cli.io.WorkDir; + import fi.helsinki.cs.tmc.core.configuration.TmcSettings; import fi.helsinki.cs.tmc.core.domain.Course; @@ -23,7 +25,7 @@ public Settings(String serverAddress, String username, String password) { this.username = username; this.password = password; } - + public Settings() { } diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/SettingsHolder.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsHolder.java similarity index 98% rename from src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/SettingsHolder.java rename to src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsHolder.java index aace9f3d..d83a0e7a 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/SettingsHolder.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsHolder.java @@ -1,4 +1,4 @@ -package fi.helsinki.cs.tmc.cli.tmcstuff; +package fi.helsinki.cs.tmc.cli.backend; import java.util.ArrayList; import java.util.Collections; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/SettingsIo.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java similarity index 99% rename from src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/SettingsIo.java rename to src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java index 983d9e32..772be8bd 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/SettingsIo.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java @@ -1,9 +1,8 @@ -package fi.helsinki.cs.tmc.cli.tmcstuff; +package fi.helsinki.cs.tmc.cli.backend; import fi.helsinki.cs.tmc.cli.io.EnvironmentUtil; import com.google.gson.Gson; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,11 +21,11 @@ public class SettingsIo { private static final Logger logger = LoggerFactory.getLogger(SettingsIo.class); - + // CONFIG_DIR is the sub-directory located within the system specific // configuration folder, ex. /home/user/.config/CONFIG_DIR/ public static final String CONFIG_DIR = "tmc-cli"; - + // ACCOUNTS_CONFIG is the _global_ configuration file containing all // user login information including usernames, passwords (in plain text) // and servers. Is located under CONFIG_DIR diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/TmcUtil.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java similarity index 98% rename from src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/TmcUtil.java rename to src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java index 37f50b2b..5c048280 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/TmcUtil.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java @@ -1,7 +1,8 @@ -package fi.helsinki.cs.tmc.cli.tmcstuff; +package fi.helsinki.cs.tmc.cli.backend; -import fi.helsinki.cs.tmc.cli.CliContext; +import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.io.Io; + import fi.helsinki.cs.tmc.core.TmcCore; import fi.helsinki.cs.tmc.core.commands.GetUpdatableExercises.UpdateResult; import fi.helsinki.cs.tmc.core.domain.Course; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/DocumentCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/DocumentCommand.java index e80edea5..110b1ff9 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/DocumentCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/DocumentCommand.java @@ -1,7 +1,7 @@ package fi.helsinki.cs.tmc.cli.command; -import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand; -import fi.helsinki.cs.tmc.cli.command.core.Command; +import fi.helsinki.cs.tmc.cli.core.AbstractCommand; +import fi.helsinki.cs.tmc.cli.core.Command; import fi.helsinki.cs.tmc.cli.io.Color; import fi.helsinki.cs.tmc.cli.io.EnvironmentUtil; import fi.helsinki.cs.tmc.cli.io.Io; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java index 804a988d..edbffd57 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java @@ -1,17 +1,18 @@ package fi.helsinki.cs.tmc.cli.command; -import fi.helsinki.cs.tmc.cli.CliContext; -import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand; -import fi.helsinki.cs.tmc.cli.command.core.Command; +import fi.helsinki.cs.tmc.cli.backend.CourseInfo; +import fi.helsinki.cs.tmc.cli.backend.CourseInfoIo; +import fi.helsinki.cs.tmc.cli.backend.Settings; +import fi.helsinki.cs.tmc.cli.backend.SettingsIo; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +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.CliProgressObserver; import fi.helsinki.cs.tmc.cli.io.Color; import fi.helsinki.cs.tmc.cli.io.Io; -import fi.helsinki.cs.tmc.cli.io.TmcCliProgressObserver; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfo; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfoIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.Settings; -import fi.helsinki.cs.tmc.cli.tmcstuff.SettingsIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.TmcUtil; -import fi.helsinki.cs.tmc.cli.tmcstuff.WorkDir; +import fi.helsinki.cs.tmc.cli.io.WorkDir; + import fi.helsinki.cs.tmc.core.domain.Course; import fi.helsinki.cs.tmc.core.domain.Exercise; @@ -73,7 +74,7 @@ public void run(CommandLine args, Io io) { Color.AnsiColor color1 = ctx.getApp().getColor("progressbar-left"); Color.AnsiColor color2 = ctx.getApp().getColor("progressbar-right"); - TmcCliProgressObserver progobs = new TmcCliProgressObserver(io, color1, color2); + CliProgressObserver progobs = new CliProgressObserver(io, color1, color2); List exercises = TmcUtil.downloadExercises(ctx, filtered, progobs); if (exercises == null) { diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/HelpCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/HelpCommand.java index 429c7e60..5580cc7d 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/HelpCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/HelpCommand.java @@ -1,9 +1,9 @@ package fi.helsinki.cs.tmc.cli.command; import fi.helsinki.cs.tmc.cli.Application; -import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand; -import fi.helsinki.cs.tmc.cli.command.core.Command; -import fi.helsinki.cs.tmc.cli.command.core.CommandFactory; +import fi.helsinki.cs.tmc.cli.core.AbstractCommand; +import fi.helsinki.cs.tmc.cli.core.Command; +import fi.helsinki.cs.tmc.cli.core.CommandFactory; import fi.helsinki.cs.tmc.cli.io.Io; import org.apache.commons.cli.CommandLine; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/CourseInfoCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java similarity index 96% rename from src/main/java/fi/helsinki/cs/tmc/cli/command/CourseInfoCommand.java rename to src/main/java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java index 53ebe9a0..5e324c39 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/CourseInfoCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java @@ -5,14 +5,14 @@ import static fi.helsinki.cs.tmc.cli.io.Color.AnsiColor.ANSI_PURPLE; import static fi.helsinki.cs.tmc.cli.io.Color.AnsiColor.ANSI_RED; -import fi.helsinki.cs.tmc.cli.CliContext; -import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand; -import fi.helsinki.cs.tmc.cli.command.core.Command; +import fi.helsinki.cs.tmc.cli.backend.CourseInfo; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +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.Color; import fi.helsinki.cs.tmc.cli.io.Io; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfo; -import fi.helsinki.cs.tmc.cli.tmcstuff.TmcUtil; -import fi.helsinki.cs.tmc.cli.tmcstuff.WorkDir; +import fi.helsinki.cs.tmc.cli.io.WorkDir; import fi.helsinki.cs.tmc.core.domain.Course; import fi.helsinki.cs.tmc.core.domain.Exercise; @@ -24,7 +24,7 @@ import java.util.List; @Command(name = "info", desc = "Show info about the current directory") -public class CourseInfoCommand extends AbstractCommand { +public class InfoCommand extends AbstractCommand { private Course course; private Exercise exercise; @@ -134,14 +134,14 @@ private void printCourse(boolean showAll) { } printExercises(showAll); } - + private void printCourseShort() { io.println("Course name: " + course.getName()); io.println("Number of available exercises: " + course.getExercises().size()); io.println("Number of completed exercises: " + completedExercises()); io.println("Number of locked exercises: " + course.getUnlockables().size()); } - + private void printCourseDetails() { io.println("Unlockables:" + course.getUnlockables().toString()); io.println("Course id: " + course.getId()); @@ -202,7 +202,7 @@ private void printExercises(boolean showAll) { } } } - + private int completedExercises() { int completed = 0; for (Exercise exercise : course.getExercises()) { @@ -212,7 +212,7 @@ private int completedExercises() { } return completed; } - + private void printExercise(Exercise exercise) { io.println(" Exercise name: " + exercise.getName()); io.println(" Exercise id: " + exercise.getId()); diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java index dd3cf4b3..c78f4838 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java @@ -1,13 +1,13 @@ package fi.helsinki.cs.tmc.cli.command; -import fi.helsinki.cs.tmc.cli.CliContext; -import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand; -import fi.helsinki.cs.tmc.cli.command.core.Command; +import fi.helsinki.cs.tmc.cli.backend.Settings; +import fi.helsinki.cs.tmc.cli.backend.SettingsIo; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +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.Color; import fi.helsinki.cs.tmc.cli.io.Io; -import fi.helsinki.cs.tmc.cli.tmcstuff.Settings; -import fi.helsinki.cs.tmc.cli.tmcstuff.SettingsIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.TmcUtil; import fi.helsinki.cs.tmc.core.domain.Course; 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 a01558ff..35cd2041 100755 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/ListExercisesCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/ListExercisesCommand.java @@ -1,16 +1,15 @@ package fi.helsinki.cs.tmc.cli.command; -import fi.helsinki.cs.tmc.cli.CliContext; -import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand; -import fi.helsinki.cs.tmc.cli.command.core.Command; +import fi.helsinki.cs.tmc.cli.backend.CourseInfo; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +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.Color; 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.tmcstuff.CourseInfo; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfoIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.TmcUtil; -import fi.helsinki.cs.tmc.cli.tmcstuff.WorkDir; +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/LoginCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java index 15286f23..660d9791 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java @@ -1,13 +1,13 @@ package fi.helsinki.cs.tmc.cli.command; -import fi.helsinki.cs.tmc.cli.CliContext; -import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand; -import fi.helsinki.cs.tmc.cli.command.core.Command; +import fi.helsinki.cs.tmc.cli.backend.CourseInfo; +import fi.helsinki.cs.tmc.cli.backend.Settings; +import fi.helsinki.cs.tmc.cli.backend.SettingsIo; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +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.cli.tmcstuff.CourseInfo; -import fi.helsinki.cs.tmc.cli.tmcstuff.Settings; -import fi.helsinki.cs.tmc.cli.tmcstuff.SettingsIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.TmcUtil; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Options; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/LogoutCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/LogoutCommand.java index 09ee7908..8c77798f 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/LogoutCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/LogoutCommand.java @@ -1,9 +1,9 @@ package fi.helsinki.cs.tmc.cli.command; -import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand; -import fi.helsinki.cs.tmc.cli.command.core.Command; +import fi.helsinki.cs.tmc.cli.backend.SettingsIo; +import fi.helsinki.cs.tmc.cli.core.AbstractCommand; +import fi.helsinki.cs.tmc.cli.core.Command; import fi.helsinki.cs.tmc.cli.io.Io; -import fi.helsinki.cs.tmc.cli.tmcstuff.SettingsIo; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Options; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/PasteCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/PasteCommand.java index b31279aa..446f681f 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/PasteCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/PasteCommand.java @@ -1,13 +1,14 @@ package fi.helsinki.cs.tmc.cli.command; -import fi.helsinki.cs.tmc.cli.CliContext; -import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand; -import fi.helsinki.cs.tmc.cli.command.core.Command; +import fi.helsinki.cs.tmc.cli.backend.CourseInfo; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +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.ExternalsUtil; import fi.helsinki.cs.tmc.cli.io.Io; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfo; -import fi.helsinki.cs.tmc.cli.tmcstuff.TmcUtil; -import fi.helsinki.cs.tmc.cli.tmcstuff.WorkDir; +import fi.helsinki.cs.tmc.cli.io.WorkDir; + import fi.helsinki.cs.tmc.core.domain.Exercise; import org.apache.commons.cli.CommandLine; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/PropertiesCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/PropertiesCommand.java index d777300a..eb6a7918 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/PropertiesCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/PropertiesCommand.java @@ -1,8 +1,8 @@ package fi.helsinki.cs.tmc.cli.command; -import fi.helsinki.cs.tmc.cli.CliContext; -import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand; -import fi.helsinki.cs.tmc.cli.command.core.Command; +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; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/RunTestsCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/RunTestsCommand.java index b3946809..3ae42d23 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/RunTestsCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/RunTestsCommand.java @@ -1,15 +1,15 @@ package fi.helsinki.cs.tmc.cli.command; -import fi.helsinki.cs.tmc.cli.CliContext; -import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand; -import fi.helsinki.cs.tmc.cli.command.core.Command; +import fi.helsinki.cs.tmc.cli.backend.CourseInfo; +import fi.helsinki.cs.tmc.cli.backend.CourseInfoIo; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +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.Color; import fi.helsinki.cs.tmc.cli.io.Io; -import fi.helsinki.cs.tmc.cli.io.ResultPrinter; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfo; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfoIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.TmcUtil; -import fi.helsinki.cs.tmc.cli.tmcstuff.WorkDir; +import fi.helsinki.cs.tmc.cli.io.WorkDir; +import fi.helsinki.cs.tmc.cli.shared.ResultPrinter; import fi.helsinki.cs.tmc.core.domain.Exercise; import fi.helsinki.cs.tmc.langs.abstraction.ValidationResult; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/ShellHelperCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/ShellHelperCommand.java index fcef29e3..dbbd0035 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/ShellHelperCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/ShellHelperCommand.java @@ -1,8 +1,8 @@ package fi.helsinki.cs.tmc.cli.command; -import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand; -import fi.helsinki.cs.tmc.cli.command.core.Command; -import fi.helsinki.cs.tmc.cli.command.core.CommandFactory; +import fi.helsinki.cs.tmc.cli.core.AbstractCommand; +import fi.helsinki.cs.tmc.cli.core.Command; +import fi.helsinki.cs.tmc.cli.core.CommandFactory; import fi.helsinki.cs.tmc.cli.io.Io; import org.apache.commons.cli.CommandLine; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/SubmitCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/SubmitCommand.java index 276918e9..a98ea9f6 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/SubmitCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/SubmitCommand.java @@ -1,17 +1,18 @@ package fi.helsinki.cs.tmc.cli.command; -import fi.helsinki.cs.tmc.cli.CliContext; -import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand; -import fi.helsinki.cs.tmc.cli.command.core.Command; +import fi.helsinki.cs.tmc.cli.backend.CourseInfo; +import fi.helsinki.cs.tmc.cli.backend.CourseInfoIo; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +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.Color; import fi.helsinki.cs.tmc.cli.io.Io; -import fi.helsinki.cs.tmc.cli.io.ResultPrinter; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfo; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfoIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.ExerciseUpdater; -import fi.helsinki.cs.tmc.cli.tmcstuff.FeedbackHandler; -import fi.helsinki.cs.tmc.cli.tmcstuff.TmcUtil; -import fi.helsinki.cs.tmc.cli.tmcstuff.WorkDir; +import fi.helsinki.cs.tmc.cli.io.WorkDir; +import fi.helsinki.cs.tmc.cli.shared.ExerciseUpdater; +import fi.helsinki.cs.tmc.cli.shared.FeedbackHandler; +import fi.helsinki.cs.tmc.cli.shared.ResultPrinter; + import fi.helsinki.cs.tmc.core.domain.Course; import fi.helsinki.cs.tmc.core.domain.Exercise; import fi.helsinki.cs.tmc.core.domain.submission.FeedbackQuestion; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/UpdateCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/UpdateCommand.java index e1862b89..cc1114fe 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/UpdateCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/UpdateCommand.java @@ -1,16 +1,15 @@ package fi.helsinki.cs.tmc.cli.command; -import fi.helsinki.cs.tmc.cli.CliContext; -import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand; -import fi.helsinki.cs.tmc.cli.command.core.Command; +import fi.helsinki.cs.tmc.cli.backend.CourseInfo; +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.CliProgressObserver; import fi.helsinki.cs.tmc.cli.io.Color; import fi.helsinki.cs.tmc.cli.io.Io; -import fi.helsinki.cs.tmc.cli.io.TmcCliProgressObserver; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfo; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfoIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.ExerciseUpdater; -import fi.helsinki.cs.tmc.cli.tmcstuff.WorkDir; -import fi.helsinki.cs.tmc.core.TmcCore; +import fi.helsinki.cs.tmc.cli.io.WorkDir; +import fi.helsinki.cs.tmc.cli.shared.ExerciseUpdater; + import fi.helsinki.cs.tmc.core.domain.Exercise; import org.apache.commons.cli.CommandLine; @@ -71,7 +70,7 @@ private void updateExercises(CourseInfo info, Path configFile) { Color.AnsiColor color1 = getContext().getApp().getColor("progressbar-left"); Color.AnsiColor color2 = getContext().getApp().getColor("progressbar-right"); List downloaded = exerciseUpdater.downloadUpdates( - new TmcCliProgressObserver(io, color1, color2)); + new CliProgressObserver(io, color1, color2)); if (downloaded.isEmpty()) { io.println("Failed to download exercises"); return; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/core/AbstractCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/core/AbstractCommand.java similarity index 94% rename from src/main/java/fi/helsinki/cs/tmc/cli/command/core/AbstractCommand.java rename to src/main/java/fi/helsinki/cs/tmc/cli/core/AbstractCommand.java index 810025ef..78118a90 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/core/AbstractCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/core/AbstractCommand.java @@ -1,7 +1,5 @@ -package fi.helsinki.cs.tmc.cli.command.core; +package fi.helsinki.cs.tmc.cli.core; -import fi.helsinki.cs.tmc.cli.CliContext; -import fi.helsinki.cs.tmc.cli.command.LoginCommand; import fi.helsinki.cs.tmc.cli.io.HelpGenerator; import fi.helsinki.cs.tmc.cli.io.Io; @@ -14,7 +12,7 @@ import org.slf4j.LoggerFactory; public abstract class AbstractCommand { - private static final Logger logger = LoggerFactory.getLogger(LoginCommand.class); + private static final Logger logger = LoggerFactory.getLogger(AbstractCommand.class); private CliContext context; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/CliContext.java b/src/main/java/fi/helsinki/cs/tmc/cli/core/CliContext.java similarity index 95% rename from src/main/java/fi/helsinki/cs/tmc/cli/CliContext.java rename to src/main/java/fi/helsinki/cs/tmc/cli/core/CliContext.java index 4cda3ba0..dc6dca52 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/CliContext.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/core/CliContext.java @@ -1,12 +1,14 @@ -package fi.helsinki.cs.tmc.cli; +package fi.helsinki.cs.tmc.cli.core; +import fi.helsinki.cs.tmc.cli.Application; +import fi.helsinki.cs.tmc.cli.backend.CourseInfo; +import fi.helsinki.cs.tmc.cli.backend.CourseInfoIo; +import fi.helsinki.cs.tmc.cli.backend.Settings; +import fi.helsinki.cs.tmc.cli.backend.SettingsIo; import fi.helsinki.cs.tmc.cli.io.Io; import fi.helsinki.cs.tmc.cli.io.TerminalIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfo; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfoIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.Settings; -import fi.helsinki.cs.tmc.cli.tmcstuff.SettingsIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.WorkDir; +import fi.helsinki.cs.tmc.cli.io.WorkDir; + import fi.helsinki.cs.tmc.core.TmcCore; import fi.helsinki.cs.tmc.core.domain.Course; import fi.helsinki.cs.tmc.langs.util.TaskExecutor; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/core/Command.java b/src/main/java/fi/helsinki/cs/tmc/cli/core/Command.java similarity index 89% rename from src/main/java/fi/helsinki/cs/tmc/cli/command/core/Command.java rename to src/main/java/fi/helsinki/cs/tmc/cli/core/Command.java index 192a085f..38401e75 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/core/Command.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/core/Command.java @@ -1,4 +1,4 @@ -package fi.helsinki.cs.tmc.cli.command.core; +package fi.helsinki.cs.tmc.cli.core; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/core/CommandAnnotationProcessor.java b/src/main/java/fi/helsinki/cs/tmc/cli/core/CommandAnnotationProcessor.java similarity index 89% rename from src/main/java/fi/helsinki/cs/tmc/cli/command/core/CommandAnnotationProcessor.java rename to src/main/java/fi/helsinki/cs/tmc/cli/core/CommandAnnotationProcessor.java index 2dd69df7..0817c8f3 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/core/CommandAnnotationProcessor.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/core/CommandAnnotationProcessor.java @@ -1,4 +1,4 @@ -package fi.helsinki.cs.tmc.cli.command.core; +package fi.helsinki.cs.tmc.cli.core; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -12,8 +12,6 @@ import java.util.Set; import javax.annotation.processing.AbstractProcessor; -import javax.annotation.processing.Messager; -import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedSourceVersion; @@ -21,16 +19,15 @@ import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; -import javax.tools.Diagnostic; import javax.tools.JavaFileObject; @SupportedSourceVersion(SourceVersion.RELEASE_6) -@SupportedAnnotationTypes({"fi.helsinki.cs.tmc.cli.command.Command", "java.lang.Override"}) +@SupportedAnnotationTypes({"fi.helsinki.cs.tmc.cli.core.Command"}) public class CommandAnnotationProcessor extends AbstractProcessor { private static final Logger logger = LoggerFactory.getLogger(CommandAnnotationProcessor.class); private static final String CLASS_NAME = "CommandList"; - private static final String PACKAGE_NAME = "fi.helsinki.cs.tmc.cli.command.core"; + private static final String PACKAGE_NAME = "fi.helsinki.cs.tmc.cli.core"; private static final String TAB = " "; private void generateSourceFile(Map map) throws IOException { @@ -77,8 +74,8 @@ public boolean process(Set annotations, RoundEnvironment return false; } Command command = elem.getAnnotation(Command.class); - logger.info("element with annotation: " + elem.toString()); - logger.info("element name with annotation: " + elem.getClass().getCanonicalName()); + logger.info("Element with annotation: " + elem.toString()); + logger.info("Element name with annotation: " + elem.getClass().getCanonicalName()); TypeElement classElement = (TypeElement) elem; map.put(command.name(), processingEnv.getElementUtils() diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/core/CommandFactory.java b/src/main/java/fi/helsinki/cs/tmc/cli/core/CommandFactory.java similarity index 94% rename from src/main/java/fi/helsinki/cs/tmc/cli/command/core/CommandFactory.java rename to src/main/java/fi/helsinki/cs/tmc/cli/core/CommandFactory.java index bbaa5710..ce28aeb1 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/core/CommandFactory.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/core/CommandFactory.java @@ -1,6 +1,4 @@ -package fi.helsinki.cs.tmc.cli.command.core; - -import fi.helsinki.cs.tmc.cli.CliContext; +package fi.helsinki.cs.tmc.cli.core; import org.slf4j.LoggerFactory; @@ -12,7 +10,6 @@ /** * Class used for creating new instances of commands. - * TODO make this class completely static. */ public class CommandFactory { @@ -25,7 +22,7 @@ public class CommandFactory { * class. */ try { - Class.forName("fi.helsinki.cs.tmc.cli.command.core.CommandList"); + Class.forName("fi.helsinki.cs.tmc.cli.core.CommandList"); } catch (ClassNotFoundException ex) { System.out.println("Fail " + ex); } diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/io/TmcCliProgressObserver.java b/src/main/java/fi/helsinki/cs/tmc/cli/io/CliProgressObserver.java similarity index 94% rename from src/main/java/fi/helsinki/cs/tmc/cli/io/TmcCliProgressObserver.java rename to src/main/java/fi/helsinki/cs/tmc/cli/io/CliProgressObserver.java index 1cbbbf75..dacc6dc9 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/io/TmcCliProgressObserver.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/io/CliProgressObserver.java @@ -2,7 +2,7 @@ import fi.helsinki.cs.tmc.core.domain.ProgressObserver; -public class TmcCliProgressObserver extends ProgressObserver { +public class CliProgressObserver extends ProgressObserver { protected static final char PIPCHAR = '█'; protected static final char EMPTYCHAR = '░'; protected static final char BARLEFT = '['; @@ -16,15 +16,15 @@ public class TmcCliProgressObserver extends ProgressObserver { protected String lastMessage; protected Boolean hasProgressBar; - public TmcCliProgressObserver() { + public CliProgressObserver() { this(new TerminalIo(System.in)); } - public TmcCliProgressObserver(Io io) { + public CliProgressObserver(Io io) { this(io, Color.AnsiColor.ANSI_CYAN, Color.AnsiColor.ANSI_CYAN); } - public TmcCliProgressObserver(Io io, Color.AnsiColor color1, Color.AnsiColor color2) { + public CliProgressObserver(Io io, Color.AnsiColor color1, Color.AnsiColor color2) { this.hasProgressBar = false; this.io = io; this.maxline = EnvironmentUtil.getTerminalWidth(); @@ -142,7 +142,7 @@ protected static String percentage(double progress) { public static String getPassedTestsBar(int passed, int total, Color.AnsiColor color1, Color.AnsiColor color2) { - return TmcCliProgressObserver.progressBar( + return CliProgressObserver.progressBar( (double) passed / total, EnvironmentUtil.getTerminalWidth(), color1, color2, diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/WorkDir.java b/src/main/java/fi/helsinki/cs/tmc/cli/io/WorkDir.java similarity index 98% rename from src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/WorkDir.java rename to src/main/java/fi/helsinki/cs/tmc/cli/io/WorkDir.java index 71ab2c97..398ef04b 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/WorkDir.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/io/WorkDir.java @@ -1,5 +1,7 @@ -package fi.helsinki.cs.tmc.cli.tmcstuff; +package fi.helsinki.cs.tmc.cli.io; +import fi.helsinki.cs.tmc.cli.backend.CourseInfo; +import fi.helsinki.cs.tmc.cli.backend.CourseInfoIo; import fi.helsinki.cs.tmc.core.domain.Exercise; import java.io.File; @@ -9,7 +11,6 @@ import java.util.ArrayList; import java.util.List; -//TODO should this be in io package? public class WorkDir { // Course root directory. null if n/a. diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/ExerciseUpdater.java b/src/main/java/fi/helsinki/cs/tmc/cli/shared/ExerciseUpdater.java similarity index 89% rename from src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/ExerciseUpdater.java rename to src/main/java/fi/helsinki/cs/tmc/cli/shared/ExerciseUpdater.java index eefefea8..3e47c29a 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/ExerciseUpdater.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/shared/ExerciseUpdater.java @@ -1,7 +1,11 @@ -package fi.helsinki.cs.tmc.cli.tmcstuff; +package fi.helsinki.cs.tmc.cli.shared; + +import fi.helsinki.cs.tmc.cli.backend.CourseInfo; +import fi.helsinki.cs.tmc.cli.backend.CourseInfoIo; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +import fi.helsinki.cs.tmc.cli.core.CliContext; +import fi.helsinki.cs.tmc.cli.io.CliProgressObserver; -import fi.helsinki.cs.tmc.cli.CliContext; -import fi.helsinki.cs.tmc.cli.io.TmcCliProgressObserver; import fi.helsinki.cs.tmc.core.commands.GetUpdatableExercises.UpdateResult; import fi.helsinki.cs.tmc.core.domain.Course; import fi.helsinki.cs.tmc.core.domain.Exercise; @@ -80,7 +84,7 @@ public boolean updatesAvailable() { return newExercisesAvailable() || updatedExercisesAvailable(); } - public List downloadUpdates(TmcCliProgressObserver progobs) { + public List downloadUpdates(CliProgressObserver progobs) { List newAndUpdated = getNewAndUpdatedExercises(); for (Iterator iterator = newAndUpdated.iterator(); iterator.hasNext();) { Exercise next = iterator.next(); diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/FeedbackHandler.java b/src/main/java/fi/helsinki/cs/tmc/cli/shared/FeedbackHandler.java similarity index 95% rename from src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/FeedbackHandler.java rename to src/main/java/fi/helsinki/cs/tmc/cli/shared/FeedbackHandler.java index ec92ea5d..c730b9fe 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/FeedbackHandler.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/shared/FeedbackHandler.java @@ -1,8 +1,10 @@ -package fi.helsinki.cs.tmc.cli.tmcstuff; +package fi.helsinki.cs.tmc.cli.shared; -import fi.helsinki.cs.tmc.cli.CliContext; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.io.ExternalsUtil; import fi.helsinki.cs.tmc.cli.io.Io; + import fi.helsinki.cs.tmc.core.domain.submission.FeedbackAnswer; import fi.helsinki.cs.tmc.core.domain.submission.FeedbackQuestion; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/io/ResultPrinter.java b/src/main/java/fi/helsinki/cs/tmc/cli/shared/ResultPrinter.java similarity index 97% rename from src/main/java/fi/helsinki/cs/tmc/cli/io/ResultPrinter.java rename to src/main/java/fi/helsinki/cs/tmc/cli/shared/ResultPrinter.java index e733bf4f..f83b80e0 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/io/ResultPrinter.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/shared/ResultPrinter.java @@ -1,4 +1,8 @@ -package fi.helsinki.cs.tmc.cli.io; +package fi.helsinki.cs.tmc.cli.shared; + +import fi.helsinki.cs.tmc.cli.io.CliProgressObserver; +import fi.helsinki.cs.tmc.cli.io.Color; +import fi.helsinki.cs.tmc.cli.io.Io; import fi.helsinki.cs.tmc.core.domain.submission.SubmissionResult; import fi.helsinki.cs.tmc.langs.abstraction.Strategy; @@ -160,7 +164,7 @@ private void printResultBar(int passed, int total) { return; } io.println( - TmcCliProgressObserver.getPassedTestsBar(passed, total, passedColor, failedColor) + CliProgressObserver.getPassedTestsBar(passed, total, passedColor, failedColor) ); } diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/updater/TmcCliUpdater.java b/src/main/java/fi/helsinki/cs/tmc/cli/updater/AutoUpdater.java similarity index 94% rename from src/main/java/fi/helsinki/cs/tmc/cli/updater/TmcCliUpdater.java rename to src/main/java/fi/helsinki/cs/tmc/cli/updater/AutoUpdater.java index 23c45217..b3358c22 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/updater/TmcCliUpdater.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/updater/AutoUpdater.java @@ -20,7 +20,7 @@ import java.net.URL; import java.net.URLConnection; -public class TmcCliUpdater { +public class AutoUpdater { /** * URL to a JSON that contains information about the latest tmc-cli release. @@ -29,20 +29,20 @@ public class TmcCliUpdater { = "https://api.github.com/repos/tmc-cli/tmc-cli/releases/latest"; private static final Logger logger - = LoggerFactory.getLogger(TmcCliUpdater.class); + = LoggerFactory.getLogger(AutoUpdater.class); private final Io io; private final boolean isWindows; private final String currentVersion; - public TmcCliUpdater(Io io, String currentVersion, boolean isWindows) { + public AutoUpdater(Io io, String currentVersion, boolean isWindows) { this.io = io; this.currentVersion = currentVersion; this.isWindows = isWindows; } - public static TmcCliUpdater createUpdater(Io io, String currentVersion, boolean isWindows) { - return new TmcCliUpdater(io, currentVersion, isWindows); + public static AutoUpdater createUpdater(Io io, String currentVersion, boolean isWindows) { + return new AutoUpdater(io, currentVersion, isWindows); } /** @@ -229,7 +229,7 @@ private JsonObject toJsonObject(String jsonString) { private static String getJarLocation() { try { - return new File(TmcCliUpdater.class.getProtectionDomain() + return new File(AutoUpdater.class.getProtectionDomain() .getCodeSource().getLocation().toURI()).getParent() + File.separator; } catch (Exception ex) { diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/ApplicationTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/ApplicationTest.java index 2b436979..9e0f6234 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/ApplicationTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/ApplicationTest.java @@ -1,6 +1,5 @@ package fi.helsinki.cs.tmc.cli; -import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doReturn; @@ -12,9 +11,10 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.verifyStatic; +import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.io.Io; import fi.helsinki.cs.tmc.cli.io.TestIo; -import fi.helsinki.cs.tmc.cli.updater.TmcCliUpdater; +import fi.helsinki.cs.tmc.cli.updater.AutoUpdater; import org.junit.Before; import org.junit.Test; @@ -25,7 +25,7 @@ import java.util.HashMap; @RunWith(PowerMockRunner.class) -@PrepareForTest(TmcCliUpdater.class) +@PrepareForTest(AutoUpdater.class) public class ApplicationTest { private Application app; @@ -35,14 +35,14 @@ public class ApplicationTest { public void setUp() { io = new TestIo(); app = new Application(new CliContext(io)); - mockStatic(TmcCliUpdater.class); + mockStatic(AutoUpdater.class); } @Test public void versionWorksWithRightParameter() { String[] args = {"-v", "foo"}; app.run(args); - assertTrue(io.out().contains("TMC-CLI version")); + io.assertContains("TMC-CLI version"); io.assertNotContains("Command foo doesn't exist."); } @@ -78,8 +78,8 @@ public void runCommandWorksWithWrongParameter() { @Test public void runAutoUpdate() { String[] args = {"help"}; - TmcCliUpdater mockUpdater = mock(TmcCliUpdater.class); - when(TmcCliUpdater.createUpdater(any(Io.class), anyString(), any(Boolean.class))) + AutoUpdater mockUpdater = mock(AutoUpdater.class); + when(AutoUpdater.createUpdater(any(Io.class), anyString(), any(Boolean.class))) .thenReturn(mockUpdater); when(mockUpdater.run()).thenReturn(true); @@ -90,7 +90,7 @@ public void runAutoUpdate() { app.run(args); verifyStatic(times(1)); - TmcCliUpdater.createUpdater(any(Io.class), anyString(), any(Boolean.class)); + AutoUpdater.createUpdater(any(Io.class), anyString(), any(Boolean.class)); } @Test diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/CourseInfoIoTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoIoTest.java similarity index 97% rename from src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/CourseInfoIoTest.java rename to src/test/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoIoTest.java index 13862b48..a64b8d03 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/CourseInfoIoTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoIoTest.java @@ -1,4 +1,4 @@ -package fi.helsinki.cs.tmc.cli.tmcstuff; +package fi.helsinki.cs.tmc.cli.backend; import fi.helsinki.cs.tmc.core.domain.Course; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/CourseInfoTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoTest.java similarity index 98% rename from src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/CourseInfoTest.java rename to src/test/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoTest.java index 962f9bf3..16073c0e 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/CourseInfoTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoTest.java @@ -1,4 +1,4 @@ -package fi.helsinki.cs.tmc.cli.tmcstuff; +package fi.helsinki.cs.tmc.cli.backend; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/SettingsIoTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/backend/SettingsIoTest.java similarity index 99% rename from src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/SettingsIoTest.java rename to src/test/java/fi/helsinki/cs/tmc/cli/backend/SettingsIoTest.java index 6317c9b7..9145434d 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/SettingsIoTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/backend/SettingsIoTest.java @@ -1,4 +1,4 @@ -package fi.helsinki.cs.tmc.cli.tmcstuff; +package fi.helsinki.cs.tmc.cli.backend; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/SettingsTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/backend/SettingsTest.java similarity index 98% rename from src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/SettingsTest.java rename to src/test/java/fi/helsinki/cs/tmc/cli/backend/SettingsTest.java index e58a6555..5b612a6b 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/SettingsTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/backend/SettingsTest.java @@ -1,4 +1,4 @@ -package fi.helsinki.cs.tmc.cli.tmcstuff; +package fi.helsinki.cs.tmc.cli.backend; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/TmcUtilTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/backend/TmcUtilTest.java similarity index 98% rename from src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/TmcUtilTest.java rename to src/test/java/fi/helsinki/cs/tmc/cli/backend/TmcUtilTest.java index cec53986..6370f97c 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/TmcUtilTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/backend/TmcUtilTest.java @@ -1,4 +1,4 @@ -package fi.helsinki.cs.tmc.cli.tmcstuff; +package fi.helsinki.cs.tmc.cli.backend; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -13,9 +13,10 @@ import static org.mockito.Mockito.when; import fi.helsinki.cs.tmc.cli.Application; -import fi.helsinki.cs.tmc.cli.CliContext; +import fi.helsinki.cs.tmc.cli.core.CliContext; +import fi.helsinki.cs.tmc.cli.io.CliProgressObserver; import fi.helsinki.cs.tmc.cli.io.TestIo; -import fi.helsinki.cs.tmc.cli.io.TmcCliProgressObserver; + import fi.helsinki.cs.tmc.core.TmcCore; import fi.helsinki.cs.tmc.core.commands.GetUpdatableExercises.UpdateResult; import fi.helsinki.cs.tmc.core.domain.Course; @@ -209,7 +210,7 @@ public void downloadSomeExercises() { .thenReturn(createReturningCallback(expectedResult)); List result = TmcUtil.downloadExercises(ctx, expectedResult, - new TmcCliProgressObserver(io)); + new CliProgressObserver(io)); assertEquals(expectedResult, result); } @@ -222,7 +223,7 @@ public void failToDownloadCourses() throws Exception { eq(exercises))).thenReturn(callable); assertNull(TmcUtil.downloadExercises(ctx, exercises, - new TmcCliProgressObserver(io))); + new CliProgressObserver(io))); } @Test diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/DocumentCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/DocumentCommandTest.java index 9087ea29..d403b0e9 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/DocumentCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/DocumentCommandTest.java @@ -4,7 +4,7 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic; import fi.helsinki.cs.tmc.cli.Application; -import fi.helsinki.cs.tmc.cli.CliContext; +import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.io.EnvironmentUtil; import fi.helsinki.cs.tmc.cli.io.TestIo; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommandTest.java index ed0bfeb7..a35fa58a 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommandTest.java @@ -13,12 +13,12 @@ import static org.powermock.api.mockito.PowerMockito.verifyStatic; import fi.helsinki.cs.tmc.cli.Application; -import fi.helsinki.cs.tmc.cli.CliContext; +import fi.helsinki.cs.tmc.cli.backend.Settings; +import fi.helsinki.cs.tmc.cli.backend.SettingsIo; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.io.TestIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.Settings; -import fi.helsinki.cs.tmc.cli.tmcstuff.SettingsIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.TmcUtil; -import fi.helsinki.cs.tmc.cli.tmcstuff.WorkDir; +import fi.helsinki.cs.tmc.cli.io.WorkDir; import fi.helsinki.cs.tmc.core.TmcCore; import fi.helsinki.cs.tmc.core.domain.Course; import fi.helsinki.cs.tmc.core.domain.Exercise; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/HelpCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/HelpCommandTest.java index eda83fea..dc4aed2e 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/HelpCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/HelpCommandTest.java @@ -3,7 +3,7 @@ import static org.mockito.Mockito.mock; import fi.helsinki.cs.tmc.cli.Application; -import fi.helsinki.cs.tmc.cli.CliContext; +import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.io.TestIo; import fi.helsinki.cs.tmc.core.TmcCore; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/CourseInfoCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/InfoCommandTest.java similarity index 97% rename from src/test/java/fi/helsinki/cs/tmc/cli/command/CourseInfoCommandTest.java rename to src/test/java/fi/helsinki/cs/tmc/cli/command/InfoCommandTest.java index bdb3c68c..e7a41daf 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/CourseInfoCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/InfoCommandTest.java @@ -9,10 +9,11 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic; import fi.helsinki.cs.tmc.cli.Application; -import fi.helsinki.cs.tmc.cli.CliContext; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.io.TestIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.TmcUtil; -import fi.helsinki.cs.tmc.cli.tmcstuff.WorkDir; +import fi.helsinki.cs.tmc.cli.io.WorkDir; + import fi.helsinki.cs.tmc.core.TmcCore; import fi.helsinki.cs.tmc.core.domain.Course; import fi.helsinki.cs.tmc.core.domain.Exercise; @@ -31,7 +32,7 @@ @RunWith(PowerMockRunner.class) @PrepareForTest(TmcUtil.class) -public class CourseInfoCommandTest { +public class InfoCommandTest { private static final String COURSE_NAME = "2016-aalto-c"; private static final String EXERCISE1_NAME = "Module_1-02_intro"; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java index 536e8be1..38df6106 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java @@ -8,11 +8,12 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic; import fi.helsinki.cs.tmc.cli.Application; -import fi.helsinki.cs.tmc.cli.CliContext; +import fi.helsinki.cs.tmc.cli.backend.Settings; +import fi.helsinki.cs.tmc.cli.backend.SettingsIo; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.io.TestIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.Settings; -import fi.helsinki.cs.tmc.cli.tmcstuff.SettingsIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.TmcUtil; + import fi.helsinki.cs.tmc.core.TmcCore; import fi.helsinki.cs.tmc.core.domain.Course; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/ListExercisesCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/ListExercisesCommandTest.java index fcad2e7d..0083387b 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/ListExercisesCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/ListExercisesCommandTest.java @@ -9,10 +9,11 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic; import fi.helsinki.cs.tmc.cli.Application; -import fi.helsinki.cs.tmc.cli.CliContext; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.io.TestIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.TmcUtil; -import fi.helsinki.cs.tmc.cli.tmcstuff.WorkDir; +import fi.helsinki.cs.tmc.cli.io.WorkDir; + import fi.helsinki.cs.tmc.core.TmcCore; import fi.helsinki.cs.tmc.core.domain.Course; import fi.helsinki.cs.tmc.core.domain.Exercise; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java index be92896c..37156d75 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java @@ -9,12 +9,13 @@ import static org.powermock.api.mockito.PowerMockito.verifyStatic; import fi.helsinki.cs.tmc.cli.Application; -import fi.helsinki.cs.tmc.cli.CliContext; +import fi.helsinki.cs.tmc.cli.backend.CourseInfo; +import fi.helsinki.cs.tmc.cli.backend.Settings; +import fi.helsinki.cs.tmc.cli.backend.SettingsIo; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.io.TestIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfo; -import fi.helsinki.cs.tmc.cli.tmcstuff.Settings; -import fi.helsinki.cs.tmc.cli.tmcstuff.SettingsIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.TmcUtil; + import fi.helsinki.cs.tmc.core.TmcCore; import fi.helsinki.cs.tmc.core.configuration.TmcSettings; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/LogoutCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/LogoutCommandTest.java index 417d88df..564c66ad 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/LogoutCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/LogoutCommandTest.java @@ -5,9 +5,9 @@ import static org.powermock.api.mockito.PowerMockito.verifyStatic; import fi.helsinki.cs.tmc.cli.Application; -import fi.helsinki.cs.tmc.cli.CliContext; +import fi.helsinki.cs.tmc.cli.backend.SettingsIo; +import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.io.TestIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.SettingsIo; import org.junit.Before; import org.junit.Test; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/PasteCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/PasteCommandTest.java index c5f7652e..819175a9 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/PasteCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/PasteCommandTest.java @@ -14,13 +14,14 @@ import static org.powermock.api.mockito.PowerMockito.verifyStatic; import fi.helsinki.cs.tmc.cli.Application; -import fi.helsinki.cs.tmc.cli.CliContext; +import fi.helsinki.cs.tmc.cli.backend.CourseInfo; +import fi.helsinki.cs.tmc.cli.backend.CourseInfoIo; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.io.ExternalsUtil; import fi.helsinki.cs.tmc.cli.io.TestIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfo; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfoIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.TmcUtil; -import fi.helsinki.cs.tmc.cli.tmcstuff.WorkDir; +import fi.helsinki.cs.tmc.cli.io.WorkDir; + import fi.helsinki.cs.tmc.core.TmcCore; import fi.helsinki.cs.tmc.core.domain.Exercise; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/PropertiesCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/PropertiesCommandTest.java index 54f7fc8f..58d8ad14 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/PropertiesCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/PropertiesCommandTest.java @@ -5,7 +5,7 @@ import static org.mockito.Mockito.when; import fi.helsinki.cs.tmc.cli.Application; -import fi.helsinki.cs.tmc.cli.CliContext; +import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.io.TestIo; import org.junit.Before; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/RunTestsCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/RunTestsCommandTest.java index 4f6b473f..4277fedd 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/RunTestsCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/RunTestsCommandTest.java @@ -10,10 +10,10 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic; import fi.helsinki.cs.tmc.cli.Application; -import fi.helsinki.cs.tmc.cli.CliContext; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.io.TestIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.TmcUtil; -import fi.helsinki.cs.tmc.cli.tmcstuff.WorkDir; +import fi.helsinki.cs.tmc.cli.io.WorkDir; import fi.helsinki.cs.tmc.core.TmcCore; import fi.helsinki.cs.tmc.core.domain.Exercise; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/ShellHelperCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/ShellHelperCommandTest.java index ed5eddb6..6133a548 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/ShellHelperCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/ShellHelperCommandTest.java @@ -1,7 +1,7 @@ package fi.helsinki.cs.tmc.cli.command; import fi.helsinki.cs.tmc.cli.Application; -import fi.helsinki.cs.tmc.cli.CliContext; +import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.io.TestIo; import org.junit.Before; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/SubmitCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/SubmitCommandTest.java index bea1fd5e..877cee2f 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/SubmitCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/SubmitCommandTest.java @@ -10,12 +10,12 @@ import static org.powermock.api.mockito.PowerMockito.verifyStatic; import fi.helsinki.cs.tmc.cli.Application; -import fi.helsinki.cs.tmc.cli.CliContext; +import fi.helsinki.cs.tmc.cli.backend.CourseInfo; +import fi.helsinki.cs.tmc.cli.backend.CourseInfoIo; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.io.TestIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfo; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfoIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.TmcUtil; -import fi.helsinki.cs.tmc.cli.tmcstuff.WorkDir; +import fi.helsinki.cs.tmc.cli.io.WorkDir; import fi.helsinki.cs.tmc.core.TmcCore; import fi.helsinki.cs.tmc.core.commands.GetUpdatableExercises.UpdateResult; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/UpdateCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/UpdateCommandTest.java index 6b9ba04a..942e688f 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/UpdateCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/UpdateCommandTest.java @@ -9,12 +9,13 @@ import static org.mockito.Mockito.when; import fi.helsinki.cs.tmc.cli.Application; -import fi.helsinki.cs.tmc.cli.CliContext; +import fi.helsinki.cs.tmc.cli.backend.CourseInfo; +import fi.helsinki.cs.tmc.cli.core.CliContext; +import fi.helsinki.cs.tmc.cli.io.CliProgressObserver; import fi.helsinki.cs.tmc.cli.io.TestIo; -import fi.helsinki.cs.tmc.cli.io.TmcCliProgressObserver; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfo; -import fi.helsinki.cs.tmc.cli.tmcstuff.ExerciseUpdater; -import fi.helsinki.cs.tmc.cli.tmcstuff.WorkDir; +import fi.helsinki.cs.tmc.cli.io.WorkDir; +import fi.helsinki.cs.tmc.cli.shared.ExerciseUpdater; + import fi.helsinki.cs.tmc.core.TmcCore; import fi.helsinki.cs.tmc.core.domain.Exercise; @@ -132,7 +133,7 @@ public void updatesNewAndChangedExercises() { List newAndChanged = new ArrayList<>(); newAndChanged.addAll(newExercises); newAndChanged.addAll(changedExercises); - when(exerciseUpdater.downloadUpdates(any(TmcCliProgressObserver.class))) + when(exerciseUpdater.downloadUpdates(any(CliProgressObserver.class))) .thenReturn(newAndChanged); when(exerciseUpdater.updateCourseJson(any(CourseInfo.class), any(Path.class))) .thenReturn(true); diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/core/AbstractCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/core/AbstractCommandTest.java similarity index 93% rename from src/test/java/fi/helsinki/cs/tmc/cli/command/core/AbstractCommandTest.java rename to src/test/java/fi/helsinki/cs/tmc/cli/core/AbstractCommandTest.java index 9135c03e..8ed0d8c6 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/core/AbstractCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/core/AbstractCommandTest.java @@ -1,6 +1,5 @@ -package fi.helsinki.cs.tmc.cli.command.core; +package fi.helsinki.cs.tmc.cli.core; -import fi.helsinki.cs.tmc.cli.CliContext; import fi.helsinki.cs.tmc.cli.io.Io; import fi.helsinki.cs.tmc.cli.io.TestIo; @@ -10,6 +9,7 @@ import org.junit.Test; public class AbstractCommandTest { + AbstractCommand emptyCommand; CliContext ctx; TestIo io; @@ -25,7 +25,7 @@ public void run(CommandLine args, Io io) { public void getOptions(Options options) { } } - + public AbstractCommandTest() { emptyCommand = new EmptyCommand(); io = new TestIo(); diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/CliContextTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/core/CliContextTest.java similarity index 94% rename from src/test/java/fi/helsinki/cs/tmc/cli/CliContextTest.java rename to src/test/java/fi/helsinki/cs/tmc/cli/core/CliContextTest.java index 10f7b5dc..b392825e 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/CliContextTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/core/CliContextTest.java @@ -1,4 +1,4 @@ -package fi.helsinki.cs.tmc.cli; +package fi.helsinki.cs.tmc.cli.core; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -10,13 +10,14 @@ import static org.mockito.Mockito.when; import static org.powermock.api.mockito.PowerMockito.mockStatic; +import fi.helsinki.cs.tmc.cli.Application; +import fi.helsinki.cs.tmc.cli.backend.CourseInfo; +import fi.helsinki.cs.tmc.cli.backend.CourseInfoIo; +import fi.helsinki.cs.tmc.cli.backend.Settings; +import fi.helsinki.cs.tmc.cli.backend.SettingsIo; import fi.helsinki.cs.tmc.cli.io.TerminalIo; import fi.helsinki.cs.tmc.cli.io.TestIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfo; -import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfoIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.Settings; -import fi.helsinki.cs.tmc.cli.tmcstuff.SettingsIo; -import fi.helsinki.cs.tmc.cli.tmcstuff.WorkDir; +import fi.helsinki.cs.tmc.cli.io.WorkDir; import org.junit.Before; import org.junit.Test; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/core/CommandAnnotationProcessorTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/core/CommandAnnotationProcessorTest.java similarity index 99% rename from src/test/java/fi/helsinki/cs/tmc/cli/command/core/CommandAnnotationProcessorTest.java rename to src/test/java/fi/helsinki/cs/tmc/cli/core/CommandAnnotationProcessorTest.java index 66abcfe9..37cc2363 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/core/CommandAnnotationProcessorTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/core/CommandAnnotationProcessorTest.java @@ -1,4 +1,4 @@ -package fi.helsinki.cs.tmc.cli.command.core; +package fi.helsinki.cs.tmc.cli.core; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertFalse; @@ -41,6 +41,7 @@ import javax.tools.JavaFileObject; public class CommandAnnotationProcessorTest { + CommandAnnotationProcessor processor; RoundEnvironment roundEnv; StringWriter stringWriter; @@ -50,7 +51,7 @@ public CommandAnnotationProcessorTest() throws IOException { final JavaFileObject fileObject = mock(JavaFileObject.class); final Filer mockedFiler = mock(Filer.class); when(mockedFiler.createSourceFile(anyString())).thenReturn(fileObject); - + stringWriter = new StringWriter(); when(fileObject.openWriter()).thenReturn(stringWriter); roundEnv = mock(RoundEnvironment.class); @@ -92,7 +93,6 @@ public SourceVersion getSourceVersion() { public Locale getLocale() { throw new UnsupportedOperationException(); } - }; processor = new CommandAnnotationProcessor(); processor.init(processingEnv); diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/core/CommandFactoryTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/core/CommandFactoryTest.java similarity index 96% rename from src/test/java/fi/helsinki/cs/tmc/cli/command/core/CommandFactoryTest.java rename to src/test/java/fi/helsinki/cs/tmc/cli/core/CommandFactoryTest.java index a1372ead..ba81c2cc 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/core/CommandFactoryTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/core/CommandFactoryTest.java @@ -1,11 +1,10 @@ -package fi.helsinki.cs.tmc.cli.command.core; +package fi.helsinki.cs.tmc.cli.core; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import fi.helsinki.cs.tmc.cli.Application; -import fi.helsinki.cs.tmc.cli.CliContext; import fi.helsinki.cs.tmc.cli.io.Io; import fi.helsinki.cs.tmc.cli.io.TestIo; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/io/TmcCliProgressObserverTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/io/CliProgressObserverTest.java similarity index 83% rename from src/test/java/fi/helsinki/cs/tmc/cli/io/TmcCliProgressObserverTest.java rename to src/test/java/fi/helsinki/cs/tmc/cli/io/CliProgressObserverTest.java index e316c3a3..fa497d30 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/io/TmcCliProgressObserverTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/io/CliProgressObserverTest.java @@ -13,7 +13,7 @@ @RunWith(PowerMockRunner.class) @PrepareForTest(EnvironmentUtil.class) -public class TmcCliProgressObserverTest { +public class CliProgressObserverTest { private TestIo io; @@ -26,7 +26,7 @@ public void setup() { @Test public void progressMessageWorks() { - TmcCliProgressObserver progobs = new TmcCliProgressObserver(io); + CliProgressObserver progobs = new CliProgressObserver(io); progobs.progress(0, "Hello, world!"); assertTrue("Prints message", io.out().contains( "Hello, world! ")); @@ -34,7 +34,7 @@ public void progressMessageWorks() { @Test public void progressBarWorks() { - TmcCliProgressObserver progobs = new TmcCliProgressObserver(io); + CliProgressObserver progobs = new CliProgressObserver(io); progobs.progress(0, 0.5, "Hello, world!"); assertTrue("Prints message", io.out().contains("Hello, world!")); assertTrue("Prints the start of the progress bar", io.out().contains( @@ -49,7 +49,7 @@ public void progressBarWorks() { @Test public void testResultBarWorks() { - String string = TmcCliProgressObserver.getPassedTestsBar(1, 2, + String string = CliProgressObserver.getPassedTestsBar(1, 2, Color.AnsiColor.ANSI_NONE, Color.AnsiColor.ANSI_NONE); assertTrue("Prints the start of the progress bar", string.contains( " 50%[")); @@ -63,7 +63,7 @@ public void testResultBarWorks() { @Test public void shortensLongMessages() { - TmcCliProgressObserver progobs = new TmcCliProgressObserver(io); + CliProgressObserver progobs = new CliProgressObserver(io); progobs.progress(0, "fooooooooooooooooooooooooooooooooooooooooooooooooobar"); assertTrue("Prints what it's supposed to", @@ -74,8 +74,8 @@ public void shortensLongMessages() { @Test public void percentagesWork() { - assertEquals(" 6%", TmcCliProgressObserver.percentage(0.06)); - assertEquals(" 20%", TmcCliProgressObserver.percentage(0.2)); - assertEquals("100%", TmcCliProgressObserver.percentage(1.0)); + assertEquals(" 6%", CliProgressObserver.percentage(0.06)); + assertEquals(" 20%", CliProgressObserver.percentage(0.2)); + assertEquals("100%", CliProgressObserver.percentage(1.0)); } } diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/WorkDirTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/io/WorkDirTest.java similarity index 98% rename from src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/WorkDirTest.java rename to src/test/java/fi/helsinki/cs/tmc/cli/io/WorkDirTest.java index 57d5a10a..8e643432 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/WorkDirTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/io/WorkDirTest.java @@ -1,4 +1,4 @@ -package fi.helsinki.cs.tmc.cli.tmcstuff; +package fi.helsinki.cs.tmc.cli.io; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertNull; @@ -7,6 +7,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import fi.helsinki.cs.tmc.cli.backend.CourseInfo; +import fi.helsinki.cs.tmc.cli.backend.CourseInfoIo; +import fi.helsinki.cs.tmc.cli.backend.Settings; + import fi.helsinki.cs.tmc.core.domain.Course; import fi.helsinki.cs.tmc.core.domain.Exercise; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/ExerciseUpdaterTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/shared/ExerciseUpdaterTest.java similarity index 95% rename from src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/ExerciseUpdaterTest.java rename to src/test/java/fi/helsinki/cs/tmc/cli/shared/ExerciseUpdaterTest.java index 07650fbe..93644139 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/ExerciseUpdaterTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/shared/ExerciseUpdaterTest.java @@ -1,4 +1,4 @@ -package fi.helsinki.cs.tmc.cli.tmcstuff; +package fi.helsinki.cs.tmc.cli.shared; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -8,7 +8,8 @@ import static org.mockito.Mockito.when; import static org.powermock.api.mockito.PowerMockito.mockStatic; -import fi.helsinki.cs.tmc.cli.CliContext; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.io.TestIo; import fi.helsinki.cs.tmc.core.TmcCore; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/FeedbackHandlerTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/shared/FeedbackHandlerTest.java similarity index 96% rename from src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/FeedbackHandlerTest.java rename to src/test/java/fi/helsinki/cs/tmc/cli/shared/FeedbackHandlerTest.java index 251c7512..abddb1d1 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/tmcstuff/FeedbackHandlerTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/shared/FeedbackHandlerTest.java @@ -1,4 +1,4 @@ -package fi.helsinki.cs.tmc.cli.tmcstuff; +package fi.helsinki.cs.tmc.cli.shared; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.any; @@ -9,7 +9,8 @@ import static org.powermock.api.mockito.PowerMockito.verifyStatic; import static org.powermock.api.mockito.PowerMockito.when; -import fi.helsinki.cs.tmc.cli.CliContext; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.io.ExternalsUtil; import fi.helsinki.cs.tmc.cli.io.TestIo; import fi.helsinki.cs.tmc.core.domain.submission.FeedbackAnswer; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/io/ResultPrinterTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/shared/ResultPrinterTest.java similarity index 98% rename from src/test/java/fi/helsinki/cs/tmc/cli/io/ResultPrinterTest.java rename to src/test/java/fi/helsinki/cs/tmc/cli/shared/ResultPrinterTest.java index 1bca573b..7a523478 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/io/ResultPrinterTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/shared/ResultPrinterTest.java @@ -1,8 +1,11 @@ -package fi.helsinki.cs.tmc.cli.io; +package fi.helsinki.cs.tmc.cli.shared; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import fi.helsinki.cs.tmc.cli.io.Color; +import fi.helsinki.cs.tmc.cli.io.TestIo; + import fi.helsinki.cs.tmc.core.domain.submission.SubmissionResult; import fi.helsinki.cs.tmc.core.domain.submission.SubmissionResult.TestResultStatus; import fi.helsinki.cs.tmc.core.domain.submission.ValidationErrorImpl; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/updater/TmcCliUpdaterTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/updater/AutoUpdaterTest.java similarity index 88% rename from src/test/java/fi/helsinki/cs/tmc/cli/updater/TmcCliUpdaterTest.java rename to src/test/java/fi/helsinki/cs/tmc/cli/updater/AutoUpdaterTest.java index 611bf460..e20011ee 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/updater/TmcCliUpdaterTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/updater/AutoUpdaterTest.java @@ -6,7 +6,6 @@ import static org.junit.Assert.assertThat; import static org.junit.matchers.JUnitMatchers.containsString; import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -25,7 +24,7 @@ import java.io.InputStream; import java.io.IOException; -public class TmcCliUpdaterTest { +public class AutoUpdaterTest { private static String latestJson; private static String apiLimitExeededJson; @@ -61,7 +60,7 @@ public void stub() { @Test public void doNothingIfReleaseEqualsCurrentVersion() { - TmcCliUpdater updater = spy(new TmcCliUpdater(io, "0.1.1", false)); + AutoUpdater updater = spy(new AutoUpdater(io, "0.1.1", false)); doReturn(latestJson).when(updater).fetchLatestReleaseJson(); //when(updater.fetchLatestReleaseJson()).thenReturn(latestJson); updater.run(); @@ -71,7 +70,7 @@ public void doNothingIfReleaseEqualsCurrentVersion() { @Test public void doNothingIfFetchingReleaseJsonFails() { - TmcCliUpdater updater = spy(new TmcCliUpdater(io, "0.1.0", false)); + AutoUpdater updater = spy(new AutoUpdater(io, "0.1.0", false)); doReturn(null).when(updater).fetchLatestReleaseJson(); //when(updater.fetchLatestReleaseJson()).thenReturn(null); updater.run(); @@ -81,7 +80,7 @@ public void doNothingIfFetchingReleaseJsonFails() { @Test public void doNothingIfFetchedJsonIsApiRateLimitExceeded() { - TmcCliUpdater updater = spy(new TmcCliUpdater(io, "0.1.0", false)); + AutoUpdater updater = spy(new AutoUpdater(io, "0.1.0", false)); doReturn(apiLimitExeededJson).when(updater).fetchLatestReleaseJson(); //when(updater.fetchLatestReleaseJson()).thenReturn(apiLimitExeededJson); updater.run(); @@ -92,7 +91,7 @@ public void doNothingIfFetchedJsonIsApiRateLimitExceeded() { @Test public void doNothingIfUserDoesntWantToUpdate() { io.addConfirmationPrompt(false); - TmcCliUpdater updater = spy(new TmcCliUpdater(io, "0.1.0", false)); + AutoUpdater updater = spy(new AutoUpdater(io, "0.1.0", false)); doReturn(latestJson).when(updater).fetchLatestReleaseJson(); //when(updater.fetchLatestReleaseJson()).thenReturn(latestJson); updater.run(); @@ -104,7 +103,7 @@ public void doNothingIfUserDoesntWantToUpdate() { @Test public void downloadsAndRunsNewBinaryIfOk() { io.addConfirmationPrompt(true); - TmcCliUpdater updater = spy(new TmcCliUpdater(io, "0.1.0", false)); + AutoUpdater updater = spy(new AutoUpdater(io, "0.1.0", false)); doReturn(latestJson).when(updater).fetchLatestReleaseJson(); //when(updater.fetchLatestReleaseJson()).thenReturn(latestJson); doReturn(true).when(updater).fetchTmcCliBinary(any(String.class), any(File.class)); @@ -120,7 +119,7 @@ public void downloadsAndRunsNewBinaryIfOk() { // Expected to fail once autoupdater is properly implemented on Windows. @Test public void newReleaseShowsDownloadLinkOnWindows() { - TmcCliUpdater updater = spy(new TmcCliUpdater(io, "0.1.0", true)); + AutoUpdater updater = spy(new AutoUpdater(io, "0.1.0", true)); doReturn(latestJson).when(updater).fetchLatestReleaseJson(); //when(updater.fetchLatestReleaseJson()).thenReturn(latestJson); updater.run(); @@ -131,7 +130,7 @@ public void newReleaseShowsDownloadLinkOnWindows() { @Test public void doNothingIfJsonIsMalformed() { - TmcCliUpdater updater = spy(new TmcCliUpdater(io, "0.1.0", false)); + AutoUpdater updater = spy(new AutoUpdater(io, "0.1.0", false)); doReturn(malformedJson).when(updater).fetchLatestReleaseJson(); //when(updater.fetchLatestReleaseJson()).thenReturn(malformedJson); updater.run(); @@ -141,7 +140,7 @@ public void doNothingIfJsonIsMalformed() { @Test public void abortIfJsonDoesNotContainNecessaryInfo() { - TmcCliUpdater updater = spy(new TmcCliUpdater(io, "0.1.0", false)); + AutoUpdater updater = spy(new AutoUpdater(io, "0.1.0", false)); doReturn(changedJson).when(updater).fetchLatestReleaseJson(); //when(updater.fetchLatestReleaseJson()).thenReturn(changedJson); updater.run(); @@ -150,7 +149,7 @@ public void abortIfJsonDoesNotContainNecessaryInfo() { } private static String readResource(String resourceName) throws IOException { - InputStream inputStream = TmcCliUpdaterTest.class.getClassLoader() + InputStream inputStream = AutoUpdaterTest.class.getClassLoader() .getResourceAsStream(resourceName); if (inputStream == null) { return null; From 928d5a9da63d2250c53d13b3ba8f6c0513cb27d4 Mon Sep 17 00:00:00 2001 From: Aleksi Salmela Date: Sat, 9 Jul 2016 19:48:09 +0300 Subject: [PATCH 02/16] Separate the login info from settings object. --- .../helsinki/cs/tmc/cli/backend/Account.java | 52 ++++++++++ .../cs/tmc/cli/backend/AccountList.java | 80 +++++++++++++++ .../helsinki/cs/tmc/cli/backend/Settings.java | 63 +++++------- .../cs/tmc/cli/backend/SettingsHolder.java | 78 --------------- .../cs/tmc/cli/backend/SettingsIo.java | 40 ++++---- .../helsinki/cs/tmc/cli/backend/TmcUtil.java | 4 +- .../cli/command/DownloadExercisesCommand.java | 20 ++-- .../tmc/cli/command/ListCoursesCommand.java | 10 +- .../cs/tmc/cli/command/LoginCommand.java | 9 +- .../helsinki/cs/tmc/cli/core/CliContext.java | 33 +++---- .../cs/tmc/cli/backend/AccountTest.java | 35 +++++++ .../cs/tmc/cli/backend/SettingsIoTest.java | 98 +++++++++---------- .../cs/tmc/cli/backend/SettingsTest.java | 41 ++++---- .../cs/tmc/cli/backend/TmcUtilTest.java | 12 +-- .../command/DownloadExercisesCommandTest.java | 50 ++++------ .../cli/command/ListCoursesCommandTest.java | 14 +-- .../cs/tmc/cli/command/LoginCommandTest.java | 25 ++--- .../cs/tmc/cli/core/CliContextTest.java | 18 +++- 18 files changed, 372 insertions(+), 310 deletions(-) create mode 100644 src/main/java/fi/helsinki/cs/tmc/cli/backend/Account.java create mode 100644 src/main/java/fi/helsinki/cs/tmc/cli/backend/AccountList.java delete mode 100644 src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsHolder.java create mode 100644 src/test/java/fi/helsinki/cs/tmc/cli/backend/AccountTest.java diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/backend/Account.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/Account.java new file mode 100644 index 00000000..b1810166 --- /dev/null +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/Account.java @@ -0,0 +1,52 @@ +package fi.helsinki.cs.tmc.cli.backend; + +/** + * This object stores all login info. + */ +public class Account { + + static Account NULL_ACCOUNT = new Account(null, null, null); + + private String serverAddress; + private String username; + private String password; + + // for gson + public Account() { } + + public Account(String serverAddress, String username, String password) { + this.serverAddress = serverAddress; + this.username = username; + this.password = password; + } + + public String getServerAddress() { + return serverAddress; + } + + public String getPassword() { + return password; + } + + public String getUsername() { + return username; + } + + private static boolean stringEquals(String str1, String str2) { + return (str1 == null ? str2 == null : str1.equals(str2)); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (!(obj instanceof Account)) { + return false; + } + Account another = (Account) obj; + return stringEquals(this.serverAddress, another.serverAddress) + && stringEquals(this.username, another.username) + && stringEquals(this.password, another.password); + } +} diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/backend/AccountList.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/AccountList.java new file mode 100644 index 00000000..e977d759 --- /dev/null +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/AccountList.java @@ -0,0 +1,80 @@ +package fi.helsinki.cs.tmc.cli.backend; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * This is a class for storing all different accounts as a single array. + */ +public class AccountList { + + private ArrayList accountArray; + + public AccountList() { + this.accountArray = new ArrayList<>(); + } + + //TODO This should not be used + public Account getAccount() { + if (this.accountArray.size() > 0) { + // Get last used account by default + return this.accountArray.get(0); + } + return null; + } + + public Account getAccount(String username, String server) { + if (username == null || server == null) { + return getAccount(); + } + for (Account account : this.accountArray) { + if (account.getUsername().equals(username) + && account.getServerAddress().equals(server)) { + // Move account to index 0 so we can always use the last used account by default + this.accountArray.remove(account); + this.accountArray.add(0, account); + return account; + } + } + return null; + } + + public void addAccount(Account newSettings) { + for (Account account : this.accountArray) { + if (account.getUsername().equals(newSettings.getUsername()) + && account.getServerAddress().equals(newSettings.getServerAddress())) { + // Replace old account if username and server match + this.accountArray.remove(account); + break; + } + } + this.accountArray.add(0, newSettings); + } + + public void deleteAccount(String username, String server) { + Account remove = null; + for (Account account : this.accountArray) { + if (account.getUsername().equals(username) + && account.getServerAddress().equals(server)) { + remove = account; + break; + } + } + if (remove != null) { + this.accountArray.remove(remove); + } + } + + public void deleteAllAccounts() { + this.accountArray = new ArrayList<>(); + } + + public int accountCount() { + return this.accountArray.size(); + } + + public List getAccountList() { + return Collections.unmodifiableList(this.accountArray); + } +} diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/backend/Settings.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/Settings.java index 3fbc975a..df8a7853 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/backend/Settings.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/Settings.java @@ -14,72 +14,57 @@ public class Settings implements TmcSettings { - private String serverAddress; - private String username; - private String password; + private WorkDir workDir; + private Account account; - private transient WorkDir workDir; - - public Settings(String serverAddress, String username, String password) { - this.serverAddress = serverAddress; - this.username = username; - this.password = password; + public Settings() { + this.account = Account.NULL_ACCOUNT; } - public Settings() { + public Settings(String serverAddress, String username, String password) { + this.account = new Account(serverAddress, username, password); } /** * This method is used for changing the main settings object. - * @param settings settings object where from the new values are copied + * @param account account that has the login info */ - public void set(Settings settings) { - this.serverAddress = settings.serverAddress; - this.username = settings.username; - this.password = settings.password; - } - - public void setWorkDir(WorkDir workDir) { - this.workDir = workDir; + public void setAccount(Account account) { + if (account == null) { + /* NULL_ACCOUNT is used so that the NullPointerException + * is not thrown in the getters. + */ + account = Account.NULL_ACCOUNT; + } + this.account = account; } - public static boolean stringEquals(String str1, String str2) { - return (str1 == null ? str2 == null : str1.equals(str2)); + public Account getAccount() { + return account; } - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (!(obj instanceof Settings)) { - return false; - } - Settings another = (Settings)obj; - return stringEquals(this.serverAddress, another.serverAddress) - && stringEquals(this.username, another.username) - && stringEquals(this.password, another.password); + public void setWorkDir(WorkDir workDir) { + this.workDir = workDir; } @Override public String getServerAddress() { - return serverAddress; + return account.getServerAddress(); } @Override public String getPassword() { - return password; + return account.getPassword(); } @Override public String getUsername() { - return username; + return account.getUsername(); } @Override public boolean userDataExists() { - return this.username != null && this.password != null - && !this.username.isEmpty() && !this.password.isEmpty(); + return getUsername() != null && getPassword() != null; } @Override @@ -107,7 +92,7 @@ public String getFormattedUserData() { if (!userDataExists()) { return ""; } - return this.username + ":" + this.password; + return getUsername() + ":" + this.getPassword(); } @Override diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsHolder.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsHolder.java deleted file mode 100644 index d83a0e7a..00000000 --- a/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsHolder.java +++ /dev/null @@ -1,78 +0,0 @@ -package fi.helsinki.cs.tmc.cli.backend; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * This is a class for storing all different login settings as a single array. - */ -public class SettingsHolder { - private ArrayList settingsArray; - - public SettingsHolder() { - this.settingsArray = new ArrayList<>(); - } - - public Settings getSettings() { - if (this.settingsArray.size() > 0) { - // Get last used settings by default - return this.settingsArray.get(0); - } - return null; - } - - public Settings getSettings(String username, String server) { - if (username == null || server == null) { - return getSettings(); - } - for (Settings settings : this.settingsArray) { - if (settings.getUsername().equals(username) - && settings.getServerAddress().equals(server)) { - // Move settings to index 0 so we can always use the last used settings by default - this.settingsArray.remove(settings); - this.settingsArray.add(0, settings); - return settings; - } - } - return null; - } - - public void addSettings(Settings newSettings) { - for (Settings settings : this.settingsArray) { - if (settings.getUsername().equals(newSettings.getUsername()) - && settings.getServerAddress().equals(newSettings.getServerAddress())) { - // Replace old settings if username and server match - this.settingsArray.remove(settings); - break; - } - } - this.settingsArray.add(0, newSettings); - } - - public void deleteSettings(String username, String server) { - Settings remove = null; - for (Settings settings : this.settingsArray) { - if (settings.getUsername().equals(username) - && settings.getServerAddress().equals(server)) { - remove = settings; - break; - } - } - if (remove != null) { - this.settingsArray.remove(remove); - } - } - - public void deleteAllSettings() { - this.settingsArray = new ArrayList(); - } - - public int settingsCount() { - return this.settingsArray.size(); - } - - public List getSettingsList() { - return Collections.unmodifiableList(this.settingsArray); - } -} diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java index 772be8bd..5e0f1ba4 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java @@ -89,56 +89,56 @@ private static Path getPropertiesFile(Path configRoot) { return file; } - public static Boolean save(Settings settings) { - return saveTo(settings, getDefaultConfigRoot()); + public static Boolean save(Account account) { + return saveTo(account, getDefaultConfigRoot()); } - public static Boolean saveTo(Settings settings, Path configRoot) { + public static Boolean saveTo(Account account, Path configRoot) { Path file = getAccountsFile(configRoot); - SettingsHolder holder; + AccountList holder; if (!Files.exists(file)) { - holder = new SettingsHolder(); + holder = new AccountList(); } else { holder = getHolderFromJson(file); } - holder.addSettings(settings); + holder.addAccount(account); return saveHolderToJson(holder, file); } - public static Settings load(String username, String server) { + public static Account load(String username, String server) { return loadFrom(username, server, getDefaultConfigRoot()); } - public static Settings load() { - // Calling the method without parametres returns the last used settings + public static Account load() { + // Calling the method without parametres returns the last used account return load(null, null); } - public static Settings loadFrom(Path configRoot) { + public static Account loadFrom(Path configRoot) { return loadFrom(null, null, configRoot); } - public static Settings loadFrom(String username, String server, Path configRoot) { + public static Account loadFrom(String username, String server, Path configRoot) { Path file = getAccountsFile(configRoot); if (!Files.exists(file)) { return null; } - SettingsHolder holder = getHolderFromJson(file); - Settings ret = holder.getSettings(username, server); + AccountList holder = getHolderFromJson(file); + Account ret = holder.getAccount(username, server); saveHolderToJson(holder, file); return ret; } - public static List getSettingsList() { + public static List getAccountList() { Path file = getAccountsFile(getDefaultConfigRoot()); if (!Files.exists(file)) { return null; } - SettingsHolder holder = getHolderFromJson(file); - return holder.getSettingsList(); + AccountList holder = getHolderFromJson(file); + return holder.getAccountList(); } - private static SettingsHolder getHolderFromJson(Path file) { + private static AccountList getHolderFromJson(Path file) { Gson gson = new Gson(); Reader reader; try { @@ -147,16 +147,16 @@ private static SettingsHolder getHolderFromJson(Path file) { logger.error("Accounts file located, but failed to read from it", e); return null; } - return gson.fromJson(reader, SettingsHolder.class); + return gson.fromJson(reader, AccountList.class); } - private static Boolean saveHolderToJson(SettingsHolder holder, Path file) { + private static Boolean saveHolderToJson(AccountList holder, Path file) { Gson gson = new Gson(); byte[] json = gson.toJson(holder).getBytes(); try { Files.write(file, json); } catch (IOException e) { - logger.error("Could not write settings to accounts file", e); + logger.error("Could not write account to accounts file", e); return false; } return true; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java index 5c048280..f7c4b26d 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java @@ -27,9 +27,9 @@ public class TmcUtil { private static final Logger logger = LoggerFactory.getLogger(TmcUtil.class); - public static boolean tryToLogin(CliContext ctx, Settings settings) { + public static boolean tryToLogin(CliContext ctx, Account account) { TmcCore core = ctx.getTmcCore(); - ctx.useSettings(settings); + ctx.useAccount(account); Callable> callable = core.listCourses(ProgressObserver.NULL_OBSERVER); //TODO restore the settings object diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java index edbffd57..7c81ae68 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java @@ -1,8 +1,8 @@ package fi.helsinki.cs.tmc.cli.command; +import fi.helsinki.cs.tmc.cli.backend.Account; import fi.helsinki.cs.tmc.cli.backend.CourseInfo; import fi.helsinki.cs.tmc.cli.backend.CourseInfoIo; -import fi.helsinki.cs.tmc.cli.backend.Settings; import fi.helsinki.cs.tmc.cli.backend.SettingsIo; import fi.helsinki.cs.tmc.cli.backend.TmcUtil; import fi.helsinki.cs.tmc.cli.core.AbstractCommand; @@ -90,12 +90,12 @@ public void run(CommandLine args, Io io) { private Course findCourse(String courseName) { Io io = ctx.getIo(); - List accountsList = SettingsIo.getSettingsList(); + List accountsList = SettingsIo.getAccountList(); // LinkedHashMap is used here to preserve ordering. - Map matches = new LinkedHashMap<>(); + Map matches = new LinkedHashMap<>(); - for (Settings settings : accountsList) { - ctx.useSettings(settings); + for (Account settings : accountsList) { + ctx.useAccount(settings); Course course = TmcUtil.findCourse(ctx, courseName); if (course != null) { matches.put(settings, course); @@ -103,8 +103,8 @@ private Course findCourse(String courseName) { } if (matches.size() == 1) { - Entry firstEntry = matches.entrySet().iterator().next(); - ctx.useSettings(firstEntry.getKey()); + Entry firstEntry = matches.entrySet().iterator().next(); + ctx.useAccount(firstEntry.getKey()); return firstEntry.getValue(); } else if (matches.isEmpty()) { io.println("Course doesn't exist."); @@ -114,14 +114,14 @@ private Course findCourse(String courseName) { io.println("There is " + matches.size() + " courses with same name at different servers."); - for (Entry entrySet : matches.entrySet()) { - Settings settings = entrySet.getKey(); + for (Entry entrySet : matches.entrySet()) { + Account settings = entrySet.getKey(); Course course = entrySet.getValue(); if (io.readConfirmation("Download course from " + settings.getServerAddress() + " with '" + settings.getUsername() + "' account", false)) { - ctx.useSettings(settings); + ctx.useAccount(settings); return course; } } diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java index c78f4838..2a5c422b 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java @@ -1,6 +1,6 @@ package fi.helsinki.cs.tmc.cli.command; -import fi.helsinki.cs.tmc.cli.backend.Settings; +import fi.helsinki.cs.tmc.cli.backend.Account; import fi.helsinki.cs.tmc.cli.backend.SettingsIo; import fi.helsinki.cs.tmc.cli.backend.TmcUtil; import fi.helsinki.cs.tmc.cli.core.AbstractCommand; @@ -38,10 +38,10 @@ public void run(CommandLine args, Io io) { return; } - List accountsList = SettingsIo.getSettingsList(); + List accountsList = SettingsIo.getAccountList(); boolean isFirst = true; - for (Settings settings : accountsList) { + for (Account settings : accountsList) { if (!isFirst) { io.println(""); } @@ -54,8 +54,8 @@ public void run(CommandLine args, Io io) { } } - private void printCourseList(Settings settings) { - ctx.useSettings(settings); + private void printCourseList(Account account) { + ctx.useAccount(account); List courses = TmcUtil.listCourses(getContext()); if (courses.isEmpty()) { io.println("No courses found from the server."); diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java index 660d9791..6850c038 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java @@ -1,7 +1,7 @@ package fi.helsinki.cs.tmc.cli.command; +import fi.helsinki.cs.tmc.cli.backend.Account; import fi.helsinki.cs.tmc.cli.backend.CourseInfo; -import fi.helsinki.cs.tmc.cli.backend.Settings; import fi.helsinki.cs.tmc.cli.backend.SettingsIo; import fi.helsinki.cs.tmc.cli.backend.TmcUtil; import fi.helsinki.cs.tmc.cli.core.AbstractCommand; @@ -48,12 +48,11 @@ public void run(CommandLine args, Io io) { username = getLoginInfo(args, username, "u", "username: "); password = getLoginInfo(args, null, "p", "password: "); - //TODO don't create new settings object. - Settings settings = new Settings(serverAddress, username, password); - if (!TmcUtil.tryToLogin(ctx, settings)) { + Account account = new Account(serverAddress, username, password); + if (!TmcUtil.tryToLogin(ctx, account)) { return; } - if (!SettingsIo.save(settings)) { + if (!SettingsIo.save(account)) { io.println("Failed to write the accounts file."); return; } 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 dc6dca52..82473f5b 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 @@ -1,6 +1,7 @@ package fi.helsinki.cs.tmc.cli.core; import fi.helsinki.cs.tmc.cli.Application; +import fi.helsinki.cs.tmc.cli.backend.Account; import fi.helsinki.cs.tmc.cli.backend.CourseInfo; import fi.helsinki.cs.tmc.cli.backend.CourseInfoIo; import fi.helsinki.cs.tmc.cli.backend.Settings; @@ -44,14 +45,11 @@ public CliContext(Io io, TmcCore core, WorkDir workDir) { if (!inTest) { io = new TerminalIo(System.in); } - // This is only used when we want to mock the tmc core. - if (core != null) { - this.settings = new Settings(); - } this.io = io; this.workDir = workDir; this.properties = SettingsIo.loadProperties(); + this.settings = new Settings(); this.tmcCore = core; this.hasLogin = (core != null); this.courseInfo = null; @@ -216,48 +214,43 @@ public boolean loadBackendWithoutLogin() { /** * Copy login info from different settings object and them. * TODO: separate settings object and login info. - * @param settings login info + * @param account login info */ - public void useSettings(Settings settings) { + public void useAccount(Account account) { if (this.tmcCore == null) { - createTmcCore(settings); + createTmcCore(account); } - this.settings.set(settings); + this.settings.setAccount(account); } - private void createTmcCore(Settings settings) { + private void createTmcCore(Account account) { TaskExecutor tmcLangs; tmcLangs = new TaskExecutorImpl(); - this.settings = settings; + this.settings.setAccount(account); this.tmcCore = new TmcCore(settings, tmcLangs); settings.setWorkDir(workDir); } private boolean createTmcCore() { - Settings cachedSettings = null; + Account cachedAccount = null; if (workDir.getConfigFile() != null) { // If we're in a course directory, we load settings matching the course // Otherwise we just load the last used settings courseInfo = getCourseInfo(); if (courseInfo != null) { - cachedSettings = SettingsIo.load(courseInfo.getUsername(), + cachedAccount = SettingsIo.load(courseInfo.getUsername(), courseInfo.getServerAddress()); } } else { // Bug: if we are not inside course directory // then we may not correctly guess the correct settings. - cachedSettings = SettingsIo.load(); - } - - hasLogin = true; - if (cachedSettings == null) { - hasLogin = false; - cachedSettings = new Settings(); + cachedAccount = SettingsIo.load(); } - createTmcCore(cachedSettings); + hasLogin = (cachedAccount != null); + createTmcCore(cachedAccount); return true; } } diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/backend/AccountTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/backend/AccountTest.java new file mode 100644 index 00000000..e7161f13 --- /dev/null +++ b/src/test/java/fi/helsinki/cs/tmc/cli/backend/AccountTest.java @@ -0,0 +1,35 @@ +package fi.helsinki.cs.tmc.cli.backend; + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + +public class AccountTest { + + private Account account; + + @Before + public void setUp() { + account = new Account("testserver", "testuser", "testpassword"); + } + + @Test + public void equalsWorksWithSameValues() { + Account compared = new Account("testserver", "testuser", "testpassword"); + assertEquals(true, account.equals(compared)); + } + + @Test + public void equalsWorksWithNull() { + Account compared = new Account(null, "testuser", "testpassword"); + assertEquals(false, account.equals(compared)); + } + + @Test + public void equalsWorksWithRandomValue() { + Account compared = new Account("xyz", "testuser", "testpassword"); + assertEquals(false, account.equals(compared)); + } + +} \ No newline at end of file diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/backend/SettingsIoTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/backend/SettingsIoTest.java index 9145434d..6bc70043 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/backend/SettingsIoTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/backend/SettingsIoTest.java @@ -5,8 +5,6 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import fi.helsinki.cs.tmc.core.configuration.TmcSettings; - import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; @@ -19,13 +17,13 @@ public class SettingsIoTest { - private Settings settings; + private Account account; private Path tempDir; @Before public void setUp() { tempDir = Paths.get(System.getProperty("java.io.tmpdir")).resolve(SettingsIo.CONFIG_DIR); - this.settings = new Settings("testserver", "testuser", "testpassword"); + account = new Account("testserver", "testuser", "testpassword"); try { FileUtils.deleteDirectory(tempDir.toFile()); } catch (Exception e) { } @@ -50,7 +48,7 @@ public void correctConfigPath() { @Test public void savingToFileWorks() { - Boolean success = SettingsIo.saveTo(settings, tempDir); + Boolean success = SettingsIo.saveTo(account, tempDir); assertTrue(success); Path path = tempDir .resolve(SettingsIo.ACCOUNTS_CONFIG); @@ -59,81 +57,81 @@ public void savingToFileWorks() { @Test public void loadingFromFileWorks() { - SettingsIo.saveTo(this.settings, tempDir); - TmcSettings loadedSettings; - loadedSettings = SettingsIo.loadFrom(tempDir); - assertNotNull(loadedSettings); - assertEquals(settings.getUsername(), loadedSettings.getUsername()); - assertEquals(settings.getPassword(), loadedSettings.getPassword()); - assertEquals(settings.getServerAddress(), loadedSettings.getServerAddress()); + SettingsIo.saveTo(account, tempDir); + Account loadedAccount; + loadedAccount = SettingsIo.loadFrom(tempDir); + assertNotNull(loadedAccount); + assertEquals(account.getUsername(), loadedAccount.getUsername()); + assertEquals(account.getPassword(), loadedAccount.getPassword()); + assertEquals(account.getServerAddress(), loadedAccount.getServerAddress()); } @Test public void loadingWhenNoFilePresentReturnsNull() { Path path = tempDir.getParent(); - TmcSettings loadedSettings = SettingsIo.loadFrom(path); - assertEquals(null, loadedSettings); + Account loadedAccount = SettingsIo.loadFrom(path); + assertEquals(null, loadedAccount); } @Test public void newHolderIsEmpty() { - SettingsHolder holder = new SettingsHolder(); - assertEquals(0, holder.settingsCount()); + AccountList holder = new AccountList(); + assertEquals(0, holder.accountCount()); } @Test - public void addingSettingsIncreasesHolderCount() { - SettingsHolder holder = new SettingsHolder(); - holder.addSettings(new Settings("eee", "aaa", "ooo")); - assertEquals(1, holder.settingsCount()); + public void addingAccountIncreasesHolderCount() { + AccountList holder = new AccountList(); + holder.addAccount(new Account("eee", "aaa", "ooo")); + assertEquals(1, holder.accountCount()); } @Test public void loadingFromHolderWorks() { - SettingsHolder holder = new SettingsHolder(); - holder.addSettings(this.settings); - Settings loaded = holder.getSettings(); - assertSame(this.settings, loaded); + AccountList holder = new AccountList(); + holder.addAccount(account); + Account loaded = holder.getAccount(); + assertSame(account, loaded); } @Test public void addingMoreThanOneSettingWorks() { - SettingsHolder holder = new SettingsHolder(); - holder.addSettings(this.settings); - holder.addSettings(new Settings("1", "2", "e")); - holder.addSettings(new Settings(":", "-", "D")); - assertEquals(3, holder.settingsCount()); + AccountList holder = new AccountList(); + holder.addAccount(account); + holder.addAccount(new Account("1", "2", "e")); + holder.addAccount(new Account(":", "-", "D")); + assertEquals(3, holder.accountCount()); } @Test - public void loadingLatestSettingsWorks() { - SettingsHolder holder = new SettingsHolder(); - holder.addSettings(new Settings(":", "-", "D")); - holder.addSettings(new Settings("1", "2", "e")); - holder.addSettings(this.settings); - Settings latest = holder.getSettings(); - assertSame(this.settings, latest); + public void loadingLatestAccountWorks() { + AccountList holder = new AccountList(); + holder.addAccount(new Account(":", "-", "D")); + holder.addAccount(new Account("1", "2", "e")); + holder.addAccount(account); + Account latest = holder.getAccount(); + assertSame(account, latest); } @Test - public void gettingSettingsByNameAndServerWorks() { - SettingsHolder holder = new SettingsHolder(); - Settings wanted = new Settings("1", "2", "e"); - holder.addSettings(new Settings(":", "-", "D")); - holder.addSettings(wanted); - holder.addSettings(new Settings("344", "wc", "fffssshhhh aaahhh")); - Settings get = holder.getSettings("2", "1"); + public void gettingAccountByNameAndServerWorks() { + AccountList holder = new AccountList(); + Account wanted = new Account("1", "2", "e"); + holder.addAccount(new Account(":", "-", "D")); + holder.addAccount(wanted); + holder.addAccount(new Account("344", "wc", "fffssshhhh aaahhh")); + Account get = holder.getAccount("2", "1"); assertSame(wanted, get); } @Test - public void gettingLatestSettingsSetsItToTheTop() { - SettingsHolder holder = new SettingsHolder(); - Settings wanted = new Settings("1", "2", "e"); - holder.addSettings(wanted); - holder.addSettings(new Settings(":", "-", "D")); - holder.getSettings("2", "1"); - Settings get = holder.getSettings(); + public void gettingLatestAccountSetsItToTheTop() { + AccountList holder = new AccountList(); + Account wanted = new Account("1", "2", "e"); + holder.addAccount(wanted); + holder.addAccount(new Account(":", "-", "D")); + holder.getAccount("2", "1"); + Account get = holder.getAccount(); assertSame(wanted, get); } diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/backend/SettingsTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/backend/SettingsTest.java index 5b612a6b..2a8bbafb 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/backend/SettingsTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/backend/SettingsTest.java @@ -1,6 +1,7 @@ package fi.helsinki.cs.tmc.cli.backend; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import fi.helsinki.cs.tmc.cli.io.EnvironmentUtil; @@ -27,21 +28,10 @@ public void constructorInitializesFields() { } @Test - public void equalsWorksWithSameValues() { - Settings compared = new Settings("testserver", "testuser", "testpassword"); - assertEquals(true, settings.equals(compared)); - } - - @Test - public void equalsWorksWithNull() { - Settings compared = new Settings(null, "testuser", "testpassword"); - assertEquals(false, settings.equals(compared)); - } - - @Test - public void equalsWorksWithRandomValue() { - Settings compared = new Settings("xyz", "testuser", "testpassword"); - assertEquals(false, settings.equals(compared)); + public void setAndGetAccount() { + Account account = new Account(); + settings.setAccount(account); + assertEquals(account, settings.getAccount()); } @Test @@ -59,6 +49,12 @@ public void correctClientName() { assertEquals("tmc_cli", settings.clientName()); } + @Test + public void userDataDoesntExistsIfUsernameAndPasswordAtStart() { + settings = new Settings(); + assertFalse(settings.userDataExists()); + } + @Test public void userDataExistsIfUsernameAndPasswordAreSet() { assertTrue(settings.userDataExists()); @@ -66,10 +62,8 @@ public void userDataExistsIfUsernameAndPasswordAreSet() { @Test public void userDataDoesNotExistIfUsernameIsNotSet() { - settings = new Settings("testserver", null, "testpassword"); - assertTrue(!settings.userDataExists()); - - settings = new Settings("testserver", "", "testpassword"); + Account account = new Account("testserver", null, "testpassword"); + settings.setAccount(account); assertTrue(!settings.userDataExists()); } @@ -80,16 +74,15 @@ public void formattedUserDataIsCorrectIfSet() { @Test public void formattedUserDataIsCorrectIfNotSet() { - settings = new Settings("testserver", null, "testpassword"); + Account account = new Account("testserver", null, "testpassword"); + settings.setAccount(account); assertEquals("", settings.getFormattedUserData()); } @Test public void userDataDoesNotExistIfPasswordIsNotSet() { - settings = new Settings("testserver", "testuser", null); - assertTrue(!settings.userDataExists()); - - settings = new Settings("testserver", "testuser", ""); + Account account = new Account("testserver", "testuser", null); + settings.setAccount(account); assertTrue(!settings.userDataExists()); } diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/backend/TmcUtilTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/backend/TmcUtilTest.java index 6370f97c..611a8be8 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/backend/TmcUtilTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/backend/TmcUtilTest.java @@ -110,12 +110,12 @@ public List call() throws Exception { public void failToLogin() throws URISyntaxException { when(mockCore.listCourses(any(ProgressObserver.class))) .thenReturn(createThrowingCallbackOfList(Course.class, "failed")); - Settings settings = new Settings(); - assertFalse(TmcUtil.tryToLogin(ctx, settings)); + Account account = new Account(); + assertFalse(TmcUtil.tryToLogin(ctx, account)); } @Test - public void tryToLoginCatchesObsoleteClientException() { + public void loginCatchesObsoleteClientException() { Callable> callable = new Callable>() { @Override public List call() throws Exception { @@ -129,13 +129,13 @@ public List call() throws Exception { when(app.runAutoUpdate()).thenReturn(true); when(mockCore.listCourses(any(ProgressObserver.class))) .thenReturn(callable); - TmcUtil.tryToLogin(ctx, new Settings()); + TmcUtil.tryToLogin(ctx, new Account()); io.assertContains("Your tmc-cli is outdated"); verify(app, times(1)).runAutoUpdate(); } @Test - public void tryToLoginCatchesFailedHttpResponseException() { + public void loginCatchesFailedHttpResponseException() { Callable> callable = new Callable>() { @Override public List call() throws Exception { @@ -146,7 +146,7 @@ public List call() throws Exception { when(mockCore.listCourses(any(ProgressObserver.class))) .thenReturn(callable); - TmcUtil.tryToLogin(ctx, new Settings()); + TmcUtil.tryToLogin(ctx, new Account()); io.assertContains("Incorrect username or password"); } diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommandTest.java index a35fa58a..b73d696f 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommandTest.java @@ -13,6 +13,7 @@ import static org.powermock.api.mockito.PowerMockito.verifyStatic; import fi.helsinki.cs.tmc.cli.Application; +import fi.helsinki.cs.tmc.cli.backend.Account; import fi.helsinki.cs.tmc.cli.backend.Settings; import fi.helsinki.cs.tmc.cli.backend.SettingsIo; import fi.helsinki.cs.tmc.cli.backend.TmcUtil; @@ -63,11 +64,12 @@ public void setUp() { mockCore = mock(TmcCore.class); ctx = new CliContext(io, mockCore, workDir); app = new Application(ctx); - Settings settings = new Settings("http://test.test", "", ""); + Account account = new Account("server", "user", "password"); + ctx.useAccount(account); mockStatic(TmcUtil.class); mockStatic(SettingsIo.class); - when(SettingsIo.getSettingsList()).thenReturn(Arrays.asList(settings)); + when(SettingsIo.getAccountList()).thenReturn(Arrays.asList(account)); } @After @@ -113,9 +115,6 @@ public void worksRightIfCourseIsFound() throws IOException { when(TmcUtil.downloadExercises(eq(ctx), anyListOf(Exercise.class), any(ProgressObserver.class))).thenReturn(exercises); - Settings settings = new Settings("server", "user", "password"); - ctx.useSettings(settings); - String[] args = {"download", "course1"}; app.run(args); @@ -132,6 +131,7 @@ public void filtersCompletedExercisesByDefault() throws ParseException { notCompleted.setCompleted(false); completed1.setCompleted(true); completed2.setCompleted(true); + workDir.setWorkdir(tempDir); List filteredExercises = Arrays.asList(notCompleted); @@ -142,10 +142,6 @@ public void filtersCompletedExercisesByDefault() throws ParseException { when(TmcUtil.downloadExercises(eq(ctx), anyListOf(Exercise.class), any(ProgressObserver.class))).thenReturn(filteredExercises); - Settings settings = new Settings("server", "user", "password"); - workDir.setWorkdir(tempDir); - ctx.useSettings(settings); - String[] args = {"download", "course1"}; app.run(args); @@ -161,6 +157,7 @@ public void getsAllExercisesWithAllSwitch() throws ParseException { notCompleted.setCompleted(false); completed1.setCompleted(true); completed2.setCompleted(true); + workDir.setWorkdir(tempDir); List exercises = Arrays.asList(completed1, notCompleted, completed2); @@ -171,10 +168,6 @@ public void getsAllExercisesWithAllSwitch() throws ParseException { when(TmcUtil.downloadExercises(eq(ctx), anyListOf(Exercise.class), any(ProgressObserver.class))).thenReturn(exercises); - Settings settings = new Settings("server", "user", "password"); - workDir.setWorkdir(tempDir); - ctx.useSettings(settings); - String[] args = {"download", "-a", "course1"}; app.run(args); @@ -191,15 +184,12 @@ public void failsToLoadExercises() throws ParseException { List downloaded = Arrays.asList(exercise1, exercise3); Course course = new Course("course1"); course.setExercises(exercises); + workDir.setWorkdir(tempDir); when(TmcUtil.findCourse(eq(ctx), eq("course1"))).thenReturn(course); when(TmcUtil.downloadExercises(eq(ctx), anyListOf(Exercise.class), any(ProgressObserver.class))).thenReturn(downloaded); - Settings settings = new Settings("server", "user", "password"); - workDir.setWorkdir(tempDir); - ctx.useSettings(settings); - String[] args = {"download", "course1"}; app.run(args); @@ -210,13 +200,13 @@ public void failsToLoadExercises() throws ParseException { @Test public void findFromMultipleServer() { - Settings settings1 = new Settings("http://test.test", "", ""); - Settings settings2 = new Settings("http://hello.test", "", ""); + Account account1 = new Account("http://test.test", "", ""); + Account account2 = new Account("http://hello.test", "", ""); when(TmcUtil.findCourse(eq(ctx), eq("course1"))).thenReturn(new Course("course1")) .thenReturn(new Course("course2")); - when(SettingsIo.getSettingsList()).thenReturn( - Arrays.asList(settings1, settings2)); + when(SettingsIo.getAccountList()).thenReturn( + Arrays.asList(account1, account2)); String[] args = {"download", "course2"}; app.run(args); @@ -224,13 +214,13 @@ public void findFromMultipleServer() { @Test public void findFromMultipleServerWithSameNameWithoutTakingAny() { - Settings settings1 = new Settings("http://test.test", "abc", ""); - Settings settings2 = new Settings("http://hello.test", "def", ""); + Account account1 = new Account("http://test.test", "abc", ""); + Account account2 = new Account("http://hello.test", "def", ""); when(TmcUtil.findCourse(eq(ctx), eq("course1"))).thenReturn(new Course("course1")) .thenReturn(new Course("course1")); - when(SettingsIo.getSettingsList()).thenReturn( - Arrays.asList(settings1, settings2)); + when(SettingsIo.getAccountList()).thenReturn( + Arrays.asList(account1, account2)); List exercises = Arrays.asList(); when(TmcUtil.downloadExercises(eq(ctx), anyListOf(Exercise.class), @@ -249,13 +239,13 @@ public void findFromMultipleServerWithSameNameWithoutTakingAny() { @Test public void findFromMultipleServerWithSameNameWithTakingFirst() { - Settings settings1 = new Settings("http://test.test", "abc", ""); - Settings settings2 = new Settings("http://hello.test", "def", ""); + Account account1 = new Account("http://test.test", "abc", ""); + Account account2 = new Account("http://hello.test", "def", ""); when(TmcUtil.findCourse(eq(ctx), eq("course1"))).thenReturn(new Course("course1")) .thenReturn(new Course("course1")); - when(SettingsIo.getSettingsList()).thenReturn( - Arrays.asList(settings1, settings2)); + when(SettingsIo.getAccountList()).thenReturn( + Arrays.asList(account1, account2)); String[] args = {"download", "course1"}; io.addConfirmationPrompt(true); @@ -270,6 +260,6 @@ public void findFromMultipleServerWithSameNameWithTakingFirst() { any(ProgressObserver.class)); Settings usedSettings = Whitebox.getInternalState(ctxCaptor.getValue(), "settings"); - assertEquals(settings1, usedSettings); + assertEquals(account1, usedSettings.getAccount()); } } diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java index 38df6106..03d56395 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java @@ -8,7 +8,7 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic; import fi.helsinki.cs.tmc.cli.Application; -import fi.helsinki.cs.tmc.cli.backend.Settings; +import fi.helsinki.cs.tmc.cli.backend.Account; import fi.helsinki.cs.tmc.cli.backend.SettingsIo; import fi.helsinki.cs.tmc.cli.backend.TmcUtil; import fi.helsinki.cs.tmc.cli.core.CliContext; @@ -41,11 +41,11 @@ public void setUp() { mockCore = mock(TmcCore.class); ctx = new CliContext(io, mockCore); app = new Application(ctx); - Settings settings = new Settings("http://test.test", "", ""); + Account account = new Account("http://test.test", "", ""); mockStatic(TmcUtil.class); mockStatic(SettingsIo.class); - when(SettingsIo.getSettingsList()).thenReturn(Arrays.asList(settings)); + when(SettingsIo.getAccountList()).thenReturn(Arrays.asList(account)); } @Test @@ -81,10 +81,10 @@ public void listCoursesWorksWithCourses() { @Test public void listCoursesWorksWithTwoServers() { - Settings settings1 = new Settings("http://test.test", "", ""); - Settings settings2 = new Settings("http://hello.test", "", ""); - when(SettingsIo.getSettingsList()).thenReturn( - Arrays.asList(settings1, settings2)); + Account account1 = new Account("http://test.test", "", ""); + Account account2 = new Account("http://hello.test", "", ""); + when(SettingsIo.getAccountList()).thenReturn( + Arrays.asList(account1, account2)); List list1 = Arrays.asList(new Course("course1")); List list2 = Arrays.asList(new Course("course2")); diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java index 37156d75..e2fa1d28 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java @@ -9,6 +9,7 @@ import static org.powermock.api.mockito.PowerMockito.verifyStatic; import fi.helsinki.cs.tmc.cli.Application; +import fi.helsinki.cs.tmc.cli.backend.Account; import fi.helsinki.cs.tmc.cli.backend.CourseInfo; import fi.helsinki.cs.tmc.cli.backend.Settings; import fi.helsinki.cs.tmc.cli.backend.SettingsIo; @@ -49,7 +50,7 @@ public void setUp() { mockStatic(TmcUtil.class); mockStatic(SettingsIo.class); - when(SettingsIo.save(any(Settings.class))).thenReturn(true); + when(SettingsIo.save(any(Account.class))).thenReturn(true); } @Test @@ -64,8 +65,8 @@ public void failIfBackendFails() { @Test public void logsInWithCorrectServerUserAndPassword() { - when(TmcUtil.tryToLogin(eq(ctx), any(Settings.class))).thenReturn(true); - when(SettingsIo.save(any(Settings.class))).thenReturn(true); + when(TmcUtil.tryToLogin(eq(ctx), any(Account.class))).thenReturn(true); + when(SettingsIo.save(any(Account.class))).thenReturn(true); String[] args = {"login", "-s", SERVER, "-u", USERNAME, "-p", PASSWORD}; app.run(args); io.assertContains("Login successful."); @@ -73,8 +74,8 @@ public void logsInWithCorrectServerUserAndPassword() { @Test public void userGetsErrorMessageIfLoginFails() { - when(TmcUtil.tryToLogin(eq(ctx), any(Settings.class))).thenReturn(true); - when(SettingsIo.save(any(Settings.class))).thenReturn(false); + when(TmcUtil.tryToLogin(eq(ctx), any(Account.class))).thenReturn(true); + when(SettingsIo.save(any(Account.class))).thenReturn(false); String[] args = {"login", "-s", SERVER, "-u", USERNAME, "-p", "WrongPassword"}; app.run(args); io.assertContains("Failed to write the accounts file."); @@ -82,7 +83,7 @@ public void userGetsErrorMessageIfLoginFails() { @Test public void loginAsksUsernameFromUserIfNotGiven() { - when(TmcUtil.tryToLogin(eq(ctx), any(Settings.class))).thenReturn(true); + when(TmcUtil.tryToLogin(eq(ctx), any(Account.class))).thenReturn(true); String[] args = {"login", "-s", SERVER, "-p", PASSWORD}; io.addLinePrompt(USERNAME); app.run(args); @@ -91,7 +92,7 @@ public void loginAsksUsernameFromUserIfNotGiven() { @Test public void loginAsksPasswordFromUserIfNotGiven() { - when(TmcUtil.tryToLogin(eq(ctx), any(Settings.class))).thenReturn(true); + when(TmcUtil.tryToLogin(eq(ctx), any(Account.class))).thenReturn(true); String[] args = {"login", "-s", SERVER, "-u", USERNAME}; io.addPasswordPrompt(PASSWORD); app.run(args); @@ -100,7 +101,7 @@ public void loginAsksPasswordFromUserIfNotGiven() { @Test public void loginAsksServerFromUserIfNotGiven() { - when(TmcUtil.tryToLogin(eq(ctx), any(Settings.class))).thenReturn(true); + when(TmcUtil.tryToLogin(eq(ctx), any(Account.class))).thenReturn(true); String[] args = {"login", "-p", PASSWORD, "-u", USERNAME}; io.addLinePrompt(SERVER); app.run(args); @@ -111,7 +112,7 @@ public void loginAsksServerFromUserIfNotGiven() { public void serverAndNotAskedAfterLogout() { TmcSettings settings = new Settings(SERVER, "username", "pass"); CourseInfo info = new CourseInfo(settings, null); - when(TmcUtil.tryToLogin(eq(ctx), any(Settings.class))).thenReturn(true); + when(TmcUtil.tryToLogin(eq(ctx), any(Account.class))).thenReturn(true); when(ctx.getCourseInfo()).thenReturn(info); String[] args = {"login"}; io.addPasswordPrompt(PASSWORD); @@ -123,14 +124,14 @@ public void serverAndNotAskedAfterLogout() { public void courseInfoValuesOverridedByOptions() { Settings settings = new Settings(SERVER, "username", "pass"); CourseInfo info = new CourseInfo(settings, null); - when(TmcUtil.tryToLogin(eq(ctx), any(Settings.class))).thenReturn(true); + when(TmcUtil.tryToLogin(eq(ctx), any(Account.class))).thenReturn(true); when(ctx.getCourseInfo()).thenReturn(info); String[] args = {"login", "-p", PASSWORD, "-u", USERNAME}; app.run(args); io.assertAllPromptsUsed(); - Settings expectedSettings = new Settings(SERVER, USERNAME, PASSWORD); + Account expectedAccount = new Account(SERVER, USERNAME, PASSWORD); verifyStatic(); - TmcUtil.tryToLogin(eq(ctx), eq(expectedSettings)); + TmcUtil.tryToLogin(eq(ctx), eq(expectedAccount)); } } diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/core/CliContextTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/core/CliContextTest.java index b392825e..e2ec04e1 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/core/CliContextTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/core/CliContextTest.java @@ -11,6 +11,7 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic; import fi.helsinki.cs.tmc.cli.Application; +import fi.helsinki.cs.tmc.cli.backend.Account; import fi.helsinki.cs.tmc.cli.backend.CourseInfo; import fi.helsinki.cs.tmc.cli.backend.CourseInfoIo; import fi.helsinki.cs.tmc.cli.backend.Settings; @@ -24,6 +25,7 @@ import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; import java.nio.file.Path; @@ -58,6 +60,18 @@ public void setAppAndGetIt() { assertEquals(app, ctx.getApp()); } + @Test + public void useDifferentAccount() { + CliContext ctx = new CliContext(io); + Application app = new Application(ctx); + Account account = new Account(); + + ctx.useAccount(account); + //TODO replace the Whitebox usage somehow + Settings usedSettings = Whitebox.getInternalState(ctx, "settings"); + assertEquals(account, usedSettings.getAccount()); + } + @Test(expected = RuntimeException.class) public void getAppWithoutSettingIt() { CliContext ctx = new CliContext(io); @@ -109,7 +123,7 @@ public void backendInitWithInternet() { Path path = mock(Path.class); when(CourseInfoIo.load(eq(path))).thenReturn(info); - when(SettingsIo.load(anyString(), anyString())).thenReturn(new Settings()); + when(SettingsIo.load(anyString(), anyString())).thenReturn(new Account()); when(workDir.getConfigFile()).thenReturn(path); CliContext ctx = new CliContext(io, null, workDir); @@ -173,7 +187,7 @@ public void backendInitWithoutInternetWithCourse() { Path path = mock(Path.class); when(CourseInfoIo.load(eq(path))).thenReturn(info); - when(SettingsIo.load(anyString(), anyString())).thenReturn(new Settings()); + when(SettingsIo.load(anyString(), anyString())).thenReturn(new Account()); when(workDir.getConfigFile()).thenReturn(path); CliContext ctx = new CliContext(io, null, workDir); From 243acd4f6eb55876b771306feadd61d5be6545e2 Mon Sep 17 00:00:00 2001 From: Aleksi Salmela Date: Sun, 10 Jul 2016 10:44:07 +0300 Subject: [PATCH 03/16] Add tests for account list and improve it's integration. --- .../cs/tmc/cli/backend/AccountList.java | 12 +- .../helsinki/cs/tmc/cli/backend/Settings.java | 2 +- .../cs/tmc/cli/backend/SettingsIo.java | 50 +++++---- .../cs/tmc/cli/command/LoginCommand.java | 8 +- .../helsinki/cs/tmc/cli/core/CliContext.java | 2 +- .../cs/tmc/cli/backend/AccountListTest.java | 104 ++++++++++++++++++ .../cs/tmc/cli/backend/SettingsIoTest.java | 104 ++++++------------ .../cs/tmc/cli/command/LoginCommandTest.java | 12 +- .../cs/tmc/cli/core/CliContextTest.java | 27 ++++- 9 files changed, 217 insertions(+), 104 deletions(-) create mode 100644 src/test/java/fi/helsinki/cs/tmc/cli/backend/AccountListTest.java diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/backend/AccountList.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/AccountList.java index e977d759..13a5ffd9 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/backend/AccountList.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/AccountList.java @@ -2,14 +2,15 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.List; /** * This is a class for storing all different accounts as a single array. */ -public class AccountList { +public class AccountList implements Iterable { - private ArrayList accountArray; + private List accountArray; public AccountList() { this.accountArray = new ArrayList<>(); @@ -70,11 +71,16 @@ public void deleteAllAccounts() { this.accountArray = new ArrayList<>(); } - public int accountCount() { + public int getAccountCount() { return this.accountArray.size(); } public List getAccountList() { return Collections.unmodifiableList(this.accountArray); } + + @Override + public Iterator iterator() { + return getAccountList().iterator(); + } } diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/backend/Settings.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/Settings.java index df8a7853..281e8996 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/backend/Settings.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/Settings.java @@ -112,7 +112,7 @@ public SystemDefaultRoutePlanner proxy() { @Override public Path getConfigRoot() { - return SettingsIo.getDefaultConfigRoot(); + return SettingsIo.getConfigDirectory(); } @Override diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java index 5e0f1ba4..7402a0a3 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java @@ -36,11 +36,32 @@ public class SettingsIo { // was last updated. Is located under CONFIG_DIR public static final String PROPERTIES_CONFIG = "properties.json"; + public static AccountList loadAccountList() { + return loadAccountList(getConfigDirectory()); + } + + public static AccountList loadAccountList(Path configRoot) { + Path file = getAccountsFile(configRoot); + if (!Files.exists(file)) { + return new AccountList(); + } + return getHolderFromJson(file); + } + + public static boolean saveAccountList(AccountList list) { + return saveAccountList(list, getConfigDirectory()); + } + + public static boolean saveAccountList(AccountList list, Path configRoot) { + Path file = getAccountsFile(configRoot); + return saveHolderToJson(list, file); + } + /** * Get the correct directory in which our config files go * ie. /home/user/.config/tmc-cli/ */ - public static Path getDefaultConfigRoot() { + protected static Path getConfigDirectory() { Path configPath; if (EnvironmentUtil.isWindows()) { String appdata = System.getenv("APPDATA"); @@ -89,10 +110,7 @@ private static Path getPropertiesFile(Path configRoot) { return file; } - public static Boolean save(Account account) { - return saveTo(account, getDefaultConfigRoot()); - } - + @Deprecated public static Boolean saveTo(Account account, Path configRoot) { Path file = getAccountsFile(configRoot); AccountList holder; @@ -105,19 +123,12 @@ public static Boolean saveTo(Account account, Path configRoot) { return saveHolderToJson(holder, file); } + @Deprecated public static Account load(String username, String server) { - return loadFrom(username, server, getDefaultConfigRoot()); - } - - public static Account load() { - // Calling the method without parametres returns the last used account - return load(null, null); - } - - public static Account loadFrom(Path configRoot) { - return loadFrom(null, null, configRoot); + return loadFrom(username, server, getConfigDirectory()); } + @Deprecated public static Account loadFrom(String username, String server, Path configRoot) { Path file = getAccountsFile(configRoot); if (!Files.exists(file)) { @@ -129,8 +140,9 @@ public static Account loadFrom(String username, String server, Path configRoot) return ret; } + @Deprecated public static List getAccountList() { - Path file = getAccountsFile(getDefaultConfigRoot()); + Path file = getAccountsFile(getConfigDirectory()); if (!Files.exists(file)) { return null; } @@ -189,7 +201,7 @@ private static Boolean savePropertiesToJson(HashMap properties, } public static Boolean delete() { - Path file = getAccountsFile(getDefaultConfigRoot()); + Path file = getAccountsFile(getConfigDirectory()); try { Files.deleteIfExists(file); } catch (IOException e) { @@ -200,7 +212,7 @@ public static Boolean delete() { } public static HashMap loadProperties() { - return loadPropertiesFrom(getDefaultConfigRoot()); + return loadPropertiesFrom(getConfigDirectory()); } public static HashMap loadPropertiesFrom(Path path) { @@ -214,7 +226,7 @@ public static HashMap loadPropertiesFrom(Path path) { } public static Boolean saveProperties(HashMap properties) { - return savePropertiesTo(properties, getDefaultConfigRoot()); + return savePropertiesTo(properties, getConfigDirectory()); } public static Boolean savePropertiesTo(HashMap properties, Path path) { diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java index 6850c038..5694e990 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java @@ -1,6 +1,7 @@ package fi.helsinki.cs.tmc.cli.command; import fi.helsinki.cs.tmc.cli.backend.Account; +import fi.helsinki.cs.tmc.cli.backend.AccountList; import fi.helsinki.cs.tmc.cli.backend.CourseInfo; import fi.helsinki.cs.tmc.cli.backend.SettingsIo; import fi.helsinki.cs.tmc.cli.backend.TmcUtil; @@ -38,6 +39,8 @@ public void run(CommandLine args, Io io) { return; } + //TODO try to login so that user won't type inputs if internet + // doesn't work. CourseInfo info = ctx.getCourseInfo(); if (info != null) { serverAddress = info.getServerAddress(); @@ -52,7 +55,10 @@ public void run(CommandLine args, Io io) { if (!TmcUtil.tryToLogin(ctx, account)) { return; } - if (!SettingsIo.save(account)) { + + AccountList list = SettingsIo.loadAccountList(); + list.addAccount(account); + if (!SettingsIo.saveAccountList(list)) { io.println("Failed to write the accounts file."); return; } 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 82473f5b..2731a108 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 @@ -246,7 +246,7 @@ private boolean createTmcCore() { } else { // Bug: if we are not inside course directory // then we may not correctly guess the correct settings. - cachedAccount = SettingsIo.load(); + cachedAccount = SettingsIo.load(null, null); } hasLogin = (cachedAccount != null); diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/backend/AccountListTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/backend/AccountListTest.java new file mode 100644 index 00000000..e1a9d681 --- /dev/null +++ b/src/test/java/fi/helsinki/cs/tmc/cli/backend/AccountListTest.java @@ -0,0 +1,104 @@ +package fi.helsinki.cs.tmc.cli.backend; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; + +import org.junit.Before; +import org.junit.Test; + +import java.util.Iterator; + +public class AccountListTest { + + private AccountList list; + private Account account; + + @Before + public void setUp() { + list = new AccountList(); + account = new Account("testserver", "testuser", "testpassword"); + } + + @Test + public void newHolderIsEmpty() { + assertEquals(0, list.getAccountCount()); + } + + @Test + public void addingAccountIncreasesHolderCount() { + list.addAccount(new Account("eee", "aaa", "ooo")); + assertEquals(1, list.getAccountCount()); + } + + @Test + public void loadingFromHolderWorks() { + list.addAccount(account); + Account loaded = list.getAccount(); + assertSame(account, loaded); + } + + @Test + public void addingMoreThanOneSettingWorks() { + list.addAccount(account); + list.addAccount(new Account("1", "2", "e")); + list.addAccount(new Account(":", "-", "D")); + assertEquals(3, list.getAccountCount()); + } + + @Test + public void loadingLatestAccountWorks() { + list.addAccount(new Account(":", "-", "D")); + list.addAccount(new Account("1", "2", "e")); + list.addAccount(account); + Account latest = list.getAccount(); + assertSame(account, latest); + } + + @Test + public void gettingAccountByNameAndServerWorks() { + Account wanted = new Account("1", "2", "e"); + list.addAccount(new Account(":", "-", "D")); + list.addAccount(wanted); + list.addAccount(new Account("344", "wc", "fffssshhhh aaahhh")); + Account get = list.getAccount("2", "1"); + assertSame(wanted, get); + } + + @Test + public void gettingLatestAccountSetsItToTheTop() { + Account wanted = new Account("1", "2", "e"); + list.addAccount(wanted); + list.addAccount(new Account(":", "-", "D")); + list.getAccount("2", "1"); + Account get = list.getAccount(); + assertSame(wanted, get); + } + + @Test + public void iterateOverZeroAccounts() { + Iterator iterator = list.iterator(); + assertEquals(false, iterator.hasNext()); + } + + @Test + public void iterateOverOneAccount() { + list.addAccount(account); + Iterator iterator = list.iterator(); + assertEquals(true, iterator.hasNext()); + assertEquals(account, iterator.next()); + assertEquals(false, iterator.hasNext()); + } + + @Test + public void iterateOverTwoAccounts() { + Account account2 = new Account("1", "2", "e"); + list.addAccount(account); + list.addAccount(account2); + Iterator iterator = list.iterator(); + assertEquals(true, iterator.hasNext()); + assertEquals(account2, iterator.next()); + assertEquals(true, iterator.hasNext()); + assertEquals(account, iterator.next()); + assertEquals(false, iterator.hasNext()); + } +} diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/backend/SettingsIoTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/backend/SettingsIoTest.java index 6bc70043..0a7eda4d 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/backend/SettingsIoTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/backend/SettingsIoTest.java @@ -2,7 +2,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import org.apache.commons.io.FileUtils; @@ -17,6 +16,7 @@ public class SettingsIoTest { + private AccountList accountList; private Account account; private Path tempDir; @@ -24,6 +24,7 @@ public class SettingsIoTest { public void setUp() { tempDir = Paths.get(System.getProperty("java.io.tmpdir")).resolve(SettingsIo.CONFIG_DIR); account = new Account("testserver", "testuser", "testpassword"); + accountList = new AccountList(); try { FileUtils.deleteDirectory(tempDir.toFile()); } catch (Exception e) { } @@ -38,7 +39,7 @@ public void cleanUp() { @Test public void correctConfigPath() { - Path path = SettingsIo.getDefaultConfigRoot(); + Path path = SettingsIo.getConfigDirectory(); String fs = System.getProperty("file.separator"); assertTrue(path.toString().contains(SettingsIo.CONFIG_DIR)); assertTrue(path.toString().contains(fs)); @@ -47,8 +48,8 @@ public void correctConfigPath() { } @Test - public void savingToFileWorks() { - Boolean success = SettingsIo.saveTo(account, tempDir); + public void saveZeroAccountsToFile() { + boolean success = SettingsIo.saveAccountList(accountList, tempDir); assertTrue(success); Path path = tempDir .resolve(SettingsIo.ACCOUNTS_CONFIG); @@ -56,83 +57,42 @@ public void savingToFileWorks() { } @Test - public void loadingFromFileWorks() { - SettingsIo.saveTo(account, tempDir); - Account loadedAccount; - loadedAccount = SettingsIo.loadFrom(tempDir); - assertNotNull(loadedAccount); - assertEquals(account.getUsername(), loadedAccount.getUsername()); - assertEquals(account.getPassword(), loadedAccount.getPassword()); - assertEquals(account.getServerAddress(), loadedAccount.getServerAddress()); - } - - @Test - public void loadingWhenNoFilePresentReturnsNull() { - Path path = tempDir.getParent(); - Account loadedAccount = SettingsIo.loadFrom(path); - assertEquals(null, loadedAccount); - } - - @Test - public void newHolderIsEmpty() { - AccountList holder = new AccountList(); - assertEquals(0, holder.accountCount()); - } - - @Test - public void addingAccountIncreasesHolderCount() { - AccountList holder = new AccountList(); - holder.addAccount(new Account("eee", "aaa", "ooo")); - assertEquals(1, holder.accountCount()); - } - - @Test - public void loadingFromHolderWorks() { - AccountList holder = new AccountList(); - holder.addAccount(account); - Account loaded = holder.getAccount(); - assertSame(account, loaded); - } - - @Test - public void addingMoreThanOneSettingWorks() { - AccountList holder = new AccountList(); - holder.addAccount(account); - holder.addAccount(new Account("1", "2", "e")); - holder.addAccount(new Account(":", "-", "D")); - assertEquals(3, holder.accountCount()); + public void saveOneAccountToFile() { + accountList.addAccount(account); + boolean success = SettingsIo.saveAccountList(accountList, tempDir); + assertTrue(success); + Path path = tempDir + .resolve(SettingsIo.ACCOUNTS_CONFIG); + assertTrue(Files.exists(path)); } @Test - public void loadingLatestAccountWorks() { - AccountList holder = new AccountList(); - holder.addAccount(new Account(":", "-", "D")); - holder.addAccount(new Account("1", "2", "e")); - holder.addAccount(account); - Account latest = holder.getAccount(); - assertSame(account, latest); + public void saveAndLoadZeroAccountsFromFile() { + boolean success = SettingsIo.saveAccountList(accountList, tempDir); + AccountList loadedList = SettingsIo.loadAccountList(tempDir); + assertNotNull(loadedList); + assertEquals(0, loadedList.getAccountCount()); } @Test - public void gettingAccountByNameAndServerWorks() { - AccountList holder = new AccountList(); - Account wanted = new Account("1", "2", "e"); - holder.addAccount(new Account(":", "-", "D")); - holder.addAccount(wanted); - holder.addAccount(new Account("344", "wc", "fffssshhhh aaahhh")); - Account get = holder.getAccount("2", "1"); - assertSame(wanted, get); + public void saveAndLoadOneAccountFromFile() { + accountList.addAccount(account); + boolean success = SettingsIo.saveAccountList(accountList, tempDir); + AccountList loadedList = SettingsIo.loadAccountList(tempDir); + assertNotNull(loadedList); + assertEquals(1, loadedList.getAccountCount()); + Account loadedAccount = loadedList.iterator().next(); + assertEquals(account.getUsername(), loadedAccount.getUsername()); + assertEquals(account.getPassword(), loadedAccount.getPassword()); + assertEquals(account.getServerAddress(), loadedAccount.getServerAddress()); } @Test - public void gettingLatestAccountSetsItToTheTop() { - AccountList holder = new AccountList(); - Account wanted = new Account("1", "2", "e"); - holder.addAccount(wanted); - holder.addAccount(new Account(":", "-", "D")); - holder.getAccount("2", "1"); - Account get = holder.getAccount(); - assertSame(wanted, get); + public void loadingWhenNoFilePresentReturnsNull() { + Path path = tempDir.getParent(); + AccountList loadedList = SettingsIo.loadAccountList(path); + assertNotNull(loadedList); + assertEquals(0, loadedList.getAccountCount()); } @Test diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java index e2fa1d28..853490f1 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java @@ -10,6 +10,7 @@ import fi.helsinki.cs.tmc.cli.Application; import fi.helsinki.cs.tmc.cli.backend.Account; +import fi.helsinki.cs.tmc.cli.backend.AccountList; import fi.helsinki.cs.tmc.cli.backend.CourseInfo; import fi.helsinki.cs.tmc.cli.backend.Settings; import fi.helsinki.cs.tmc.cli.backend.SettingsIo; @@ -23,7 +24,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; - import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @@ -50,7 +50,8 @@ public void setUp() { mockStatic(TmcUtil.class); mockStatic(SettingsIo.class); - when(SettingsIo.save(any(Account.class))).thenReturn(true); + when(SettingsIo.loadAccountList()).thenReturn(new AccountList()); + when(SettingsIo.saveAccountList(any(AccountList.class))).thenReturn(true); } @Test @@ -66,7 +67,7 @@ public void failIfBackendFails() { @Test public void logsInWithCorrectServerUserAndPassword() { when(TmcUtil.tryToLogin(eq(ctx), any(Account.class))).thenReturn(true); - when(SettingsIo.save(any(Account.class))).thenReturn(true); + when(SettingsIo.saveAccountList(any(AccountList.class))).thenReturn(true); String[] args = {"login", "-s", SERVER, "-u", USERNAME, "-p", PASSWORD}; app.run(args); io.assertContains("Login successful."); @@ -75,7 +76,7 @@ public void logsInWithCorrectServerUserAndPassword() { @Test public void userGetsErrorMessageIfLoginFails() { when(TmcUtil.tryToLogin(eq(ctx), any(Account.class))).thenReturn(true); - when(SettingsIo.save(any(Account.class))).thenReturn(false); + when(SettingsIo.saveAccountList(any(AccountList.class))).thenReturn(false); String[] args = {"login", "-s", SERVER, "-u", USERNAME, "-p", "WrongPassword"}; app.run(args); io.assertContains("Failed to write the accounts file."); @@ -83,7 +84,8 @@ public void userGetsErrorMessageIfLoginFails() { @Test public void loginAsksUsernameFromUserIfNotGiven() { - when(TmcUtil.tryToLogin(eq(ctx), any(Account.class))).thenReturn(true); + when(SettingsIo.loadAccountList()).thenReturn(new AccountList()); + when(SettingsIo.saveAccountList(any(AccountList.class))).thenReturn(true); String[] args = {"login", "-s", SERVER, "-p", PASSWORD}; io.addLinePrompt(USERNAME); app.run(args); diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/core/CliContextTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/core/CliContextTest.java index e2ec04e1..25992900 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/core/CliContextTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/core/CliContextTest.java @@ -4,6 +4,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; @@ -123,7 +124,8 @@ public void backendInitWithInternet() { Path path = mock(Path.class); when(CourseInfoIo.load(eq(path))).thenReturn(info); - when(SettingsIo.load(anyString(), anyString())).thenReturn(new Account()); + when(SettingsIo.load(anyString(), anyString())) + .thenReturn(new Account()); when(workDir.getConfigFile()).thenReturn(path); CliContext ctx = new CliContext(io, null, workDir); @@ -131,6 +133,26 @@ public void backendInitWithInternet() { assertEquals(true, ctx.hasLogin()); } + @Test + public void failBackendInitWithCourseButWithoutInternet() { + mockStatic(CourseInfoIo.class); + mockStatic(SettingsIo.class); + + WorkDir workDir = mock(WorkDir.class); + Path path = mock(Path.class); + CourseInfo info = mock(CourseInfo.class); + + when(info.getUsername()).thenReturn("user"); + when(CourseInfoIo.load(eq(path))).thenReturn(info); + when(workDir.getConfigFile()).thenReturn(path); + when(SettingsIo.load(anyString(), anyString())).thenReturn(null); + CliContext ctx = new CliContext(io, null, workDir); + + assertFalse(ctx.loadBackend()); + assertEquals(false, ctx.hasLogin()); + io.assertContains("You are not logged in as user. Log in using: tmc login"); + } + @Test public void failBackendInitWithInternetButWithoutCourse() { mockStatic(CourseInfoIo.class); @@ -170,7 +192,8 @@ public void backendInitWithoutInternet() { WorkDir workDir = mock(WorkDir.class); when(workDir.getConfigFile()).thenReturn(null); - when(SettingsIo.load()).thenReturn(null); + when(SettingsIo.loadFrom(anyString(), anyString(), any(Path.class))) + .thenReturn(null); CliContext ctx = new CliContext(io, null, workDir); assertTrue(ctx.loadBackendWithoutLogin()); From b93afbcae52fe72f1b40223f177c0522155b12f4 Mon Sep 17 00:00:00 2001 From: Aleksi Salmela Date: Sun, 10 Jul 2016 12:15:03 +0300 Subject: [PATCH 04/16] Remove deprecated SettingsIo methods. --- .../cs/tmc/cli/backend/SettingsIo.java | 54 +++---------------- .../cli/command/DownloadExercisesCommand.java | 8 ++- .../tmc/cli/command/ListCoursesCommand.java | 10 +++- .../cs/tmc/cli/command/LoginCommand.java | 2 +- .../helsinki/cs/tmc/cli/core/CliContext.java | 6 ++- .../command/DownloadExercisesCommandTest.java | 23 +++++--- .../cli/command/ListCoursesCommandTest.java | 12 +++-- .../cs/tmc/cli/core/CliContextTest.java | 23 +++----- 8 files changed, 61 insertions(+), 77 deletions(-) diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java index 7402a0a3..25732c14 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java @@ -59,7 +59,7 @@ public static boolean saveAccountList(AccountList list, Path configRoot) { /** * Get the correct directory in which our config files go - * ie. /home/user/.config/tmc-cli/ + * ie /home/user/.config/tmc-cli/. */ protected static Path getConfigDirectory() { Path configPath; @@ -84,6 +84,7 @@ protected static Path getConfigDirectory() { return configPath.resolve(CONFIG_DIR); } + //TODO handle exceptions private static Path getAccountsFile(Path configRoot) { Path file = configRoot.resolve(ACCOUNTS_CONFIG); if (!Files.exists(configRoot)) { @@ -97,6 +98,7 @@ private static Path getAccountsFile(Path configRoot) { return file; } + //TODO handle exceptions private static Path getPropertiesFile(Path configRoot) { Path file = configRoot.resolve(PROPERTIES_CONFIG); if (!Files.exists(configRoot)) { @@ -110,46 +112,6 @@ private static Path getPropertiesFile(Path configRoot) { return file; } - @Deprecated - public static Boolean saveTo(Account account, Path configRoot) { - Path file = getAccountsFile(configRoot); - AccountList holder; - if (!Files.exists(file)) { - holder = new AccountList(); - } else { - holder = getHolderFromJson(file); - } - holder.addAccount(account); - return saveHolderToJson(holder, file); - } - - @Deprecated - public static Account load(String username, String server) { - return loadFrom(username, server, getConfigDirectory()); - } - - @Deprecated - public static Account loadFrom(String username, String server, Path configRoot) { - Path file = getAccountsFile(configRoot); - if (!Files.exists(file)) { - return null; - } - AccountList holder = getHolderFromJson(file); - Account ret = holder.getAccount(username, server); - saveHolderToJson(holder, file); - return ret; - } - - @Deprecated - public static List getAccountList() { - Path file = getAccountsFile(getConfigDirectory()); - if (!Files.exists(file)) { - return null; - } - AccountList holder = getHolderFromJson(file); - return holder.getAccountList(); - } - private static AccountList getHolderFromJson(Path file) { Gson gson = new Gson(); Reader reader; @@ -162,7 +124,7 @@ private static AccountList getHolderFromJson(Path file) { return gson.fromJson(reader, AccountList.class); } - private static Boolean saveHolderToJson(AccountList holder, Path file) { + private static boolean saveHolderToJson(AccountList holder, Path file) { Gson gson = new Gson(); byte[] json = gson.toJson(holder).getBytes(); try { @@ -188,7 +150,7 @@ private static HashMap getPropertiesFromJson(Path file) { return map; } - private static Boolean savePropertiesToJson(HashMap properties, Path file) { + private static boolean savePropertiesToJson(HashMap properties, Path file) { Gson gson = new Gson(); byte[] json = gson.toJson(properties).getBytes(); try { @@ -200,7 +162,7 @@ private static Boolean savePropertiesToJson(HashMap properties, return true; } - public static Boolean delete() { + public static boolean delete() { Path file = getAccountsFile(getConfigDirectory()); try { Files.deleteIfExists(file); @@ -225,11 +187,11 @@ public static HashMap loadPropertiesFrom(Path path) { } } - public static Boolean saveProperties(HashMap properties) { + public static boolean saveProperties(HashMap properties) { return savePropertiesTo(properties, getConfigDirectory()); } - public static Boolean savePropertiesTo(HashMap properties, Path path) { + public static boolean savePropertiesTo(HashMap properties, Path path) { Path file = getPropertiesFile(path); return savePropertiesToJson(properties, file); } diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java index 7c81ae68..c29e84ee 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java @@ -1,6 +1,7 @@ package fi.helsinki.cs.tmc.cli.command; import fi.helsinki.cs.tmc.cli.backend.Account; +import fi.helsinki.cs.tmc.cli.backend.AccountList; import fi.helsinki.cs.tmc.cli.backend.CourseInfo; import fi.helsinki.cs.tmc.cli.backend.CourseInfoIo; import fi.helsinki.cs.tmc.cli.backend.SettingsIo; @@ -90,10 +91,15 @@ public void run(CommandLine args, Io io) { private Course findCourse(String courseName) { Io io = ctx.getIo(); - List accountsList = SettingsIo.getAccountList(); + AccountList accountsList = SettingsIo.loadAccountList(); // LinkedHashMap is used here to preserve ordering. Map matches = new LinkedHashMap<>(); + if (accountsList.getAccountCount() == 0) { + io.println("You haven't logged in on any tmc server."); + return null; + } + for (Account settings : accountsList) { ctx.useAccount(settings); Course course = TmcUtil.findCourse(ctx, courseName); diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java index 2a5c422b..fc6afbbf 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java @@ -1,6 +1,7 @@ package fi.helsinki.cs.tmc.cli.command; import fi.helsinki.cs.tmc.cli.backend.Account; +import fi.helsinki.cs.tmc.cli.backend.AccountList; import fi.helsinki.cs.tmc.cli.backend.SettingsIo; import fi.helsinki.cs.tmc.cli.backend.TmcUtil; import fi.helsinki.cs.tmc.cli.core.AbstractCommand; @@ -38,14 +39,19 @@ public void run(CommandLine args, Io io) { return; } - List accountsList = SettingsIo.getAccountList(); + AccountList accountsList = SettingsIo.loadAccountList(); boolean isFirst = true; + if (accountsList.getAccountCount() == 0) { + io.println("You haven't logged in on any tmc server."); + return; + } + for (Account settings : accountsList) { if (!isFirst) { io.println(""); } - if (accountsList.size() > 1) { + if (accountsList.getAccountCount() > 1) { io.println(Color.colorString("Server " + settings.getServerAddress(), Color.AnsiColor.ANSI_YELLOW)); } diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java index 5694e990..5241a391 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java @@ -39,7 +39,7 @@ public void run(CommandLine args, Io io) { return; } - //TODO try to login so that user won't type inputs if internet + //TODO try to login so that user won't fill the fields if internet // doesn't work. CourseInfo info = ctx.getCourseInfo(); if (info != null) { 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 2731a108..94f2adda 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 @@ -2,6 +2,7 @@ import fi.helsinki.cs.tmc.cli.Application; import fi.helsinki.cs.tmc.cli.backend.Account; +import fi.helsinki.cs.tmc.cli.backend.AccountList; import fi.helsinki.cs.tmc.cli.backend.CourseInfo; import fi.helsinki.cs.tmc.cli.backend.CourseInfoIo; import fi.helsinki.cs.tmc.cli.backend.Settings; @@ -234,19 +235,20 @@ private void createTmcCore(Account account) { private boolean createTmcCore() { Account cachedAccount = null; + AccountList list = SettingsIo.loadAccountList(); if (workDir.getConfigFile() != null) { // If we're in a course directory, we load settings matching the course // Otherwise we just load the last used settings courseInfo = getCourseInfo(); if (courseInfo != null) { - cachedAccount = SettingsIo.load(courseInfo.getUsername(), + cachedAccount = list.getAccount(courseInfo.getUsername(), courseInfo.getServerAddress()); } } else { // Bug: if we are not inside course directory // then we may not correctly guess the correct settings. - cachedAccount = SettingsIo.load(null, null); + cachedAccount = list.getAccount(); } hasLogin = (cachedAccount != null); diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommandTest.java index b73d696f..5387a3f2 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommandTest.java @@ -14,6 +14,7 @@ import fi.helsinki.cs.tmc.cli.Application; import fi.helsinki.cs.tmc.cli.backend.Account; +import fi.helsinki.cs.tmc.cli.backend.AccountList; import fi.helsinki.cs.tmc.cli.backend.Settings; import fi.helsinki.cs.tmc.cli.backend.SettingsIo; import fi.helsinki.cs.tmc.cli.backend.TmcUtil; @@ -66,10 +67,12 @@ public void setUp() { app = new Application(ctx); Account account = new Account("server", "user", "password"); ctx.useAccount(account); + AccountList accountList = new AccountList(); + accountList.addAccount(account); mockStatic(TmcUtil.class); mockStatic(SettingsIo.class); - when(SettingsIo.getAccountList()).thenReturn(Arrays.asList(account)); + when(SettingsIo.loadAccountList()).thenReturn(accountList); } @After @@ -202,11 +205,13 @@ public void failsToLoadExercises() throws ParseException { public void findFromMultipleServer() { Account account1 = new Account("http://test.test", "", ""); Account account2 = new Account("http://hello.test", "", ""); + AccountList accountList = new AccountList(); + accountList.addAccount(account1); + accountList.addAccount(account2); when(TmcUtil.findCourse(eq(ctx), eq("course1"))).thenReturn(new Course("course1")) .thenReturn(new Course("course2")); - when(SettingsIo.getAccountList()).thenReturn( - Arrays.asList(account1, account2)); + when(SettingsIo.loadAccountList()).thenReturn(accountList); String[] args = {"download", "course2"}; app.run(args); @@ -216,11 +221,13 @@ public void findFromMultipleServer() { public void findFromMultipleServerWithSameNameWithoutTakingAny() { Account account1 = new Account("http://test.test", "abc", ""); Account account2 = new Account("http://hello.test", "def", ""); + AccountList accountList = new AccountList(); + accountList.addAccount(account1); + accountList.addAccount(account2); when(TmcUtil.findCourse(eq(ctx), eq("course1"))).thenReturn(new Course("course1")) .thenReturn(new Course("course1")); - when(SettingsIo.getAccountList()).thenReturn( - Arrays.asList(account1, account2)); + when(SettingsIo.loadAccountList()).thenReturn(accountList); List exercises = Arrays.asList(); when(TmcUtil.downloadExercises(eq(ctx), anyListOf(Exercise.class), @@ -241,11 +248,13 @@ public void findFromMultipleServerWithSameNameWithoutTakingAny() { public void findFromMultipleServerWithSameNameWithTakingFirst() { Account account1 = new Account("http://test.test", "abc", ""); Account account2 = new Account("http://hello.test", "def", ""); + AccountList accountList = new AccountList(); + accountList.addAccount(account2); + accountList.addAccount(account1); when(TmcUtil.findCourse(eq(ctx), eq("course1"))).thenReturn(new Course("course1")) .thenReturn(new Course("course1")); - when(SettingsIo.getAccountList()).thenReturn( - Arrays.asList(account1, account2)); + when(SettingsIo.loadAccountList()).thenReturn(accountList); String[] args = {"download", "course1"}; io.addConfirmationPrompt(true); diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java index 03d56395..24828976 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java @@ -9,6 +9,7 @@ import fi.helsinki.cs.tmc.cli.Application; import fi.helsinki.cs.tmc.cli.backend.Account; +import fi.helsinki.cs.tmc.cli.backend.AccountList; import fi.helsinki.cs.tmc.cli.backend.SettingsIo; import fi.helsinki.cs.tmc.cli.backend.TmcUtil; import fi.helsinki.cs.tmc.cli.core.CliContext; @@ -42,10 +43,12 @@ public void setUp() { ctx = new CliContext(io, mockCore); app = new Application(ctx); Account account = new Account("http://test.test", "", ""); + AccountList accountList = new AccountList(); + accountList.addAccount(account); mockStatic(TmcUtil.class); mockStatic(SettingsIo.class); - when(SettingsIo.getAccountList()).thenReturn(Arrays.asList(account)); + when(SettingsIo.loadAccountList()).thenReturn(accountList); } @Test @@ -83,8 +86,11 @@ public void listCoursesWorksWithCourses() { public void listCoursesWorksWithTwoServers() { Account account1 = new Account("http://test.test", "", ""); Account account2 = new Account("http://hello.test", "", ""); - when(SettingsIo.getAccountList()).thenReturn( - Arrays.asList(account1, account2)); + + AccountList accountList = new AccountList(); + accountList.addAccount(account1); + accountList.addAccount(account2); + when(SettingsIo.loadAccountList()).thenReturn(accountList); List list1 = Arrays.asList(new Course("course1")); List list2 = Arrays.asList(new Course("course2")); diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/core/CliContextTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/core/CliContextTest.java index 25992900..df141d7f 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/core/CliContextTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/core/CliContextTest.java @@ -4,8 +4,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -13,6 +11,7 @@ import fi.helsinki.cs.tmc.cli.Application; import fi.helsinki.cs.tmc.cli.backend.Account; +import fi.helsinki.cs.tmc.cli.backend.AccountList; import fi.helsinki.cs.tmc.cli.backend.CourseInfo; import fi.helsinki.cs.tmc.cli.backend.CourseInfoIo; import fi.helsinki.cs.tmc.cli.backend.Settings; @@ -35,10 +34,15 @@ public class CliContextTest { private TestIo io; + private AccountList list; @Before public void setUp() { io = new TestIo(); + list = new AccountList(); + + mockStatic(SettingsIo.class); + when(SettingsIo.loadAccountList()).thenReturn(list); } @Test @@ -117,15 +121,13 @@ public void getCourseInfoWhenItDoesntExist() { @Test public void backendInitWithInternet() { mockStatic(CourseInfoIo.class); - mockStatic(SettingsIo.class); CourseInfo info = mock(CourseInfo.class); WorkDir workDir = mock(WorkDir.class); Path path = mock(Path.class); + list.addAccount(new Account()); when(CourseInfoIo.load(eq(path))).thenReturn(info); - when(SettingsIo.load(anyString(), anyString())) - .thenReturn(new Account()); when(workDir.getConfigFile()).thenReturn(path); CliContext ctx = new CliContext(io, null, workDir); @@ -136,7 +138,6 @@ public void backendInitWithInternet() { @Test public void failBackendInitWithCourseButWithoutInternet() { mockStatic(CourseInfoIo.class); - mockStatic(SettingsIo.class); WorkDir workDir = mock(WorkDir.class); Path path = mock(Path.class); @@ -145,7 +146,6 @@ public void failBackendInitWithCourseButWithoutInternet() { when(info.getUsername()).thenReturn("user"); when(CourseInfoIo.load(eq(path))).thenReturn(info); when(workDir.getConfigFile()).thenReturn(path); - when(SettingsIo.load(anyString(), anyString())).thenReturn(null); CliContext ctx = new CliContext(io, null, workDir); assertFalse(ctx.loadBackend()); @@ -156,7 +156,6 @@ public void failBackendInitWithCourseButWithoutInternet() { @Test public void failBackendInitWithInternetButWithoutCourse() { mockStatic(CourseInfoIo.class); - mockStatic(SettingsIo.class); WorkDir workDir = mock(WorkDir.class); when(workDir.getConfigFile()).thenReturn(null); @@ -170,7 +169,6 @@ public void failBackendInitWithInternetButWithoutCourse() { @Test public void failBackendInitWithInternetButWithCorruptedCourse() { mockStatic(CourseInfoIo.class); - mockStatic(SettingsIo.class); WorkDir workDir = mock(WorkDir.class); Path path = mock(Path.class); @@ -188,12 +186,8 @@ public void failBackendInitWithInternetButWithCorruptedCourse() { @Test public void backendInitWithoutInternet() { - mockStatic(SettingsIo.class); - WorkDir workDir = mock(WorkDir.class); when(workDir.getConfigFile()).thenReturn(null); - when(SettingsIo.loadFrom(anyString(), anyString(), any(Path.class))) - .thenReturn(null); CliContext ctx = new CliContext(io, null, workDir); assertTrue(ctx.loadBackendWithoutLogin()); @@ -203,14 +197,13 @@ public void backendInitWithoutInternet() { @Test public void backendInitWithoutInternetWithCourse() { mockStatic(CourseInfoIo.class); - mockStatic(SettingsIo.class); WorkDir workDir = mock(WorkDir.class); CourseInfo info = mock(CourseInfo.class); Path path = mock(Path.class); + list.addAccount(new Account()); when(CourseInfoIo.load(eq(path))).thenReturn(info); - when(SettingsIo.load(anyString(), anyString())).thenReturn(new Account()); when(workDir.getConfigFile()).thenReturn(path); CliContext ctx = new CliContext(io, null, workDir); From d7bae429e371d0ec35757c8557d01b8260c4e209 Mon Sep 17 00:00:00 2001 From: Aleksi Salmela Date: Sun, 10 Jul 2016 12:16:25 +0300 Subject: [PATCH 05/16] Reorder SettingsIo methods. --- .../cs/tmc/cli/backend/SettingsIo.java | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java index 25732c14..0c4d37b9 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java @@ -57,6 +57,40 @@ public static boolean saveAccountList(AccountList list, Path configRoot) { return saveHolderToJson(list, file); } + public static boolean delete() { + Path file = getAccountsFile(getConfigDirectory()); + try { + Files.deleteIfExists(file); + } catch (IOException e) { + logger.error("Could not delete config file in " + file.toString(), e); + return false; + } + return true; + } + + public static HashMap loadProperties() { + return loadPropertiesFrom(getConfigDirectory()); + } + + public static HashMap loadPropertiesFrom(Path path) { + Path file = getPropertiesFile(path); + HashMap properties = getPropertiesFromJson(file); + if (properties != null) { + return properties; + } else { + return new HashMap<>(); + } + } + + public static boolean saveProperties(HashMap properties) { + return savePropertiesTo(properties, getConfigDirectory()); + } + + public static boolean savePropertiesTo(HashMap properties, Path path) { + Path file = getPropertiesFile(path); + return savePropertiesToJson(properties, file); + } + /** * Get the correct directory in which our config files go * ie /home/user/.config/tmc-cli/. @@ -161,38 +195,4 @@ private static boolean savePropertiesToJson(HashMap properties, } return true; } - - public static boolean delete() { - Path file = getAccountsFile(getConfigDirectory()); - try { - Files.deleteIfExists(file); - } catch (IOException e) { - logger.error("Could not delete config file in " + file.toString(), e); - return false; - } - return true; - } - - public static HashMap loadProperties() { - return loadPropertiesFrom(getConfigDirectory()); - } - - public static HashMap loadPropertiesFrom(Path path) { - Path file = getPropertiesFile(path); - HashMap properties = getPropertiesFromJson(file); - if (properties != null) { - return properties; - } else { - return new HashMap<>(); - } - } - - public static boolean saveProperties(HashMap properties) { - return savePropertiesTo(properties, getConfigDirectory()); - } - - public static boolean savePropertiesTo(HashMap properties, Path path) { - Path file = getPropertiesFile(path); - return savePropertiesToJson(properties, file); - } } From 5a801e983b8fed3fe1499727a2eec80e08e4d7be Mon Sep 17 00:00:00 2001 From: Aleksi Salmela Date: Sun, 10 Jul 2016 12:44:38 +0300 Subject: [PATCH 06/16] Don't use TmcSettings object in CourseInfo. --- .../java/fi/helsinki/cs/tmc/cli/backend/CourseInfo.java | 9 ++++----- .../java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java | 1 - .../java/fi/helsinki/cs/tmc/cli/core/CliContext.java | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfo.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfo.java index d5ea1df2..eb5433ae 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfo.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfo.java @@ -1,6 +1,5 @@ package fi.helsinki.cs.tmc.cli.backend; -import fi.helsinki.cs.tmc.core.configuration.TmcSettings; import fi.helsinki.cs.tmc.core.domain.Course; import fi.helsinki.cs.tmc.core.domain.Exercise; @@ -19,12 +18,12 @@ public class CourseInfo { private List localCompletedExercises; private HashMap properties; - public CourseInfo(TmcSettings settings, Course course) { - this.username = settings.getUsername(); - this.serverAddress = settings.getServerAddress(); + public CourseInfo(Account account, Course course) { + this.username = account.getUsername(); + this.serverAddress = account.getServerAddress(); this.course = course; this.properties = new HashMap<>(); - this.localCompletedExercises = new ArrayList(); + this.localCompletedExercises = new ArrayList<>(); } public String getUsername() { diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java index 0c4d37b9..08d73555 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/SettingsIo.java @@ -13,7 +13,6 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashMap; -import java.util.List; /** * Reads and writes to config files on the system. 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 94f2adda..d47e6fd0 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 @@ -112,7 +112,7 @@ public WorkDir getWorkDir() { * @return cached course data object */ public CourseInfo createCourseInfo(Course course) { - return new CourseInfo(settings, course); + return new CourseInfo(settings.getAccount(), course); } /** From 0d45c296a02d46ec3ebf92f0ce743ba999225f2c Mon Sep 17 00:00:00 2001 From: Aleksi Salmela Date: Sun, 10 Jul 2016 12:44:58 +0300 Subject: [PATCH 07/16] Simplify the CliContext code. --- .../helsinki/cs/tmc/cli/core/CliContext.java | 4 ---- .../cs/tmc/cli/core/CliContextTest.java | 18 +++++++++++++----- 2 files changed, 13 insertions(+), 9 deletions(-) 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 d47e6fd0..41649ba1 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 @@ -214,13 +214,9 @@ public boolean loadBackendWithoutLogin() { /** * Copy login info from different settings object and them. - * TODO: separate settings object and login info. * @param account login info */ public void useAccount(Account account) { - if (this.tmcCore == null) { - createTmcCore(account); - } this.settings.setAccount(account); } diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/core/CliContextTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/core/CliContextTest.java index df141d7f..acab6b2b 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/core/CliContextTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/core/CliContextTest.java @@ -67,14 +67,22 @@ public void setAppAndGetIt() { @Test public void useDifferentAccount() { - CliContext ctx = new CliContext(io); - Application app = new Application(ctx); - Account account = new Account(); + mockStatic(CourseInfoIo.class); + + WorkDir workDir = mock(WorkDir.class); + Path path = mock(Path.class); + Account newAccount = new Account(); + + when(CourseInfoIo.load(eq(path))).thenReturn(mock(CourseInfo.class)); + when(workDir.getConfigFile()).thenReturn(path); + CliContext ctx = new CliContext(io, null, workDir); + + ctx.loadBackend(); + ctx.useAccount(newAccount); - ctx.useAccount(account); //TODO replace the Whitebox usage somehow Settings usedSettings = Whitebox.getInternalState(ctx, "settings"); - assertEquals(account, usedSettings.getAccount()); + assertEquals(newAccount, usedSettings.getAccount()); } @Test(expected = RuntimeException.class) From dde9e01515ee529f7760916638575907f2b77a80 Mon Sep 17 00:00:00 2001 From: Aleksi Salmela Date: Sun, 10 Jul 2016 13:40:06 +0300 Subject: [PATCH 08/16] Fix the CourseInfo constructor in tests. --- .../fi/helsinki/cs/tmc/cli/backend/CourseInfo.java | 2 +- .../helsinki/cs/tmc/cli/backend/CourseInfoIoTest.java | 8 +------- .../helsinki/cs/tmc/cli/backend/CourseInfoTest.java | 2 +- .../cs/tmc/cli/command/ListCoursesCommandTest.java | 2 +- .../helsinki/cs/tmc/cli/command/LoginCommandTest.java | 11 +++++------ .../java/fi/helsinki/cs/tmc/cli/io/WorkDirTest.java | 4 ++-- 6 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfo.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfo.java index eb5433ae..4ce03ddf 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfo.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfo.java @@ -46,7 +46,7 @@ public List getLocalCompletedExercises() { // Check for null pointer in case of old .tmc.json files // Remove this when we are sure nobody's using 0.5.1 anymore if (this.localCompletedExercises == null) { - this.localCompletedExercises = new ArrayList(); + this.localCompletedExercises = new ArrayList<>(); } return this.localCompletedExercises; } diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoIoTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoIoTest.java index a64b8d03..966352c1 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoIoTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoIoTest.java @@ -14,7 +14,6 @@ public class CourseInfoIoTest { - private Settings settings; private CourseInfo course; private Path courseFile; private String tempDir; @@ -25,12 +24,7 @@ public void setup() { this.courseFile = Paths.get(tempDir) .resolve("test-course") .resolve(CourseInfoIo.COURSE_CONFIG); - this.settings = new Settings(); - this.course = new CourseInfo(this.settings, new Course("test-course")); - try { - FileUtils.deleteDirectory(Paths.get(tempDir) - .resolve("test-course").toFile()); - } catch (Exception e) { } + this.course = new CourseInfo(new Account(), new Course("test-course")); } @After diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoTest.java index 16073c0e..fcc7f2e7 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoTest.java @@ -19,7 +19,7 @@ public class CourseInfoTest { @Before public void setUp() { - courseInfo = new CourseInfo(new Settings(), new Course("test-course")); + courseInfo = new CourseInfo(new Account(), new Course("test-course")); } @Test diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java index 24828976..ae9a5557 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java @@ -53,7 +53,7 @@ public void setUp() { @Test public void failIfBackendFails() { - CliContext ctx = spy(new CliContext(io, mockCore)); + ctx = spy(ctx); app = new Application(ctx); doReturn(false).when(ctx).loadBackend(); diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java index 853490f1..36c7ebf0 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java @@ -12,14 +12,12 @@ import fi.helsinki.cs.tmc.cli.backend.Account; import fi.helsinki.cs.tmc.cli.backend.AccountList; import fi.helsinki.cs.tmc.cli.backend.CourseInfo; -import fi.helsinki.cs.tmc.cli.backend.Settings; import fi.helsinki.cs.tmc.cli.backend.SettingsIo; import fi.helsinki.cs.tmc.cli.backend.TmcUtil; 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.core.configuration.TmcSettings; import org.junit.Before; import org.junit.Test; @@ -50,6 +48,7 @@ public void setUp() { mockStatic(TmcUtil.class); mockStatic(SettingsIo.class); + when(TmcUtil.hasConnection(eq(ctx))).thenReturn(true); when(SettingsIo.loadAccountList()).thenReturn(new AccountList()); when(SettingsIo.saveAccountList(any(AccountList.class))).thenReturn(true); } @@ -112,8 +111,8 @@ public void loginAsksServerFromUserIfNotGiven() { @Test public void serverAndNotAskedAfterLogout() { - TmcSettings settings = new Settings(SERVER, "username", "pass"); - CourseInfo info = new CourseInfo(settings, null); + Account account = new Account(SERVER, "username", "pass"); + CourseInfo info = new CourseInfo(account, null); when(TmcUtil.tryToLogin(eq(ctx), any(Account.class))).thenReturn(true); when(ctx.getCourseInfo()).thenReturn(info); String[] args = {"login"}; @@ -124,8 +123,8 @@ public void serverAndNotAskedAfterLogout() { @Test public void courseInfoValuesOverridedByOptions() { - Settings settings = new Settings(SERVER, "username", "pass"); - CourseInfo info = new CourseInfo(settings, null); + Account account = new Account(SERVER, "username", "pass"); + CourseInfo info = new CourseInfo(account, null); when(TmcUtil.tryToLogin(eq(ctx), any(Account.class))).thenReturn(true); when(ctx.getCourseInfo()).thenReturn(info); String[] args = {"login", "-p", PASSWORD, "-u", USERNAME}; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/io/WorkDirTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/io/WorkDirTest.java index 8e643432..b6e71a7a 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/io/WorkDirTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/io/WorkDirTest.java @@ -7,9 +7,9 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import fi.helsinki.cs.tmc.cli.backend.Account; import fi.helsinki.cs.tmc.cli.backend.CourseInfo; import fi.helsinki.cs.tmc.cli.backend.CourseInfoIo; -import fi.helsinki.cs.tmc.cli.backend.Settings; import fi.helsinki.cs.tmc.core.domain.Course; import fi.helsinki.cs.tmc.core.domain.Exercise; @@ -57,7 +57,7 @@ public static void setup() { exercises.get(1).setCompleted(true); exercises.add(new Exercise("viikko2-teht3")); exercises.add(new Exercise("viikko3-nonexistent")); - CourseInfo info = new CourseInfo(new Settings(), new Course("dirUtilTest")); + CourseInfo info = new CourseInfo(new Account(), new Course("dirUtilTest")); info.getLocalCompletedExercises().add("viikko1-teht1"); info.setExercises(exercises); CourseInfoIo.save(info, tempDir.resolve(CourseInfoIo.COURSE_CONFIG)); From 9f1cba72f3fcc711fae5d691e30fcbc7ebede09f Mon Sep 17 00:00:00 2001 From: Aleksi Salmela Date: Sun, 10 Jul 2016 13:55:42 +0300 Subject: [PATCH 09/16] Check that we have internet and print login info. --- .../helsinki/cs/tmc/cli/backend/TmcUtil.java | 22 +++++++++++++++++++ .../cs/tmc/cli/command/LoginCommand.java | 15 ++++++++++--- .../cs/tmc/cli/backend/TmcUtilTest.java | 21 +++++++++++++++++- .../cs/tmc/cli/command/LoginCommandTest.java | 9 ++++++++ 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java index f7c4b26d..e0fc9e3e 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java @@ -14,6 +14,7 @@ import fi.helsinki.cs.tmc.core.exceptions.ObsoleteClientException; import fi.helsinki.cs.tmc.langs.abstraction.ValidationResult; import fi.helsinki.cs.tmc.langs.domain.RunResult; +import java.net.InetAddress; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,6 +28,27 @@ public class TmcUtil { private static final Logger logger = LoggerFactory.getLogger(TmcUtil.class); + /** + * Check if we have internet connection. + * + * This is done with making dns lookup + * for the www.mooc.fi domain. This isn't + * 100% exact way to check internet access, + * but it's good enough. + * + * @param ctx context object + * @return true if we have internet access. + */ + public static boolean hasConnection(CliContext ctx) { + try { + InetAddress.getByName("www.mooc.fi"); + } catch (Exception e) { + TmcUtil.logger.warn("No internet", e.getCause()); + return false; + } + return true; + } + public static boolean tryToLogin(CliContext ctx, Account account) { TmcCore core = ctx.getTmcCore(); ctx.useAccount(account); diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java index 5241a391..e0c6176a 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java @@ -39,8 +39,12 @@ public void run(CommandLine args, Io io) { return; } - //TODO try to login so that user won't fill the fields if internet - // doesn't work. + if (!TmcUtil.hasConnection(ctx)) { + io.println("You don't have internet connection currently."); + io.println("Check the tmc-cli logs to get exact problem."); + return; + } + CourseInfo info = ctx.getCourseInfo(); if (info != null) { serverAddress = info.getServerAddress(); @@ -69,12 +73,17 @@ public void run(CommandLine args, Io io) { private String getLoginInfo(CommandLine line, String oldValue, String option, String prompt) { String value = oldValue; + boolean isPassword = option.equals("p"); if (line.hasOption(option)) { value = line.getOptionValue(option); } - if (value == null && option.equals("p")) { + if (value != null && !isPassword) { + io.println(prompt + value); + } + + if (value == null && isPassword) { value = io.readPassword(prompt); } else if (value == null) { value = io.readLine(prompt); diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/backend/TmcUtilTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/backend/TmcUtilTest.java index 611a8be8..1ebe2820 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/backend/TmcUtilTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/backend/TmcUtilTest.java @@ -6,11 +6,13 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyListOf; +import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.powermock.api.mockito.PowerMockito.mockStatic; import fi.helsinki.cs.tmc.cli.Application; import fi.helsinki.cs.tmc.cli.core.CliContext; @@ -39,15 +41,17 @@ import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import java.net.InetAddress; import java.net.URI; import java.net.URISyntaxException; +import java.net.UnknownHostException; import java.nio.file.Path; import java.util.Arrays; import java.util.List; import java.util.concurrent.Callable; @RunWith(PowerMockRunner.class) -@PrepareForTest(RunResult.class) +@PrepareForTest({RunResult.class, InetAddress.class, TmcUtil.class}) public class TmcUtilTest { static Path workDir; @@ -106,6 +110,21 @@ public List call() throws Exception { }; } + @Test + public void hasInternetConnection() throws UnknownHostException { + mockStatic(InetAddress.class); + when(InetAddress.getByName(anyString())).thenReturn(null); + assertTrue(TmcUtil.hasConnection(ctx)); + } + + @Test + public void hasNoInternetConnection() throws UnknownHostException { + mockStatic(InetAddress.class); + when(InetAddress.getByName(anyString())).thenThrow( + new UnknownHostException()); + assertFalse(TmcUtil.hasConnection(ctx)); + } + @Test public void failToLogin() throws URISyntaxException { when(mockCore.listCourses(any(ProgressObserver.class))) diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java index 36c7ebf0..b2d9ddf6 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/LoginCommandTest.java @@ -63,6 +63,15 @@ public void failIfBackendFails() { io.assertNotContains("Login successful"); } + @Test + public void failIfThereIsNoConnection() { + when(TmcUtil.hasConnection(eq(ctx))).thenReturn(false); + + String[] args = {"login"}; + app.run(args); + io.assertContains("don't have internet connection"); + } + @Test public void logsInWithCorrectServerUserAndPassword() { when(TmcUtil.tryToLogin(eq(ctx), any(Account.class))).thenReturn(true); From 0806aa64ab3e40e1a94362dda22ee8002517d29c Mon Sep 17 00:00:00 2001 From: Aleksi Salmela Date: Sun, 10 Jul 2016 14:13:58 +0300 Subject: [PATCH 10/16] Check internet connection in all Tmc comands. --- .../java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java | 11 +++++++++-- .../cs/tmc/cli/command/ListCoursesCommand.java | 6 ++++++ .../fi/helsinki/cs/tmc/cli/backend/TmcUtilTest.java | 4 ++-- .../cs/tmc/cli/command/ListCoursesCommandTest.java | 10 ++++++++++ 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java index e0fc9e3e..dcee0cbb 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java @@ -14,11 +14,12 @@ import fi.helsinki.cs.tmc.core.exceptions.ObsoleteClientException; import fi.helsinki.cs.tmc.langs.abstraction.ValidationResult; import fi.helsinki.cs.tmc.langs.domain.RunResult; -import java.net.InetAddress; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.net.URI; import java.util.ArrayList; import java.util.List; @@ -30,11 +31,12 @@ public class TmcUtil { /** * Check if we have internet connection. - * * This is done with making dns lookup * for the www.mooc.fi domain. This isn't * 100% exact way to check internet access, * but it's good enough. + * TODO the method could be changed into requireConnection(), + * which also would print error message. * * @param ctx context object * @return true if we have internet access. @@ -229,6 +231,11 @@ protected static void handleTmcExceptions(CliContext ctx, Exception exception) { ctx.getApp().runAutoUpdate(); return; } + if (cause != null && cause.getCause() instanceof UnknownHostException) { + logger.error("No internet connection"); + io.println("You have no internet connection."); + return; + } logger.error("Command failed in tmc-core", exception); io.println("Command failed in tmc-core, check tmc-cli.log file for more info"); } diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java index fc6afbbf..6c4a13aa 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java @@ -39,6 +39,12 @@ public void run(CommandLine args, Io io) { return; } + if (!TmcUtil.hasConnection(ctx)) { + io.println("You don't have internet connection currently."); + io.println("Check the tmc-cli logs to get exact problem."); + return; + } + AccountList accountsList = SettingsIo.loadAccountList(); boolean isFirst = true; diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/backend/TmcUtilTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/backend/TmcUtilTest.java index 1ebe2820..43201513 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/backend/TmcUtilTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/backend/TmcUtilTest.java @@ -42,9 +42,9 @@ import org.powermock.modules.junit4.PowerMockRunner; import java.net.InetAddress; +import java.net.UnknownHostException; import java.net.URI; import java.net.URISyntaxException; -import java.net.UnknownHostException; import java.nio.file.Path; import java.util.Arrays; import java.util.List; @@ -121,7 +121,7 @@ public void hasInternetConnection() throws UnknownHostException { public void hasNoInternetConnection() throws UnknownHostException { mockStatic(InetAddress.class); when(InetAddress.getByName(anyString())).thenThrow( - new UnknownHostException()); + new UnknownHostException()); assertFalse(TmcUtil.hasConnection(ctx)); } diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java index ae9a5557..b90e400e 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java @@ -48,6 +48,7 @@ public void setUp() { mockStatic(TmcUtil.class); mockStatic(SettingsIo.class); + when(TmcUtil.hasConnection(eq(ctx))).thenReturn(true); when(SettingsIo.loadAccountList()).thenReturn(accountList); } @@ -62,6 +63,15 @@ public void failIfBackendFails() { io.assertNotContains("Course doesn't exist"); } + @Test + public void failIfThereIsNoConnection() { + when(TmcUtil.hasConnection(eq(ctx))).thenReturn(false); + + String[] args = {"courses"}; + app.run(args); + io.assertContains("don't have internet connection"); + } + @Test public void listCoursesWorksWithNoCourses() { List list = Arrays.asList(); From 061a6d602038a180e7bb9fa5765657c99f7fa91d Mon Sep 17 00:00:00 2001 From: Aleksi Salmela Date: Sun, 10 Jul 2016 14:43:57 +0300 Subject: [PATCH 11/16] Print message when there isn't any login info at ListCourses. --- .../java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java | 2 +- .../fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java index 6c4a13aa..bbfab2ef 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java @@ -35,7 +35,7 @@ public void run(CommandLine args, Io io) { this.ctx = getContext(); this.io = ctx.getIo(); - if (! getContext().loadBackend()) { + if (! getContext().loadBackendWithoutLogin()) { return; } diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java index b90e400e..bc0f7de9 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommandTest.java @@ -56,7 +56,7 @@ public void setUp() { public void failIfBackendFails() { ctx = spy(ctx); app = new Application(ctx); - doReturn(false).when(ctx).loadBackend(); + doReturn(false).when(ctx).loadBackendWithoutLogin(); String[] args = {"courses", "foo"}; app.run(args); From 6a0e24c817f59a999cba3d2ac240362e438b3f94 Mon Sep 17 00:00:00 2001 From: Aleksi Salmela Date: Sun, 10 Jul 2016 17:04:05 +0300 Subject: [PATCH 12/16] Change the arguments for the Commands' run method. --- .../fi/helsinki/cs/tmc/cli/Application.java | 4 ++-- .../cs/tmc/cli/command/DocumentCommand.java | 5 +++-- .../cli/command/DownloadExercisesCommand.java | 7 ++++-- .../cs/tmc/cli/command/HelpCommand.java | 7 +++--- .../cs/tmc/cli/command/InfoCommand.java | 8 +++---- .../tmc/cli/command/ListCoursesCommand.java | 8 +++---- .../tmc/cli/command/ListExercisesCommand.java | 6 ++--- .../cs/tmc/cli/command/LoginCommand.java | 6 ++--- .../cs/tmc/cli/command/LogoutCommand.java | 6 ++--- .../cs/tmc/cli/command/PasteCommand.java | 6 ++--- .../cs/tmc/cli/command/PropertiesCommand.java | 9 ++++---- .../cs/tmc/cli/command/RunTestsCommand.java | 6 +++-- .../tmc/cli/command/ShellHelperCommand.java | 5 ++++- .../cs/tmc/cli/command/SubmitCommand.java | 6 ++--- .../cs/tmc/cli/command/UpdateCommand.java | 10 ++++----- .../cs/tmc/cli/core/AbstractCommand.java | 22 +++++-------------- .../cs/tmc/cli/core/CommandFactory.java | 3 +-- .../cs/tmc/cli/core/AbstractCommandTest.java | 11 ++++------ .../core/CommandAnnotationProcessorTest.java | 6 ++--- .../cs/tmc/cli/core/CommandFactoryTest.java | 11 +++++----- 20 files changed, 73 insertions(+), 79 deletions(-) diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/Application.java b/src/main/java/fi/helsinki/cs/tmc/cli/Application.java index 8f2b506d..75c4a66e 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/Application.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/Application.java @@ -59,13 +59,13 @@ public Application(CliContext context) { } private boolean runCommand(String name, String[] args) { - AbstractCommand command = CommandFactory.createCommand(this.context, name); + AbstractCommand command = CommandFactory.createCommand(name); if (command == null) { io.println("Command " + name + " doesn't exist."); return false; } - command.execute(args, io); + command.execute(context, args); return true; } diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/DocumentCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/DocumentCommand.java index 110b1ff9..3829d3c8 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/DocumentCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/DocumentCommand.java @@ -1,6 +1,7 @@ package fi.helsinki.cs.tmc.cli.command; 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.Color; import fi.helsinki.cs.tmc.cli.io.EnvironmentUtil; @@ -78,8 +79,8 @@ public void getOptions(Options options) { } @Override - public void run(CommandLine args, Io io) { - this.io = io; + public void run(CliContext context, CommandLine args) { + this.io = context.getIo(); this.width = EnvironmentUtil.getTerminalWidth(); this.height = 30; this.cursorX = 0; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java index c29e84ee..82f87c18 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java @@ -43,7 +43,10 @@ public void getOptions(Options options) { } @Override - public void run(CommandLine args, Io io) { + public void run(CliContext context, CommandLine args) { + Io io = context.getIo(); + ctx = context; + String[] stringArgs = args.getArgs(); if (stringArgs.length == 0 || stringArgs.length > 1) { io.println("You must give a course name as an argument."); @@ -51,7 +54,7 @@ public void run(CommandLine args, Io io) { return; } - ctx = getContext(); + ctx = context; showAll = args.hasOption("a"); if (!ctx.loadBackend()) { diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/HelpCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/HelpCommand.java index 5580cc7d..bb3ed760 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/HelpCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/HelpCommand.java @@ -2,6 +2,7 @@ import fi.helsinki.cs.tmc.cli.Application; 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.core.CommandFactory; import fi.helsinki.cs.tmc.cli.io.Io; @@ -24,9 +25,9 @@ public void getOptions(Options options) { } @Override - public void run(CommandLine args, Io io) { - Application app = getContext().getApp(); - this.io = io; + public void run(CliContext context, CommandLine args) { + Application app = context.getApp(); + this.io = context.getIo(); StringBuilder sb = new StringBuilder(); sb.append("TMC commands:\n"); diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java index 5e324c39..5f8640e7 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java @@ -40,10 +40,10 @@ public void getOptions(Options options) { } @Override - public void run(CommandLine args, Io io) { - this.io = io; - this.ctx = getContext(); - workDir = ctx.getWorkDir(); + public void run(CliContext context, CommandLine args) { + this.ctx = context; + this.workDir = ctx.getWorkDir(); + this.io = ctx.getIo(); boolean fetchFromInternet = args.hasOption("i"); diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java index bbfab2ef..92cada5e 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java @@ -31,11 +31,11 @@ public void getOptions(Options options) { } @Override - public void run(CommandLine args, Io io) { - this.ctx = getContext(); + public void run(CliContext context, CommandLine args) { + this.ctx = context; this.io = ctx.getIo(); - if (! getContext().loadBackendWithoutLogin()) { + if (! ctx.loadBackendWithoutLogin()) { return; } @@ -68,7 +68,7 @@ public void run(CommandLine args, Io io) { private void printCourseList(Account account) { ctx.useAccount(account); - List courses = TmcUtil.listCourses(getContext()); + List courses = TmcUtil.listCourses(ctx); if (courses.isEmpty()) { io.println("No courses found from the server."); return; 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 35cd2041..2c55c81c 100755 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/ListExercisesCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/ListExercisesCommand.java @@ -32,9 +32,9 @@ public void getOptions(Options options) { } @Override - public void run(CommandLine args, Io io) { - this.ctx = getContext(); - this.io = io; + public void run(CliContext context, CommandLine args) { + this.ctx = context; + this.io = ctx.getIo(); String courseName = getCourseName(args); if (courseName == null) { diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java index e0c6176a..4747fba4 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/LoginCommand.java @@ -31,9 +31,9 @@ public void getOptions(Options options) { } @Override - public void run(CommandLine args, Io io) { - this.ctx = getContext(); - this.io = io; + public void run(CliContext context, CommandLine args) { + this.ctx = context; + this.io = ctx.getIo(); if (!ctx.loadBackendWithoutLogin()) { return; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/LogoutCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/LogoutCommand.java index 8c77798f..45495e02 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/LogoutCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/LogoutCommand.java @@ -2,8 +2,8 @@ import fi.helsinki.cs.tmc.cli.backend.SettingsIo; 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; @@ -16,8 +16,8 @@ public void getOptions(Options options) { } @Override - public void run(CommandLine args, Io io) { + public void run(CliContext context, CommandLine args) { SettingsIo.delete(); - io.println("Logged out."); + context.getIo().println("Logged out."); } } diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/PasteCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/PasteCommand.java index 446f681f..798a70d4 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/PasteCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/PasteCommand.java @@ -34,9 +34,9 @@ public void getOptions(Options options) { } @Override - public void run(CommandLine args, Io io) { - this.io = io; - CliContext ctx = getContext(); + public void run(CliContext context, CommandLine args) { + CliContext ctx = context; + this.io = ctx.getIo(); if (!ctx.loadBackend()) { return; } diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/PropertiesCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/PropertiesCommand.java index eb6a7918..47848416 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/PropertiesCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/PropertiesCommand.java @@ -27,10 +27,11 @@ public void getOptions(Options options) { } @Override - public void run(CommandLine args, Io io) { - this.io = io; - CliContext ctx = getContext(); - Boolean unset = args.hasOption("u"); + public void run(CliContext context, CommandLine args) { + CliContext ctx = context; + this.io = ctx.getIo(); + + boolean unset = args.hasOption("u"); String[] arguments = args.getArgs(); HashMap props = ctx.getProperties(); if (arguments.length == 0) { diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/RunTestsCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/RunTestsCommand.java index 3ae42d23..37ccdf90 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/RunTestsCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/RunTestsCommand.java @@ -39,13 +39,15 @@ public void getOptions(Options options) { } @Override - public void run(CommandLine args, Io io) { + public void run(CliContext context, CommandLine args) { + CliContext ctx = context; + Io io = ctx.getIo(); + String[] exercisesFromArgs = parseArgs(args); if (exercisesFromArgs == null) { return; } - CliContext ctx = getContext(); if (!ctx.loadBackendWithoutLogin()) { return; } diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/ShellHelperCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/ShellHelperCommand.java index dbbd0035..72ba39cd 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/ShellHelperCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/ShellHelperCommand.java @@ -1,6 +1,7 @@ package fi.helsinki.cs.tmc.cli.command; 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.core.CommandFactory; import fi.helsinki.cs.tmc.cli.io.Io; @@ -18,7 +19,9 @@ public void getOptions(Options options) { } @Override - public void run(CommandLine args, Io io) { + public void run(CliContext context, CommandLine args) { + Io io = context.getIo(); + if (args.hasOption("c")) { for (Class commandClass : CommandFactory.getCommands()) { Command command = CommandFactory.getCommand(commandClass); diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/SubmitCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/SubmitCommand.java index a98ea9f6..caa7f011 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/SubmitCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/SubmitCommand.java @@ -47,9 +47,9 @@ public void getOptions(Options options) { } @Override - public void run(CommandLine args, Io io) { - this.ctx = getContext(); - this.io = io; + public void run(CliContext context, CommandLine args) { + this.ctx = context; + this.io = ctx.getIo(); String[] exercisesFromArgs = parseArgs(args); if (exercisesFromArgs == null) { diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/UpdateCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/UpdateCommand.java index cc1114fe..18a46bdf 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/UpdateCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/UpdateCommand.java @@ -30,9 +30,9 @@ public void getOptions(Options options) { } @Override - public void run(CommandLine args, Io io) { - this.ctx = getContext(); - this.io = io; + public void run(CliContext context, CommandLine args) { + this.ctx = context; + this.io = ctx.getIo(); String[] stringArgs = args.getArgs(); //TODO: Do this in all commands @@ -67,8 +67,8 @@ private void updateExercises(CourseInfo info, Path configFile) { printExercises(exerciseUpdater.getUpdatedExercises(), "Modified exercises:"); io.println(""); - Color.AnsiColor color1 = getContext().getApp().getColor("progressbar-left"); - Color.AnsiColor color2 = getContext().getApp().getColor("progressbar-right"); + Color.AnsiColor color1 = ctx.getApp().getColor("progressbar-left"); + Color.AnsiColor color2 = ctx.getApp().getColor("progressbar-right"); List downloaded = exerciseUpdater.downloadUpdates( new CliProgressObserver(io, color1, color2)); if (downloaded.isEmpty()) { diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/core/AbstractCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/core/AbstractCommand.java index 78118a90..ab66ff3f 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/core/AbstractCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/core/AbstractCommand.java @@ -14,16 +14,6 @@ public abstract class AbstractCommand { private static final Logger logger = LoggerFactory.getLogger(AbstractCommand.class); - private CliContext context; - - protected void setContext(CliContext context) { - this.context = context; - } - - protected CliContext getContext() { - return this.context; - } - /** * Override this method if you want longer description for the command than * the annotation description. @@ -51,18 +41,18 @@ private Options getOptions() { * TODO io param isn't needed anymore!!!! * * @param args Command line arguments for this command. - * @param io The terminal IO object + * @param ctx The context object. */ - public abstract void run(CommandLine args, Io io); + public abstract void run(CliContext ctx, CommandLine args); - public void execute(String[] stringArgs, Io io) { - CommandLine args = parseArgs(stringArgs); + public void execute(CliContext context, String[] stringArgs) { + CommandLine args = parseArgs(context, stringArgs); if (args != null) { - run(args, io); + run(context, args); } } - public CommandLine parseArgs(String[] stringArgs) { + public CommandLine parseArgs(CliContext context, String[] stringArgs) { GnuParser parser = new GnuParser(); CommandLine args; Options options = getOptions(); diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/core/CommandFactory.java b/src/main/java/fi/helsinki/cs/tmc/cli/core/CommandFactory.java index ce28aeb1..90e71f3c 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/core/CommandFactory.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/core/CommandFactory.java @@ -65,14 +65,13 @@ public static void addCommand(Class commandClass) { * @param name Name of the command * @return A new command instance */ - public static AbstractCommand createCommand(CliContext context, String name) { + public static AbstractCommand createCommand(String name) { Class commandClass = CommandFactory.commands.get(name); if (commandClass == null) { return null; } try { AbstractCommand command = (AbstractCommand)commandClass.newInstance(); - command.setContext(context); return command; } catch (InstantiationException | IllegalAccessException ex) { throw new RuntimeException("getCommand failed", ex); diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/core/AbstractCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/core/AbstractCommandTest.java index 8ed0d8c6..e23a45bd 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/core/AbstractCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/core/AbstractCommandTest.java @@ -18,7 +18,7 @@ public class AbstractCommandTest { private class EmptyCommand extends AbstractCommand { @Override - public void run(CommandLine args, Io io) { + public void run(CliContext context, CommandLine args) { } @Override @@ -35,24 +35,21 @@ public AbstractCommandTest() { @Test public void helpMessagePrints() { String[] args = {"-h"}; - emptyCommand.setContext(ctx); - emptyCommand.execute(args, io); + emptyCommand.execute(ctx, args); io.assertContains("tmc empty"); } @Test public void emptyCommandHasHelpOption() { String[] args = {"-h"}; - emptyCommand.setContext(ctx); - emptyCommand.execute(args, io); + emptyCommand.execute(ctx, args); io.assertContains("--help"); } @Test public void failWhenInvalidOption() { String[] args = {"-a34t3"}; - emptyCommand.setContext(ctx); - emptyCommand.execute(args, io); + emptyCommand.execute(ctx, args); io.assertContains("Invalid command"); } } \ No newline at end of file diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/core/CommandAnnotationProcessorTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/core/CommandAnnotationProcessorTest.java index 37cc2363..4ee927c7 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/core/CommandAnnotationProcessorTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/core/CommandAnnotationProcessorTest.java @@ -11,8 +11,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import fi.helsinki.cs.tmc.cli.io.Io; - import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Options; import org.junit.Test; @@ -106,7 +104,7 @@ public void getOptions(Options options) { } @Override - public void run(CommandLine args, Io io) { + public void run(CliContext ctx, CommandLine args) { throw new UnsupportedOperationException(); } } @@ -119,7 +117,7 @@ public void getOptions(Options options) { } @Override - public void run(CommandLine args, Io io) { + public void run(CliContext ctx, CommandLine args) { throw new UnsupportedOperationException(); } } diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/core/CommandFactoryTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/core/CommandFactoryTest.java index ba81c2cc..3a214681 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/core/CommandFactoryTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/core/CommandFactoryTest.java @@ -5,7 +5,6 @@ import static org.junit.Assert.assertTrue; import fi.helsinki.cs.tmc.cli.Application; -import fi.helsinki.cs.tmc.cli.io.Io; import fi.helsinki.cs.tmc.cli.io.TestIo; import org.apache.commons.cli.CommandLine; @@ -37,12 +36,12 @@ public void constructorAddsCommands() { @Test public void createCommandWorksWithRealCommand() { - assertNotNull(CommandFactory.createCommand(ctx, "help")); + assertNotNull(CommandFactory.createCommand("help")); } @Test public void createCommandWorksWithBadCommand() { - assertNull(CommandFactory.createCommand(ctx, "foobar")); + assertNull(CommandFactory.createCommand("foobar")); } @Command(name = "good", desc = "test") @@ -54,7 +53,7 @@ public void getOptions(Options options) { } @Override - public void run(CommandLine args, Io io) { + public void run(CliContext context, CommandLine args) { throw new UnsupportedOperationException(); } } @@ -63,7 +62,7 @@ public void run(CommandLine args, Io io) { public void addGoodCommand() { CommandFactory.addCommand(GoodCommand.class); //TODO check the all the stuff in the command - assertNotNull(CommandFactory.createCommand(ctx, "good")); + assertNotNull(CommandFactory.createCommand("good")); } public static class BadCommand extends AbstractCommand { @@ -74,7 +73,7 @@ public void getOptions(Options options) { } @Override - public void run(CommandLine args, Io io) { + public void run(CliContext context, CommandLine args) { throw new UnsupportedOperationException(); } } From 125915e667e36c86beb2f7e7bb9a8ba2a46f0fba Mon Sep 17 00:00:00 2001 From: Aleksi Salmela Date: Sun, 10 Jul 2016 18:28:21 +0300 Subject: [PATCH 13/16] Use proper date parsing and printing. --- .../java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java index 5f8640e7..b9d8dd6b 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java @@ -21,6 +21,7 @@ import org.apache.commons.cli.Options; import java.util.Arrays; +import java.util.Date; import java.util.List; @Command(name = "info", desc = "Show info about the current directory") @@ -241,11 +242,7 @@ private void printExercise(Exercise exercise) { } private String getDeadline(Exercise exercise) { - String deadline = exercise.getDeadline(); - if (deadline == null) { - return "not available"; - } - deadline = deadline.substring(0, 19); - return deadline.replace("T", " at "); + Date deadline = exercise.getDeadlineDate(); + return deadline.toString(); } } From 5a2227e170e8d6bf8366cce46e113977b707da96 Mon Sep 17 00:00:00 2001 From: Aleksi Salmela Date: Sun, 10 Jul 2016 20:05:46 +0300 Subject: [PATCH 14/16] Improve color api. --- .../fi/helsinki/cs/tmc/cli/Application.java | 15 ++--- .../cs/tmc/cli/command/DocumentCommand.java | 5 +- .../cli/command/DownloadExercisesCommand.java | 10 +-- .../cs/tmc/cli/command/InfoCommand.java | 14 ++--- .../tmc/cli/command/ListCoursesCommand.java | 5 +- .../tmc/cli/command/ListExercisesCommand.java | 11 ++-- .../cs/tmc/cli/command/RunTestsCommand.java | 7 ++- .../cs/tmc/cli/command/SubmitCommand.java | 11 ++-- .../cs/tmc/cli/command/UpdateCommand.java | 4 +- .../cs/tmc/cli/io/CliProgressObserver.java | 20 +++--- .../java/fi/helsinki/cs/tmc/cli/io/Color.java | 62 +++++-------------- .../fi/helsinki/cs/tmc/cli/io/ColorUtil.java | 24 +++++++ .../cs/tmc/cli/io/ShutdownHandler.java | 2 +- .../cs/tmc/cli/shared/ResultPrinter.java | 21 ++++--- .../tmc/cli/io/CliProgressObserverTest.java | 2 +- .../fi/helsinki/cs/tmc/cli/io/ColorTest.java | 48 +++++++++++++- .../cs/tmc/cli/io/ShutdownHandlerTest.java | 2 +- .../cs/tmc/cli/shared/ResultPrinterTest.java | 2 +- 18 files changed, 154 insertions(+), 111 deletions(-) create mode 100644 src/main/java/fi/helsinki/cs/tmc/cli/io/ColorUtil.java diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/Application.java b/src/main/java/fi/helsinki/cs/tmc/cli/Application.java index 75c4a66e..6a49309e 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/Application.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/Application.java @@ -4,6 +4,7 @@ import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.core.CommandFactory; import fi.helsinki.cs.tmc.cli.io.Color; +import fi.helsinki.cs.tmc.cli.io.ColorUtil; import fi.helsinki.cs.tmc.cli.io.EnvironmentUtil; import fi.helsinki.cs.tmc.cli.io.HelpGenerator; import fi.helsinki.cs.tmc.cli.io.Io; @@ -182,16 +183,16 @@ public boolean runAutoUpdate() { } //TODO rename this as getColorProperty and move it somewhere else - public Color.AnsiColor getColor(String propertyName) { + public Color getColor(String propertyName) { String propertyValue = context.getProperties().get(propertyName); - Color.AnsiColor color = Color.getColor(propertyValue); + Color color = ColorUtil.getColor(propertyValue); if (color == null) { switch (propertyName) { - case "progressbar-left": return Color.AnsiColor.ANSI_CYAN; - case "progressbar-right": return Color.AnsiColor.ANSI_CYAN; - case "testresults-left": return Color.AnsiColor.ANSI_GREEN; - case "testresults-right": return Color.AnsiColor.ANSI_RED; - default: return Color.AnsiColor.ANSI_NONE; + case "progressbar-left": return Color.CYAN; + case "progressbar-right": return Color.CYAN; + case "testresults-left": return Color.GREEN; + case "testresults-right": return Color.RED; + default: return Color.NONE; } } return color; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/DocumentCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/DocumentCommand.java index 3829d3c8..6adaa93e 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/DocumentCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/DocumentCommand.java @@ -4,6 +4,7 @@ import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.core.Command; import fi.helsinki.cs.tmc.cli.io.Color; +import fi.helsinki.cs.tmc.cli.io.ColorUtil; import fi.helsinki.cs.tmc.cli.io.EnvironmentUtil; import fi.helsinki.cs.tmc.cli.io.Io; @@ -140,7 +141,7 @@ public void run(CliContext context, CommandLine args) { setCursor(0, 0); io.print("\u001B[0J"); - blitter(Color.colorString("Original dev team", Color.AnsiColor.ANSI_BLUE), + blitter(ColorUtil.colorString("Original dev team", Color.BLUE), Math.max(centerX - 10, 0), centerY - 2); blitter("Johannes L. (jclc)", centerX, centerY++); centerY++; @@ -157,7 +158,7 @@ public void run(CliContext context, CommandLine args) { io.print("\u001B[0J"); centerY = height / 2 - 3; - blitter(Color.colorString("Special thanks for", Color.AnsiColor.ANSI_CYAN), + blitter(ColorUtil.colorString("Special thanks for", Color.CYAN), Math.max(centerX - 10, 0), centerY - 2); blitter("Jarmo Isotalo (Jamo)", centerX, centerY++); centerY++; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java index 82f87c18..55d5c7e0 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java @@ -11,6 +11,7 @@ import fi.helsinki.cs.tmc.cli.core.Command; import fi.helsinki.cs.tmc.cli.io.CliProgressObserver; import fi.helsinki.cs.tmc.cli.io.Color; +import fi.helsinki.cs.tmc.cli.io.ColorUtil; import fi.helsinki.cs.tmc.cli.io.Io; import fi.helsinki.cs.tmc.cli.io.WorkDir; @@ -76,8 +77,8 @@ public void run(CliContext context, CommandLine args) { // todo: If -c switch, use core.downloadCompletedExercises() to download user's old // submissions. Not yet implemented in tmc-core. - Color.AnsiColor color1 = ctx.getApp().getColor("progressbar-left"); - Color.AnsiColor color2 = ctx.getApp().getColor("progressbar-right"); + Color color1 = ctx.getApp().getColor("progressbar-left"); + Color color2 = ctx.getApp().getColor("progressbar-right"); CliProgressObserver progobs = new CliProgressObserver(io, color1, color2); List exercises = TmcUtil.downloadExercises(ctx, filtered, progobs); @@ -169,8 +170,8 @@ private void printStatistics(Course course, int requestCount, int downloadCount) if (failedCount > 0) { io.println(" of which " + (requestCount - failedCount) + " exercises were succesfully downloaded"); - io.println(Color.colorString(" and of which " + failedCount + " failed.", - Color.AnsiColor.ANSI_RED)); + io.println(ColorUtil.colorString(" and of which " + failedCount + " failed.", + Color.RED)); //TODO we could print the names of the not downloaded exercises here } else { io.println(" of which " @@ -182,6 +183,7 @@ private void printStatistics(Course course, int requestCount, int downloadCount) } } + //TODO this could be moved into CourseInfoIo or ExerciseUpdater private void createNewCourse(Course course) { WorkDir workDir = ctx.getWorkDir(); Path configFile = workDir.getWorkingDirectory() diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java index b9d8dd6b..c3f0131d 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java @@ -1,16 +1,12 @@ package fi.helsinki.cs.tmc.cli.command; -import static fi.helsinki.cs.tmc.cli.io.Color.AnsiColor.ANSI_BLUE; -import static fi.helsinki.cs.tmc.cli.io.Color.AnsiColor.ANSI_GREEN; -import static fi.helsinki.cs.tmc.cli.io.Color.AnsiColor.ANSI_PURPLE; -import static fi.helsinki.cs.tmc.cli.io.Color.AnsiColor.ANSI_RED; - import fi.helsinki.cs.tmc.cli.backend.CourseInfo; import fi.helsinki.cs.tmc.cli.backend.TmcUtil; 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.Color; +import fi.helsinki.cs.tmc.cli.io.ColorUtil; import fi.helsinki.cs.tmc.cli.io.Io; import fi.helsinki.cs.tmc.cli.io.WorkDir; @@ -166,10 +162,10 @@ private void printExerciseShort() { io.println("Deadline: " + getDeadline(exercise)); if (exercise.hasDeadlinePassed() && !exercise.isCompleted()) { - io.println(Color.colorString("deadline passed", ANSI_PURPLE)); + io.println(ColorUtil.colorString("deadline passed", Color.PURPLE)); } else { if (!exercise.isCompleted() && exercise.isAttempted()) { - io.println(Color.colorString("attempted", ANSI_BLUE)); + io.println(ColorUtil.colorString("attempted", Color.BLUE)); } else { io.println(formatString("completed", exercise.isCompleted())); } @@ -181,9 +177,9 @@ private void printExerciseShort() { private String formatString(String string, boolean color) { if (color) { - return Color.colorString(string, ANSI_GREEN); + return ColorUtil.colorString(string, Color.GREEN); } else { - return Color.colorString("not " + string, ANSI_RED); + return ColorUtil.colorString("not " + string, Color.RED); } } diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java index 92cada5e..51285b3d 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/ListCoursesCommand.java @@ -8,6 +8,7 @@ import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.core.Command; import fi.helsinki.cs.tmc.cli.io.Color; +import fi.helsinki.cs.tmc.cli.io.ColorUtil; import fi.helsinki.cs.tmc.cli.io.Io; import fi.helsinki.cs.tmc.core.domain.Course; @@ -58,8 +59,8 @@ public void run(CliContext context, CommandLine args) { io.println(""); } if (accountsList.getAccountCount() > 1) { - io.println(Color.colorString("Server " + settings.getServerAddress(), - Color.AnsiColor.ANSI_YELLOW)); + io.println(ColorUtil.colorString("Server " + settings.getServerAddress(), + Color.YELLOW)); } printCourseList(settings); isFirst = false; 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 2c55c81c..31816ca9 100755 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/ListExercisesCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/ListExercisesCommand.java @@ -6,6 +6,7 @@ import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.core.Command; import fi.helsinki.cs.tmc.cli.io.Color; +import fi.helsinki.cs.tmc.cli.io.ColorUtil; import fi.helsinki.cs.tmc.cli.io.EnvironmentUtil; import fi.helsinki.cs.tmc.cli.io.ExternalsUtil; import fi.helsinki.cs.tmc.cli.io.Io; @@ -155,16 +156,16 @@ private String getExerciseStatus(Exercise exercise) { String status; if (exercise.isCompleted()) { if (exercise.requiresReview() && !exercise.isReviewed()) { - status = Color.colorString(" Requires review: ", Color.AnsiColor.ANSI_YELLOW); + status = ColorUtil.colorString(" Requires review: ", Color.YELLOW); } else { - status = Color.colorString(" Completed: ", Color.AnsiColor.ANSI_GREEN); + status = ColorUtil.colorString(" Completed: ", Color.GREEN); } } else if (exercise.hasDeadlinePassed()) { - status = Color.colorString(" Deadline passed: ", Color.AnsiColor.ANSI_PURPLE); + status = ColorUtil.colorString(" Deadline passed: ", Color.PURPLE); } else if (exercise.isAttempted()) { - status = Color.colorString(" Attempted: ", Color.AnsiColor.ANSI_BLUE); + status = ColorUtil.colorString(" Attempted: ", Color.BLUE); } else { - status = Color.colorString(" Not completed: ", Color.AnsiColor.ANSI_RED); + status = ColorUtil.colorString(" Not completed: ", Color.RED); } status += exercise.getName() + "\n"; diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/RunTestsCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/RunTestsCommand.java index 37ccdf90..56504800 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/RunTestsCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/RunTestsCommand.java @@ -7,6 +7,7 @@ import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.core.Command; import fi.helsinki.cs.tmc.cli.io.Color; +import fi.helsinki.cs.tmc.cli.io.ColorUtil; import fi.helsinki.cs.tmc.cli.io.Io; import fi.helsinki.cs.tmc.cli.io.WorkDir; import fi.helsinki.cs.tmc.cli.shared.ResultPrinter; @@ -68,15 +69,15 @@ public void run(CliContext context, CommandLine args) { CourseInfo info = ctx.getCourseInfo(); - Color.AnsiColor passedColor = ctx.getApp().getColor("testresults-left"); - Color.AnsiColor failedColor = ctx.getApp().getColor("testresults-right"); + Color passedColor = ctx.getApp().getColor("testresults-left"); + Color failedColor = ctx.getApp().getColor("testresults-right"); ResultPrinter resultPrinter = new ResultPrinter(io, showDetails, showPassed, passedColor, failedColor); boolean isOnlyExercise = (exerciseNames.size() == 1); for (String name : exerciseNames) { - io.println(Color.colorString("Testing: " + name, Color.AnsiColor.ANSI_YELLOW)); + io.println(ColorUtil.colorString("Testing: " + name, Color.YELLOW)); Exercise exercise = info.getExercise(name); RunResult runResult = TmcUtil.runLocalTests(ctx, exercise); diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/SubmitCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/SubmitCommand.java index caa7f011..dd378c78 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/SubmitCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/SubmitCommand.java @@ -7,6 +7,7 @@ import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.core.Command; import fi.helsinki.cs.tmc.cli.io.Color; +import fi.helsinki.cs.tmc.cli.io.ColorUtil; import fi.helsinki.cs.tmc.cli.io.Io; import fi.helsinki.cs.tmc.cli.io.WorkDir; import fi.helsinki.cs.tmc.cli.shared.ExerciseUpdater; @@ -91,8 +92,8 @@ public void run(CliContext context, CommandLine args) { return; } - Color.AnsiColor color1 = ctx.getApp().getColor("testresults-left"); - Color.AnsiColor color2 = ctx.getApp().getColor("testresults-right"); + Color color1 = ctx.getApp().getColor("testresults-left"); + Color color2 = ctx.getApp().getColor("testresults-right"); ResultPrinter resultPrinter = new ResultPrinter(io, this.showDetails, this.showAll, color1, color2); @@ -104,8 +105,8 @@ public void run(CliContext context, CommandLine args) { List feedbackUris = new ArrayList<>(); for (Exercise exercise : submitExercises) { - io.println(Color.colorString("Submitting: " + exercise.getName(), - Color.AnsiColor.ANSI_YELLOW)); + io.println(ColorUtil.colorString("Submitting: " + exercise.getName(), + Color.YELLOW)); SubmissionResult result = TmcUtil.submitExercise(ctx, exercise); if (result == null) { io.println("Submission failed."); @@ -202,7 +203,7 @@ private void checkForExerciseUpdates(Course course) { msg += "Use 'tmc update' to download " + (total > 1 ? "them." : "it."); io.println(""); - io.println(Color.colorString(msg, Color.AnsiColor.ANSI_YELLOW)); + io.println(ColorUtil.colorString(msg, Color.YELLOW)); } private String[] parseArgs(CommandLine args) { diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/UpdateCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/UpdateCommand.java index 18a46bdf..ae38c594 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/UpdateCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/UpdateCommand.java @@ -67,8 +67,8 @@ private void updateExercises(CourseInfo info, Path configFile) { printExercises(exerciseUpdater.getUpdatedExercises(), "Modified exercises:"); io.println(""); - Color.AnsiColor color1 = ctx.getApp().getColor("progressbar-left"); - Color.AnsiColor color2 = ctx.getApp().getColor("progressbar-right"); + Color color1 = ctx.getApp().getColor("progressbar-left"); + Color color2 = ctx.getApp().getColor("progressbar-right"); List downloaded = exerciseUpdater.downloadUpdates( new CliProgressObserver(io, color1, color2)); if (downloaded.isEmpty()) { diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/io/CliProgressObserver.java b/src/main/java/fi/helsinki/cs/tmc/cli/io/CliProgressObserver.java index dacc6dc9..befaa7d9 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/io/CliProgressObserver.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/io/CliProgressObserver.java @@ -11,8 +11,8 @@ public class CliProgressObserver extends ProgressObserver { protected Io io; private int pips; protected int maxline; - private Color.AnsiColor color1; - private Color.AnsiColor color2; + private Color color1; + private Color color2; protected String lastMessage; protected Boolean hasProgressBar; @@ -21,10 +21,10 @@ public CliProgressObserver() { } public CliProgressObserver(Io io) { - this(io, Color.AnsiColor.ANSI_CYAN, Color.AnsiColor.ANSI_CYAN); + this(io, Color.CYAN, Color.CYAN); } - public CliProgressObserver(Io io, Color.AnsiColor color1, Color.AnsiColor color2) { + public CliProgressObserver(Io io, Color color1, Color color2) { this.hasProgressBar = false; this.io = io; this.maxline = EnvironmentUtil.getTerminalWidth(); @@ -97,7 +97,7 @@ protected void flush(int length) { } public static String progressBar(double progress, int length, - Color.AnsiColor color1, Color.AnsiColor color2) { + Color color1, Color color2) { return progressBar(progress, length, color1, color2, BARLEFT, BARRIGHT, PIPCHAR, EMPTYCHAR); } @@ -105,8 +105,8 @@ public static String progressBar(double progress, int length, public static String progressBar( double progress, int length, - Color.AnsiColor color1, - Color.AnsiColor color2, + Color color1, + Color color2, char barLeft, char barRight, char donePip, @@ -122,8 +122,8 @@ public static String progressBar( } return percentage(progress) + barLeft - + Color.colorString(sbLeft.toString(), color1) - + Color.colorString(sbRight.toString(), color2) + + ColorUtil.colorString(sbLeft.toString(), color1) + + ColorUtil.colorString(sbRight.toString(), color2) + barRight; } @@ -141,7 +141,7 @@ protected static String percentage(double progress) { } public static String getPassedTestsBar(int passed, int total, - Color.AnsiColor color1, Color.AnsiColor color2) { + Color color1, Color color2) { return CliProgressObserver.progressBar( (double) passed / total, EnvironmentUtil.getTerminalWidth(), diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/io/Color.java b/src/main/java/fi/helsinki/cs/tmc/cli/io/Color.java index 9492feb6..0099969d 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/io/Color.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/io/Color.java @@ -1,53 +1,25 @@ package fi.helsinki.cs.tmc.cli.io; -public class Color { +public enum Color { + NONE(""), + RESET("\u001B[0m"), + BLACK("\u001B[30m"), + RED("\u001B[31m"), + GREEN("\u001B[32m"), + YELLOW("\u001B[33m"), + BLUE("\u001B[34m"), + PURPLE("\u001B[35m"), + CYAN("\u001B[36m"), + WHITE("\u001B[37m"); - public enum AnsiColor { - ANSI_NONE(""), - ANSI_RESET("\u001B[0m"), - ANSI_BLACK("\u001B[30m"), - ANSI_RED("\u001B[31m"), - ANSI_GREEN("\u001B[32m"), - ANSI_YELLOW("\u001B[33m"), - ANSI_BLUE("\u001B[34m"), - ANSI_PURPLE("\u001B[35m"), - ANSI_CYAN("\u001B[36m"), - ANSI_WHITE("\u001B[37m"); + private final String escCode; - private String escCode; - - AnsiColor(String color) { - this.escCode = color; - } - - public String toString() { - return this.escCode; - } - } - - public static String colorString(String string, AnsiColor color) { - if (!EnvironmentUtil.isWindows() && color != AnsiColor.ANSI_NONE) { - return color + string + AnsiColor.ANSI_RESET; - } else { - return string; - } + Color(String escCode) { + this.escCode = escCode; } - public static AnsiColor getColor(String color) { - if (color == null) { - return null; - } - switch (color) { - case "black": return AnsiColor.ANSI_BLACK; - case "red": return AnsiColor.ANSI_RED; - case "green": return AnsiColor.ANSI_GREEN; - case "yellow": return AnsiColor.ANSI_YELLOW; - case "blue": return AnsiColor.ANSI_BLUE; - case "purple": return AnsiColor.ANSI_PURPLE; - case "cyan": return AnsiColor.ANSI_CYAN; - case "white": return AnsiColor.ANSI_WHITE; - case "none": return AnsiColor.ANSI_NONE; - default: return null; - } + @Override + public String toString() { + return this.escCode; } } diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/io/ColorUtil.java b/src/main/java/fi/helsinki/cs/tmc/cli/io/ColorUtil.java new file mode 100644 index 00000000..4b4d433c --- /dev/null +++ b/src/main/java/fi/helsinki/cs/tmc/cli/io/ColorUtil.java @@ -0,0 +1,24 @@ +package fi.helsinki.cs.tmc.cli.io; + +public class ColorUtil { + + public static String colorString(String string, Color color) { + if (!EnvironmentUtil.isWindows() && color != Color.NONE) { + return color + string + Color.RESET; + } else { + return string; + } + } + + public static Color getColor(String name) { + try { + Color color = Color.valueOf(name.toUpperCase()); + if (color == Color.NONE || color == Color.RESET) { + color = null; + } + return color; + } catch (IllegalArgumentException | NullPointerException e) { + return null; + } + } +} diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/io/ShutdownHandler.java b/src/main/java/fi/helsinki/cs/tmc/cli/io/ShutdownHandler.java index 1912c870..8e6dc5f9 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/io/ShutdownHandler.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/io/ShutdownHandler.java @@ -15,7 +15,7 @@ public ShutdownHandler(Io io) { public void run() { // Reset terminal color back to default in case we exit in the middle of // colored printing. Otherwise user is left with a colored terminal. - io.println(Color.AnsiColor.ANSI_RESET.toString()); + io.println(Color.RESET.toString()); } public void enable() { diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/shared/ResultPrinter.java b/src/main/java/fi/helsinki/cs/tmc/cli/shared/ResultPrinter.java index f83b80e0..92392351 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/shared/ResultPrinter.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/shared/ResultPrinter.java @@ -2,6 +2,7 @@ import fi.helsinki.cs.tmc.cli.io.CliProgressObserver; import fi.helsinki.cs.tmc.cli.io.Color; +import fi.helsinki.cs.tmc.cli.io.ColorUtil; import fi.helsinki.cs.tmc.cli.io.Io; import fi.helsinki.cs.tmc.core.domain.submission.SubmissionResult; @@ -20,14 +21,14 @@ public class ResultPrinter { private static final String COMPILE_ERROR_MESSAGE - = Color.colorString("Failed to compile project", Color.AnsiColor.ANSI_PURPLE); + = ColorUtil.colorString("Failed to compile project", Color.PURPLE); private static final String FAIL_MESSAGE = "Failed: "; private static final String PASS_MESSAGE = "Passed: "; private static final String PADDING = createPaddingString(PASS_MESSAGE.length()); private final Io io; - private final Color.AnsiColor passedColor; - private final Color.AnsiColor failedColor; + private final Color passedColor; + private final Color failedColor; private boolean showDetails; private boolean showPassed; @@ -35,7 +36,7 @@ public class ResultPrinter { private int passedExercises; public ResultPrinter(Io io, boolean showDetails, boolean showPassed, - Color.AnsiColor passedColor, Color.AnsiColor failedColor) { + Color passedColor, Color failedColor) { this.io = io; this.passedColor = passedColor; this.failedColor = failedColor; @@ -121,7 +122,7 @@ public boolean printLocalTestResult(RunResult runResult, ValidationResult valRes } if (runResult.status == RunResult.Status.PASSED && validationsPassed) { - io.print(Color.colorString("All tests passed!", Color.AnsiColor.ANSI_GREEN)); + io.print(ColorUtil.colorString("All tests passed!", Color.GREEN)); io.println(" Submit to server with 'tmc submit'"); passedExercises++; return true; @@ -178,7 +179,7 @@ private boolean validationsPassed(ValidationResult result) { private void printValidationErrors(ValidationResult result) { Map> errors = result.getValidationErrors(); - io.println(Color.colorString("Validation error:", failedColor)); + io.println(ColorUtil.colorString("Validation error:", failedColor)); for (Map.Entry> entry : errors.entrySet()) { io.println("File: " + entry.getKey()); @@ -203,7 +204,7 @@ private void printTestCases(List testResults) { } private void printFailedTest(TestResult testResult) { - io.print(Color.colorString(FAIL_MESSAGE, failedColor)); + io.print(ColorUtil.colorString(FAIL_MESSAGE, failedColor)); io.println(testResult.getName()); io.println(PADDING + testResult.getMessage()); @@ -225,7 +226,7 @@ private void printFailedTest(TestResult testResult) { } private void printPassedTest(TestResult testResult) { - io.print(Color.colorString(PASS_MESSAGE, passedColor)); + io.print(ColorUtil.colorString(PASS_MESSAGE, passedColor)); io.println(testResult.getName()); } @@ -239,7 +240,7 @@ private void printPassedSubmissionResult(SubmissionResult submResult, boolean pr printResultBar(passedTests, totalTests); } - io.println(Color.colorString("All tests passed on server!", passedColor)); + io.println(ColorUtil.colorString("All tests passed on server!", passedColor)); passedExercises++; if (!submResult.getPoints().isEmpty()) { @@ -257,7 +258,7 @@ private void printFailedSubmissionResult(SubmissionResult submResult, boolean pr String valgrind = submResult.getValgrind(); if (valgrind != null && !valgrind.isEmpty()) { - io.println(Color.colorString("Valgrind error:", failedColor)); + io.println(ColorUtil.colorString("Valgrind error:", failedColor)); io.println(valgrind); totalTests++; } diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/io/CliProgressObserverTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/io/CliProgressObserverTest.java index fa497d30..71d7acc1 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/io/CliProgressObserverTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/io/CliProgressObserverTest.java @@ -50,7 +50,7 @@ public void progressBarWorks() { @Test public void testResultBarWorks() { String string = CliProgressObserver.getPassedTestsBar(1, 2, - Color.AnsiColor.ANSI_NONE, Color.AnsiColor.ANSI_NONE); + Color.NONE, Color.NONE); assertTrue("Prints the start of the progress bar", string.contains( " 50%[")); assertTrue("Prints the first part of the progress bar", string.contains( diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/io/ColorTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/io/ColorTest.java index 1749e5e3..67a9179a 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/io/ColorTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/io/ColorTest.java @@ -22,20 +22,62 @@ public void setup() { @Test public void colorsWorkInNonWindows() { when(EnvironmentUtil.isWindows()).thenReturn(false); - String string = Color.colorString("foobar", Color.AnsiColor.ANSI_BLACK); + String string = ColorUtil.colorString("foobar", Color.BLACK); assertEquals("\u001B[30mfoobar\u001B[0m", string); } @Test public void colorsWorkInWindows() { when(EnvironmentUtil.isWindows()).thenReturn(true); - String string = Color.colorString("foobar", Color.AnsiColor.ANSI_BLACK); + String string = ColorUtil.colorString("foobar", Color.BLACK); assertEquals("foobar", string); } @Test public void noColorWorks() { - String string = Color.colorString("foobar", Color.AnsiColor.ANSI_NONE); + String string = ColorUtil.colorString("foobar", Color.NONE); assertEquals("foobar", string); } + + @Test + public void getLowerCaseGreenColor() { + Color color = ColorUtil.getColor("green"); + assertEquals(Color.GREEN, color); + } + + @Test + public void getCamelCaseGreenColor() { + Color color = ColorUtil.getColor("Green"); + assertEquals(Color.GREEN, color); + } + + @Test + public void getUpperCaseGreenColor() { + Color color = ColorUtil.getColor("GREEN"); + assertEquals(Color.GREEN, color); + } + + @Test + public void getGreenWithSpecialCharColor() { + Color color = ColorUtil.getColor("green$"); + assertEquals(null, color); + } + + @Test + public void getInvalidColor() { + Color color = ColorUtil.getColor("xgrewsg"); + assertEquals(null, color); + } + + @Test + public void getResetColor() { + Color color = ColorUtil.getColor("reset"); + assertEquals(null, color); + } + + @Test + public void getNullAsColor() { + Color color = ColorUtil.getColor(null); + assertEquals(null, color); + } } diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/io/ShutdownHandlerTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/io/ShutdownHandlerTest.java index 2b8518c1..f1a5f3ac 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/io/ShutdownHandlerTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/io/ShutdownHandlerTest.java @@ -33,7 +33,7 @@ public void setUp() { @Test public void printsAnsiResetAtRun() { shutdownHandler.run(); - io.assertEquals(Color.AnsiColor.ANSI_RESET.toString() + "\n"); + io.assertEquals(Color.RESET.toString() + "\n"); } @Test diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/shared/ResultPrinterTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/shared/ResultPrinterTest.java index 7a523478..2040df77 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/shared/ResultPrinterTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/shared/ResultPrinterTest.java @@ -40,7 +40,7 @@ public class ResultPrinterTest { public void setUp() { io = new TestIo(); printer = new ResultPrinter(io, true, true, - Color.AnsiColor.ANSI_GREEN, Color.AnsiColor.ANSI_RED); + Color.GREEN, Color.RED); mockSubResult = mock(SubmissionResult.class); logs = ImmutableMap.of(); } From 5abc0ce9e4d5dd2eda31440e56f1e45db91bc47a Mon Sep 17 00:00:00 2001 From: Aleksi Salmela Date: Sun, 10 Jul 2016 21:56:08 +0300 Subject: [PATCH 15/16] Move course finding code to separate class. --- .../cs/tmc/cli/backend/CourseInfoIo.java | 12 ++ .../cli/command/DownloadExercisesCommand.java | 77 ++----------- .../helsinki/cs/tmc/cli/core/CliContext.java | 10 -- .../cs/tmc/cli/shared/CourseFinder.java | 106 ++++++++++++++++++ 4 files changed, 125 insertions(+), 80 deletions(-) create mode 100644 src/main/java/fi/helsinki/cs/tmc/cli/shared/CourseFinder.java diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoIo.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoIo.java index e6addd3a..cf3f2289 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoIo.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfoIo.java @@ -1,5 +1,7 @@ package fi.helsinki.cs.tmc.cli.backend; +import fi.helsinki.cs.tmc.core.domain.Course; + import com.google.gson.Gson; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,4 +52,14 @@ public static CourseInfo load(Path courseInfoFile) { } return gson.fromJson(reader, CourseInfo.class); } + + public static void createNewCourse(Course course, Account account, Path parentDir) { + Path configFile = parentDir + .resolve(course.getName()) + .resolve(CourseInfoIo.COURSE_CONFIG); + + CourseInfo info = new CourseInfo(account, course); + info.setExercises(course.getExercises()); + CourseInfoIo.save(info, configFile); + } } diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java index 55d5c7e0..353c064b 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java @@ -1,10 +1,6 @@ package fi.helsinki.cs.tmc.cli.command; -import fi.helsinki.cs.tmc.cli.backend.Account; -import fi.helsinki.cs.tmc.cli.backend.AccountList; -import fi.helsinki.cs.tmc.cli.backend.CourseInfo; import fi.helsinki.cs.tmc.cli.backend.CourseInfoIo; -import fi.helsinki.cs.tmc.cli.backend.SettingsIo; import fi.helsinki.cs.tmc.cli.backend.TmcUtil; import fi.helsinki.cs.tmc.cli.core.AbstractCommand; import fi.helsinki.cs.tmc.cli.core.CliContext; @@ -14,6 +10,7 @@ import fi.helsinki.cs.tmc.cli.io.ColorUtil; import fi.helsinki.cs.tmc.cli.io.Io; import fi.helsinki.cs.tmc.cli.io.WorkDir; +import fi.helsinki.cs.tmc.cli.shared.CourseFinder; import fi.helsinki.cs.tmc.core.domain.Course; import fi.helsinki.cs.tmc.core.domain.Exercise; @@ -21,12 +18,8 @@ import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Options; -import java.nio.file.Path; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; @Command(name = "download", desc = "Download exercises for a specific course") public class DownloadExercisesCommand extends AbstractCommand { @@ -69,10 +62,11 @@ public void run(CliContext context, CommandLine args) { } String courseName = stringArgs[0]; - Course course = findCourse(courseName); - if (course == null) { + CourseFinder finder = new CourseFinder(ctx); + if (!finder.search(courseName)) { return; } + Course course = finder.getCourse(); List filtered = getFilteredExercises(course); // todo: If -c switch, use core.downloadCompletedExercises() to download user's old // submissions. Not yet implemented in tmc-core. @@ -81,6 +75,7 @@ public void run(CliContext context, CommandLine args) { Color color2 = ctx.getApp().getColor("progressbar-right"); CliProgressObserver progobs = new CliProgressObserver(io, color1, color2); + ctx.useAccount(finder.getAccount()); List exercises = TmcUtil.downloadExercises(ctx, filtered, progobs); if (exercises == null) { io.println("Failed to download exercises"); @@ -88,55 +83,9 @@ public void run(CliContext context, CommandLine args) { } printStatistics(course, filtered.size(), exercises.size()); - createNewCourse(course); - } - - // TODO This method could be moved somewhere else. - private Course findCourse(String courseName) { - Io io = ctx.getIo(); - - AccountList accountsList = SettingsIo.loadAccountList(); - // LinkedHashMap is used here to preserve ordering. - Map matches = new LinkedHashMap<>(); - - if (accountsList.getAccountCount() == 0) { - io.println("You haven't logged in on any tmc server."); - return null; - } - for (Account settings : accountsList) { - ctx.useAccount(settings); - Course course = TmcUtil.findCourse(ctx, courseName); - if (course != null) { - matches.put(settings, course); - } - } - - if (matches.size() == 1) { - Entry firstEntry = matches.entrySet().iterator().next(); - ctx.useAccount(firstEntry.getKey()); - return firstEntry.getValue(); - } else if (matches.isEmpty()) { - io.println("Course doesn't exist."); - return null; - } - - io.println("There is " + matches.size() - + " courses with same name at different servers."); - - for (Entry entrySet : matches.entrySet()) { - Account settings = entrySet.getKey(); - Course course = entrySet.getValue(); - - if (io.readConfirmation("Download course from " - + settings.getServerAddress() + " with '" - + settings.getUsername() + "' account", false)) { - ctx.useAccount(settings); - return course; - } - } - io.println("The previous course was last that matched."); - return null; + CourseInfoIo.createNewCourse(course, finder.getAccount(), + workDir.getWorkingDirectory()); } private List getFilteredExercises(Course course) { @@ -182,16 +131,4 @@ private void printStatistics(Course course, int requestCount, int downloadCount) } } } - - //TODO this could be moved into CourseInfoIo or ExerciseUpdater - private void createNewCourse(Course course) { - WorkDir workDir = ctx.getWorkDir(); - Path configFile = workDir.getWorkingDirectory() - .resolve(course.getName()) - .resolve(CourseInfoIo.COURSE_CONFIG); - - CourseInfo info = ctx.createCourseInfo(course); - info.setExercises(course.getExercises()); - CourseInfoIo.save(info, configFile); - } } 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 41649ba1..e540b319 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 @@ -105,16 +105,6 @@ public WorkDir getWorkDir() { return workDir; } - /** - * Create local course info file after download. - * - * @param course local copy of course object - * @return cached course data object - */ - public CourseInfo createCourseInfo(Course course) { - return new CourseInfo(settings.getAccount(), course); - } - /** * Get map of the properties. * diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/shared/CourseFinder.java b/src/main/java/fi/helsinki/cs/tmc/cli/shared/CourseFinder.java new file mode 100644 index 00000000..3811f20f --- /dev/null +++ b/src/main/java/fi/helsinki/cs/tmc/cli/shared/CourseFinder.java @@ -0,0 +1,106 @@ +package fi.helsinki.cs.tmc.cli.shared; + +import fi.helsinki.cs.tmc.cli.backend.Account; +import fi.helsinki.cs.tmc.cli.backend.AccountList; +import fi.helsinki.cs.tmc.cli.backend.SettingsIo; +import fi.helsinki.cs.tmc.cli.backend.TmcUtil; +import fi.helsinki.cs.tmc.cli.core.CliContext; +import fi.helsinki.cs.tmc.cli.io.Io; + +import fi.helsinki.cs.tmc.core.domain.Course; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * TODO move some of the test from DownloadExercisesCommand to CourseFinder + */ +public class CourseFinder { + + private final CliContext ctx; + private Course course; + private Account account; + + public CourseFinder(CliContext ctx) { + this.ctx = ctx; + } + + public Course getCourse() { + verifySearchIsCalled(); + return course; + } + + public Account getAccount() { + verifySearchIsCalled(); + return account; + } + + public boolean search(String courseName) { + Io io = ctx.getIo(); + + AccountList accountsList = SettingsIo.loadAccountList(); + // LinkedHashMap is used here to preserve ordering. + Map matches = new LinkedHashMap<>(); + + if (accountsList.getAccountCount() == 0) { + io.println("You haven't logged in on any tmc server."); + return false; + } + + for (Account settings : accountsList) { + ctx.useAccount(settings); + Course found = TmcUtil.findCourse(ctx, courseName); + if (found != null) { + matches.put(settings, found); + } + } + + if (matches.isEmpty()) { + //TODO we could search here for similar courses. + io.println("Course doesn't exist."); + return false; + } else if (matches.size() == 1) { + return handleSingleMatchingCourses(matches); + } else { + return handleMultipleMatchingCourses(matches); + } + } + + private boolean handleSingleMatchingCourses(Map matches) { + Map.Entry firstEntry; + firstEntry = matches.entrySet().iterator().next(); + + this.account = firstEntry.getKey(); + this.course = firstEntry.getValue(); + return true; + } + + private boolean handleMultipleMatchingCourses(Map matches) { + Io io = ctx.getIo(); + io.println("There is " + matches.size() + + " courses with same name at different servers."); + + for (Map.Entry entrySet : matches.entrySet()) { + Account entryAccount = entrySet.getKey(); + Course entryCourse = entrySet.getValue(); + + if (io.readConfirmation("Download course from " + + entryAccount.getServerAddress() + " with '" + + entryAccount.getUsername() + "' account", false)) { + this.account = entryAccount; + this.course = entryCourse; + return true; + } + } + + io.println("The previous course was last that matched."); + return false; + } + + private void verifySearchIsCalled() { + if (course != null) { + return; + } + throw new RuntimeException("You must search before using getters"); + } +} From 08388c626675d3f8eac7d90f238f8b3f4f761302 Mon Sep 17 00:00:00 2001 From: Aleksi Salmela Date: Mon, 11 Jul 2016 00:22:16 +0300 Subject: [PATCH 16/16] Major refactoring of info command. --- .../cs/tmc/cli/backend/CourseInfo.java | 1 + .../helsinki/cs/tmc/cli/backend/TmcUtil.java | 1 + .../cs/tmc/cli/command/InfoCommand.java | 212 +++++++++--------- .../helsinki/cs/tmc/cli/core/CliContext.java | 11 +- .../cs/tmc/cli/shared/CourseFinder.java | 1 + .../cs/tmc/cli/command/InfoCommandTest.java | 58 ++++- 6 files changed, 168 insertions(+), 116 deletions(-) diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfo.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfo.java index 4ce03ddf..413470c8 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfo.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/CourseInfo.java @@ -77,6 +77,7 @@ public List getExerciseNames() { return names; } + //TODO This is exactly same method as TmcUtil.findExercise(course, name) public Exercise getExercise(String name) { for (Exercise exercise : this.course.getExercises()) { if (exercise.getName().equals(name)) { diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java b/src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java index dcee0cbb..474a8f15 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java @@ -105,6 +105,7 @@ public static Course findCourse(CliContext ctx, String name) { return null; } + //TODO This is exactly same method as CourseInfo.getExercise(course, name) public static Exercise findExercise(Course course, String name) { List exercises; exercises = course.getExercises(); diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java b/src/main/java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java index c3f0131d..a2616cdb 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/command/InfoCommand.java @@ -1,7 +1,6 @@ package fi.helsinki.cs.tmc.cli.command; import fi.helsinki.cs.tmc.cli.backend.CourseInfo; -import fi.helsinki.cs.tmc.cli.backend.TmcUtil; import fi.helsinki.cs.tmc.cli.core.AbstractCommand; import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.core.Command; @@ -9,6 +8,7 @@ import fi.helsinki.cs.tmc.cli.io.ColorUtil; import fi.helsinki.cs.tmc.cli.io.Io; import fi.helsinki.cs.tmc.cli.io.WorkDir; +import fi.helsinki.cs.tmc.cli.shared.CourseFinder; import fi.helsinki.cs.tmc.core.domain.Course; import fi.helsinki.cs.tmc.core.domain.Exercise; @@ -17,19 +17,20 @@ import org.apache.commons.cli.Options; import java.util.Arrays; -import java.util.Date; import java.util.List; @Command(name = "info", desc = "Show info about the current directory") public class InfoCommand extends AbstractCommand { - private Course course; - private Exercise exercise; private CourseInfo info; private WorkDir workDir; private Io io; private CliContext ctx; + private boolean useWorkingDirectory; + private boolean fetchFromInternet; + private boolean showAll; + @Override public void getOptions(Options options) { options.addOption("a", "all", false, "Show all information for a specific course"); @@ -42,104 +43,119 @@ public void run(CliContext context, CommandLine args) { this.workDir = ctx.getWorkDir(); this.io = ctx.getIo(); - boolean fetchFromInternet = args.hasOption("i"); + String[] stringArgs = args.getArgs(); + useWorkingDirectory = (stringArgs.length == 0); + fetchFromInternet = args.hasOption("i"); + showAll = args.hasOption("a"); if (!ctx.loadBackendWithoutLogin()) { return; } - if (!fetchFromInternet) { - printLocalCourseOrExercise(args); - return; - } - - String[] stringArgs = args.getArgs(); - if (stringArgs.length == 0) { - io.println("You must give a course as an argument."); - return; + if (fetchFromInternet) { + if (useWorkingDirectory) { + io.println("You must give a course as an argument."); + return; + } + String courseName = stringArgs[0]; + printInfoFromInternet(courseName); + } else { + printLocalInfo(args.getArgs()); } + } + private void printInfoFromInternet(String courseName) { if (!ctx.hasLogin()) { io.println("Loading a course from a server requires login."); return; } - course = TmcUtil.findCourse(ctx, stringArgs[0]); - if (course == null) { - io.println("The course " + stringArgs[0] + " doesn't exist on the server."); - return; + CourseFinder finder = ctx.createCourseFinder(); + + if (finder.search(courseName)) { + printCourse(finder.getCourse()); } - printCourse(args.hasOption("a")); } - private void printLocalCourseOrExercise(CommandLine args) { + private void printLocalInfo(String[] stringArgs) { info = ctx.getCourseInfo(); - if (info != null) { - course = info.getCourse(); - printCourseOrExercise(args); - } else { - this.io.println("You have to be in a course directory" + if (info == null) { + io.println("You have to be in a course directory" + " or use the -i option with the course name " + "to get the information from the server."); - } - } - - private void printCourseOrExercise(CommandLine args) { - String[] stringArgs = args.getArgs(); - workDir.getExerciseNames(false, false, false); - - // if in exercise directory and no parameters given, print info for that exercise. - if (workDir.getExerciseNames(false, false, false).size() == 1 && stringArgs.length == 0) { - String currentExercise = workDir.getExerciseNames(false, false, false).get(0); - exercise = info.getExercise(currentExercise); - printOneExercise(args.hasOption("a")); return; } - if (stringArgs.length != 0) { - printCourseOrExerciseFromParameters(args); - return; + if (useWorkingDirectory) { + // if in exercise directory, print info for that exercise. + String exerciseName = getCurrentExercise(workDir); + if (exerciseName == null) { + printCourse(info.getCourse()); + } else { + printExercise(info.getExercise(exerciseName)); + } + } else { + if (stringArgs.length != 1) { + io.println("You can only give one path for this command."); + return; + } + String path = stringArgs[0]; + printInfoFromParameters(path); } - printCourse(args.hasOption("a")); } - private void printCourseOrExerciseFromParameters(CommandLine args) { - String[] stringArgs = args.getArgs(); - // if parameter is given, check if it is an exercise - // or a course. If neither, print an error message. - if (info.getExercise(stringArgs[0]) != null) { - exercise = info.getExercise(stringArgs[0]); - printOneExercise(args.hasOption("a")); + private void printInfoFromParameters(String pathName) { + // Check if path pointed to exercise directory + Exercise exercise = info.getExercise(pathName); + if (exercise != null) { + printExercise(exercise); return; - } - course = info.getCourse(); - if (course != null && course.getName().equals(stringArgs[0])) { - printCourse(args.hasOption("a")); + + // Check if path pointed to course directory + Course course = info.getCourse(); + if (course != null) { + printCourse(course); } else { - this.io.println("Wrong course directory." - + " Navigate to the correct course directory or" - + " use the -i option with the course name" - + " to get the information from the server."); + io.println("Not a course directory. "); + io.println("Use the -i option to get course from " + + "server."); } } - private void printCourse(boolean showAll) { - printCourseShort(); + private void printCourse(Course course) { + printCourseShort(course); if (showAll) { - printCourseDetails(); + printCourseDetails(course); } - printExercises(showAll); + printExerciseList(course); } - private void printCourseShort() { + private void printExerciseList(Course course) { + List exercises = course.getExercises(); + if (exercises == null || exercises.isEmpty()) { + io.println("Exercises: -"); + return; + } + + io.println("Exercises: "); + for (Exercise exercise : exercises) { + if (showAll) { + printExerciseFull(exercise); + } else { + io.println(" " + exercise.getName()); + } + } + } + + private void printCourseShort(Course course) { io.println("Course name: " + course.getName()); io.println("Number of available exercises: " + course.getExercises().size()); - io.println("Number of completed exercises: " + completedExercises()); + io.println("Number of completed exercises: " + getCompletedExerciseCount(course)); io.println("Number of locked exercises: " + course.getUnlockables().size()); } - private void printCourseDetails() { + private void printCourseDetails(Course course) { io.println("Unlockables:" + course.getUnlockables().toString()); io.println("Course id: " + course.getId()); io.println("Details URL: " + course.getDetailsUrl()); @@ -149,17 +165,17 @@ private void printCourseDetails() { io.println("CometUrl: " + course.getCometUrl()); } - private void printOneExercise(boolean showAll) { + private void printExercise(Exercise exercise) { if (showAll) { - printExercise(exercise); + printExerciseFull(exercise); } else { - printExerciseShort(); + printExerciseShort(exercise); } } - private void printExerciseShort() { + private void printExerciseShort(Exercise exercise) { io.println("Exercise: " + exercise.getName()); - io.println("Deadline: " + getDeadline(exercise)); + io.println("Deadline: " + exercise.getDeadlineDate()); if (exercise.hasDeadlinePassed() && !exercise.isCompleted()) { io.println(ColorUtil.colorString("deadline passed", Color.PURPLE)); @@ -167,40 +183,15 @@ private void printExerciseShort() { if (!exercise.isCompleted() && exercise.isAttempted()) { io.println(ColorUtil.colorString("attempted", Color.BLUE)); } else { - io.println(formatString("completed", exercise.isCompleted())); + printFlag("completed", exercise.isCompleted()); } if (exercise.requiresReview()) { - io.println(formatString("reviewed", exercise.isReviewed())); - } - } - } - - private String formatString(String string, boolean color) { - if (color) { - return ColorUtil.colorString(string, Color.GREEN); - } else { - return ColorUtil.colorString("not " + string, Color.RED); - } - } - - private void printExercises(boolean showAll) { - List exercises = course.getExercises(); - if (exercises == null || exercises.isEmpty()) { - io.println("Exercises: -"); - return; - } - - io.println("Exercises: "); - for (Exercise exercise : exercises) { - if (showAll) { - printExercise(exercise); - } else { - io.println(" " + exercise.getName()); + printFlag("reviewed", exercise.isReviewed()); } } } - private int completedExercises() { + private int getCompletedExerciseCount(Course course) { int completed = 0; for (Exercise exercise : course.getExercises()) { if (exercise.isCompleted()) { @@ -210,13 +201,31 @@ private int completedExercises() { return completed; } - private void printExercise(Exercise exercise) { + private String getCurrentExercise(WorkDir workDir) { + List exercises = workDir.getExerciseNames(false, false, false); + if (exercises.size() == 1) { + return exercises.get(0); + } + return null; + } + + private void printFlag(String string, boolean setting) { + Color color; + if (setting) { + color = Color.GREEN; + } else { + color = Color.RED; + string = "not " + string; + } + io.println(ColorUtil.colorString(string, color)); + } + + private void printExerciseFull(Exercise exercise) { io.println(" Exercise name: " + exercise.getName()); io.println(" Exercise id: " + exercise.getId()); io.println(" Is locked: " + exercise.isLocked()); io.println(" Deadline description: " + exercise.getDeadlineDescription()); - io.println(" Deadline: " + exercise.getDeadline()); - io.println(" Deadline date: " + exercise.getDeadlineDate()); + io.println(" Deadline: " + exercise.getDeadlineDate()); io.println(" Deadline passed: " + exercise.hasDeadlinePassed()); io.println(" Is returnable: " + exercise.isReturnable()); io.println(" Review required: " + exercise.requiresReview()); @@ -236,9 +245,4 @@ private void printExercise(Exercise exercise) { io.println(" Checksum: " + exercise.getChecksum()); io.println(""); } - - private String getDeadline(Exercise exercise) { - Date deadline = exercise.getDeadlineDate(); - return deadline.toString(); - } } 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 e540b319..8b64c690 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 @@ -10,9 +10,9 @@ import fi.helsinki.cs.tmc.cli.io.Io; import fi.helsinki.cs.tmc.cli.io.TerminalIo; import fi.helsinki.cs.tmc.cli.io.WorkDir; +import fi.helsinki.cs.tmc.cli.shared.CourseFinder; import fi.helsinki.cs.tmc.core.TmcCore; -import fi.helsinki.cs.tmc.core.domain.Course; import fi.helsinki.cs.tmc.langs.util.TaskExecutor; import fi.helsinki.cs.tmc.langs.util.TaskExecutorImpl; @@ -105,6 +105,15 @@ public WorkDir getWorkDir() { return workDir; } + /** + * Create new instance of course finder. + * This is used so that it's easy to mock out the course finder. + * + * @return new instance of CourseFinder + */ + public CourseFinder createCourseFinder() { + return new CourseFinder(this); + } /** * Get map of the properties. * diff --git a/src/main/java/fi/helsinki/cs/tmc/cli/shared/CourseFinder.java b/src/main/java/fi/helsinki/cs/tmc/cli/shared/CourseFinder.java index 3811f20f..85debd65 100644 --- a/src/main/java/fi/helsinki/cs/tmc/cli/shared/CourseFinder.java +++ b/src/main/java/fi/helsinki/cs/tmc/cli/shared/CourseFinder.java @@ -13,6 +13,7 @@ import java.util.Map; /** + * This class is used for searching courses from tmc servers. * TODO move some of the test from DownloadExercisesCommand to CourseFinder */ public class CourseFinder { diff --git a/src/test/java/fi/helsinki/cs/tmc/cli/command/InfoCommandTest.java b/src/test/java/fi/helsinki/cs/tmc/cli/command/InfoCommandTest.java index e7a41daf..07dc59d8 100644 --- a/src/test/java/fi/helsinki/cs/tmc/cli/command/InfoCommandTest.java +++ b/src/test/java/fi/helsinki/cs/tmc/cli/command/InfoCommandTest.java @@ -9,10 +9,12 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic; import fi.helsinki.cs.tmc.cli.Application; +import fi.helsinki.cs.tmc.cli.backend.Account; import fi.helsinki.cs.tmc.cli.backend.TmcUtil; import fi.helsinki.cs.tmc.cli.core.CliContext; import fi.helsinki.cs.tmc.cli.io.TestIo; import fi.helsinki.cs.tmc.cli.io.WorkDir; +import fi.helsinki.cs.tmc.cli.shared.CourseFinder; import fi.helsinki.cs.tmc.core.TmcCore; import fi.helsinki.cs.tmc.core.domain.Course; @@ -99,17 +101,28 @@ public void showErrorMessageIfNoCourseGivenWithIOption() { io.assertContains("You must give a course"); } + //TODO we should test this in CourseFinder not here. @Test - public void showMessageIfCourseDoesNotExistOnTheServer() { - when(TmcUtil.findCourse(eq(ctx), eq("foo"))).thenReturn(null); + public void dontShowCourseInfoIfTheCourseDoesntExist() { + ctx = spy(ctx); + app = new Application(ctx); + CourseFinder mockCourseFinder = mock(CourseFinder.class); + doReturn(mockCourseFinder).when(ctx).createCourseFinder(); + when(mockCourseFinder.search(eq("foo"))).thenReturn(false); String[] args = {"info", "foo", "-i"}; app.run(args); - io.assertContains("course foo doesn't exist"); + io.assertNotContains("Course name:"); } @Test - public void printCourseWithOptionI() { - when(TmcUtil.findCourse(eq(ctx), eq("test-course123"))).thenReturn(course); + public void printCourseWithInternet() { + ctx = spy(ctx); + app = new Application(ctx); + CourseFinder mockCourseFinder = mock(CourseFinder.class); + doReturn(mockCourseFinder).when(ctx).createCourseFinder(); + when(mockCourseFinder.search(eq("test-course123"))).thenReturn(true); + when(mockCourseFinder.getCourse()).thenReturn(course); + when(mockCourseFinder.getAccount()).thenReturn(new Account()); String[] args = {"info", "test-course123", "-i"}; app.run(args); @@ -118,8 +131,14 @@ public void printCourseWithOptionI() { } @Test - public void printCourseWithOptionsIAndA() { - when(TmcUtil.findCourse(eq(ctx), eq("test-course123"))).thenReturn(course); + public void printAllCourseExercisesWithInternet() { + ctx = spy(ctx); + app = new Application(ctx); + CourseFinder mockCourseFinder = mock(CourseFinder.class); + doReturn(mockCourseFinder).when(ctx).createCourseFinder(); + when(mockCourseFinder.search(eq("test-course123"))).thenReturn(true); + when(mockCourseFinder.getCourse()).thenReturn(course); + when(mockCourseFinder.getAccount()).thenReturn(new Account()); String[] args = {"info", "test-course123", "-a", "-i"}; app.run(args); @@ -128,8 +147,15 @@ public void printCourseWithOptionsIAndA() { @Test public void printCourseWithNoExercisesFromTheServer() { + ctx = spy(ctx); + app = new Application(ctx); + CourseFinder mockCourseFinder = mock(CourseFinder.class); + doReturn(mockCourseFinder).when(ctx).createCourseFinder(); + when(mockCourseFinder.search(eq("test-course123"))).thenReturn(true); + when(mockCourseFinder.getCourse()).thenReturn(course); + when(mockCourseFinder.getAccount()).thenReturn(new Account()); + course.setExercises(new ArrayList()); - when(TmcUtil.findCourse(eq(ctx), eq("test-course123"))).thenReturn(course); String[] args = {"info", "test-course123", "-i"}; app.run(args); @@ -173,8 +199,14 @@ public void printErrorMessageIfNotInCourseDirectoryAndCourseDoesntExist() { public void printGivenCourseFromTheServerIfInCourseDirectoryAndGivenCourseName() { workDir.setWorkdir(pathToDummyCourse); + ctx = spy(ctx); + app = new Application(ctx); + CourseFinder mockCourseFinder = mock(CourseFinder.class); + doReturn(mockCourseFinder).when(ctx).createCourseFinder(); + when(mockCourseFinder.search(eq("test-course123"))).thenReturn(true); + when(mockCourseFinder.getCourse()).thenReturn(course); + when(mockCourseFinder.getAccount()).thenReturn(new Account()); course.setExercises(new ArrayList()); - when(TmcUtil.findCourse(eq(ctx), eq("test-course123"))).thenReturn(course); String[] args = {"info", "test-course123", "-i"}; app.run(args); @@ -185,11 +217,15 @@ public void printGivenCourseFromTheServerIfInCourseDirectoryAndGivenCourseName() public void printsErrorIfInCourseDirectoryAndGivenCourseNameThatDoesntExistOnTheServer() { workDir.setWorkdir(pathToDummyCourse); - when(TmcUtil.findCourse(eq(ctx), eq("test-course123"))).thenReturn(course); + ctx = spy(ctx); + app = new Application(ctx); + CourseFinder mockCourseFinder = mock(CourseFinder.class); + doReturn(mockCourseFinder).when(ctx).createCourseFinder(); + when(mockCourseFinder.search(eq("test-course123"))).thenReturn(false); String[] args = {"info", "notacourse", "-i"}; app.run(args); - io.assertContains("doesn't exist on the server."); + io.assertNotContains("Course name:"); } @Test