diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameController.java b/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameController.java index a67f353620c78b5653c4eaac84220f9997f654d4..4c7a04ae43109665dbf93f6ef9d39076a1e448bc 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameController.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameController.java @@ -1,8 +1,14 @@ package edu.ntnu.idatt2003.controller; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionFactoryException; -import edu.ntnu.idatt2003.exceptions.ChaosGameException; -import edu.ntnu.idatt2003.exceptions.ChaosGameFileHandlerException; +import edu.ntnu.idatt2003.exceptions.CouldNotWriteException; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; +import edu.ntnu.idatt2003.exceptions.InvalidTypeException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; +import edu.ntnu.idatt2003.exceptions.ObservingException; +import edu.ntnu.idatt2003.exceptions.WrongFileFormatException; import edu.ntnu.idatt2003.model.game.ChaosGame; import edu.ntnu.idatt2003.model.game.ChaosGameDescription; import edu.ntnu.idatt2003.model.game.ChaosGameDescriptionFactory; @@ -12,6 +18,7 @@ import edu.ntnu.idatt2003.util.ExceptionLogger; import edu.ntnu.idatt2003.view.PopupHandler; import edu.ntnu.idatt2003.view.components.ViewCanvas; import java.io.File; +import java.io.FileNotFoundException; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.util.Duration; @@ -20,15 +27,25 @@ import javafx.util.Duration; * The controller class for the chaos game. */ public class ChaosGameController implements Observer { + //Constants for the chaos game. public static final int CHAOS_GAME_WIDTH = 680; public static final int CHAOS_GAME_HEIGHT = 680; public static final String START_DESCRIPTION = "Julia Set"; + //Constants for the animation + public static int RUN_SECONDS = 3; + public static int FPS = 60; + public static double K = 0.05; + + //Constant for unexpected exceptions not caused by the user + public static final String UNEXPECTED_EXCEPTION = + "Something went wrong. Please try again or restart."; + private ChaosGame chaosGame = null; private Timeline timeline; private final ViewCanvas viewCanvas; private final PopupHandler popupHandler; - private ExceptionLogger exceptionLogger; + private final ExceptionLogger exceptionLogger; /** * Constructor for the ChaosGameController class. @@ -36,15 +53,18 @@ public class ChaosGameController implements Observer { * @param viewCanvas the view canvas to draw on. */ public ChaosGameController(ViewCanvas viewCanvas, PopupHandler popupHandler) { + exceptionLogger = new ExceptionLogger("ChaosGameController"); this.viewCanvas = viewCanvas; this.popupHandler = popupHandler; try { - chaosGame = new ChaosGame(ChaosGameDescriptionFactory.get(START_DESCRIPTION), CHAOS_GAME_WIDTH, CHAOS_GAME_HEIGHT); + chaosGame = new ChaosGame(ChaosGameDescriptionFactory.get( + START_DESCRIPTION), CHAOS_GAME_WIDTH, CHAOS_GAME_HEIGHT); chaosGame.attach(this); - } catch (ChaosGameException | ChaosGameDescriptionFactoryException ex) { - popupHandler.showErrorPopup(ex.getMessage()); + } catch (EmptyListException | InvalidVectorRangeException | InvalidSignException + | IsNullException | InvalidTypeException | InvalidPositiveIntException e) { + exceptionLogger.logSevere(e); + popupHandler.showErrorPopup(UNEXPECTED_EXCEPTION); } - exceptionLogger = new ExceptionLogger("ChaosGameController"); } /** @@ -58,8 +78,10 @@ public class ChaosGameController implements Observer { chaosGame.resetGameWithDescription(newDescription); stopTimeline(); popupHandler.showSuccessPopup(description + " loaded successfully"); - } catch (ChaosGameDescriptionFactoryException | ChaosGameException ex) { - popupHandler.showErrorPopup(ex.getMessage()); + } catch (IsNullException | InvalidVectorRangeException | EmptyListException + | InvalidSignException | InvalidTypeException e) { + exceptionLogger.logSevere(e); + popupHandler.showErrorPopup(UNEXPECTED_EXCEPTION); } } @@ -89,8 +111,16 @@ public class ChaosGameController implements Observer { ChaosGameDescription newDescription = fileHandler.readFromFile(file); chaosGame.resetGameWithDescription(newDescription); popupHandler.showSuccessPopup("File loaded successfully"); - } catch (ChaosGameFileHandlerException | ChaosGameException ex) { - popupHandler.showErrorPopup(ex.getMessage()); + } catch (IsNullException | InvalidVectorRangeException + | EmptyListException | InvalidSignException e) { + exceptionLogger.logSevere(e); + popupHandler.showErrorPopup(e.getMessage()); + } catch (FileNotFoundException e) { + exceptionLogger.logWarning(e); + popupHandler.showErrorPopup("File not found"); + } catch (WrongFileFormatException e) { + exceptionLogger.logWarning(e); + popupHandler.showErrorPopup(e.getMessage()); } } @@ -100,8 +130,9 @@ public class ChaosGameController implements Observer { public void runSteps(int steps) { try { chaosGame.runSteps(steps); - } catch (ChaosGameException ex) { - popupHandler.showErrorPopup(ex.getMessage()); + } catch (InvalidPositiveIntException e) { + exceptionLogger.logWarning(e); + popupHandler.showErrorPopup(e.getMessage()); } } @@ -155,39 +186,43 @@ public class ChaosGameController implements Observer { */ public void animateIterations(int iterations) { if (iterations <= 0) { - popupHandler.showErrorPopup("Iterations must be a positive number"); + try { + throw new InvalidPositiveIntException("Iterations must be a positive number"); + } catch (InvalidPositiveIntException e) { + exceptionLogger.logWarning(e); + popupHandler.showErrorPopup(e.getMessage()); + } return; } - int runSeconds = 3; - int fps = 60; final int [] x = {0}; - double k = 0.05; final int [] totalSteps = {0}; timeline = new Timeline(); - KeyFrame keyFrame = new KeyFrame(Duration.millis(1000.0 / fps), e -> { - int steps = (int) (iterations * k / Math.exp(fps * runSeconds * k) * Math.exp(k * x[0])); + KeyFrame keyFrame = new KeyFrame(Duration.millis(1000.0 / FPS), e -> { + int steps = (int) (iterations * K / Math.exp(FPS * RUN_SECONDS * K) * Math.exp(K * x[0])); try { if (steps != 0) { chaosGame.runSteps(steps); } - } catch (ChaosGameException ex) { - popupHandler.showErrorPopup(ex.getMessage()); + } catch (InvalidPositiveIntException ex) { + exceptionLogger.logSevere(ex); + popupHandler.showErrorPopup(UNEXPECTED_EXCEPTION); timeline.stop(); } x[0]++; totalSteps[0] += steps; }); timeline.getKeyFrames().add(keyFrame); - timeline.setCycleCount(fps * runSeconds); + timeline.setCycleCount(FPS * RUN_SECONDS); timeline.setOnFinished(e -> { try { if (iterations - totalSteps[0] != 0) { chaosGame.runSteps(iterations - totalSteps[0]); } - } catch (ChaosGameException ex) { - popupHandler.showErrorPopup(ex.getMessage()); + } catch (InvalidPositiveIntException ex) { + exceptionLogger.logSevere(ex); + popupHandler.showErrorPopup(UNEXPECTED_EXCEPTION); } }); timeline.play(); @@ -227,8 +262,9 @@ public class ChaosGameController implements Observer { try { fileHandler.writeToFile(chaosGame.getDescriptions(), file); popupHandler.showSuccessPopup("File written successfully"); - } catch (ChaosGameFileHandlerException ex) { - popupHandler.showErrorPopup(ex.getMessage()); + } catch (CouldNotWriteException e) { + exceptionLogger.logSevere(e); + popupHandler.showErrorPopup(UNEXPECTED_EXCEPTION); } } @@ -236,6 +272,13 @@ public class ChaosGameController implements Observer { return popupHandler; } + /** + * logs a warning exception. + */ + public void logWarning(Exception e) { + exceptionLogger.logWarning(e); + } + /** * When the chaosGame is updated, this method is called. */ @@ -245,6 +288,14 @@ public class ChaosGameController implements Observer { case "clearGame" -> viewCanvas.reset(); case "putPixel" -> drawCurrentPixel(); case "setDescription" -> System.out.println("description"); + default -> { + try { + throw new ObservingException(updated + " is not being observed."); + } catch (ObservingException e) { + exceptionLogger.logSevere(e); + popupHandler.showErrorPopup(UNEXPECTED_EXCEPTION); + } + } } } } diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosCanvasException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosCanvasException.java deleted file mode 100644 index 4e0cde28d90a3d1bd419fc5606dd7fbe1bfacdfd..0000000000000000000000000000000000000000 --- a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosCanvasException.java +++ /dev/null @@ -1,32 +0,0 @@ -package edu.ntnu.idatt2003.exceptions; - -/** - * Exception class for ChaosCanvas. - */ -public class ChaosCanvasException extends Exception { - /** - * Constructs a new ChaosCanvasException with the default message. - */ - public ChaosCanvasException() { - super("Chaos canvas exception occurred."); - } - - /** - * Constructs a new ChaosCanvasException with the specified message and cause. - * - * @param message the message - * @param cause the cause - */ - public ChaosCanvasException(String message, Throwable cause) { - super(message, cause); - } - - /** - * Constructs a new ChaosCanvasException with the specified message. - * - * @param message the message - */ - public ChaosCanvasException(String message) { - super(message); - } -} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionException.java deleted file mode 100644 index 679b88da4e95de6ddd128d5e3ada652e9216851b..0000000000000000000000000000000000000000 --- a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionException.java +++ /dev/null @@ -1,32 +0,0 @@ -package edu.ntnu.idatt2003.exceptions; - -/** - * Exception class for ChaosGameDescription. - */ -public class ChaosGameDescriptionException extends Exception { - /** - * Constructs a new ChaosGameDescriptionException with the default message. - */ - public ChaosGameDescriptionException() { - super("An error occurred in the ChaosGameDescription class."); - } - - /** - * Constructs a new ChaosGameDescriptionException with the specified message. - * - * @param message the message - */ - public ChaosGameDescriptionException(String message) { - super(message); - } - - /** - * Constructs a new ChaosGameDescriptionException with the specified message and cause. - * - * @param message the message - * @param cause the cause - */ - public ChaosGameDescriptionException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionFactoryException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionFactoryException.java deleted file mode 100644 index 9d9acce6775ead35e1f86ea36a6b3699f9dc8bd8..0000000000000000000000000000000000000000 --- a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionFactoryException.java +++ /dev/null @@ -1,32 +0,0 @@ -package edu.ntnu.idatt2003.exceptions; - -/** - * Exception class for ChaosGameDescriptionFactory. - */ -public class ChaosGameDescriptionFactoryException extends Exception { - /** - * Constructs a new ChaosGameDescriptionFactoryException with the default message. - */ - public ChaosGameDescriptionFactoryException() { - super("An error occurred while creating a ChaosGameDescription object."); - } - - /** - * Constructs a new ChaosGameDescriptionFactoryException with the specified message and cause. - * - * @param message the message - * @param cause the cause - */ - public ChaosGameDescriptionFactoryException(String message, Throwable cause) { - super(message, cause); - } - - /** - * Constructs a new ChaosGameDescriptionFactoryException with the specified message. - * - * @param message the message - */ - public ChaosGameDescriptionFactoryException(String message) { - super(message); - } -} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameException.java deleted file mode 100644 index e31a7ea6b40c0c0b97c7019cc7d11ef19681c60c..0000000000000000000000000000000000000000 --- a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameException.java +++ /dev/null @@ -1,32 +0,0 @@ -package edu.ntnu.idatt2003.exceptions; - -/** - * Exception class for ChaosGame. - */ -public class ChaosGameException extends Exception { - /** - * Constructs a new ChaosGameException with the default message. - */ - public ChaosGameException() { - super("Chaos game exception occurred."); - } - - /** - * Constructs a new ChaosGameException with the specified message and cause. - * - * @param message the message - * @param cause the cause - */ - public ChaosGameException(String message, Throwable cause) { - super(message, cause); - } - - /** - * Constructs a new ChaosGameException with the specified message. - * - * @param message the message - */ - public ChaosGameException(String message) { - super(message); - } -} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameFileHandlerException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameFileHandlerException.java deleted file mode 100644 index 1f6c62e28810c76b0cf1fa0c13890e0c9017e265..0000000000000000000000000000000000000000 --- a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameFileHandlerException.java +++ /dev/null @@ -1,32 +0,0 @@ -package edu.ntnu.idatt2003.exceptions; - -/** - * Exception class for ChaosGameFileHandler. - */ -public class ChaosGameFileHandlerException extends Exception { - /** - * Constructs a new ChaosGameFileHandlerException with the default message. - */ - public ChaosGameFileHandlerException() { - super("An error occurred while handling the file"); - } - - /** - * Constructs a new ChaosGameFileHandlerException with the specified message and cause. - * - * @param message the message - * @param cause the cause - */ - public ChaosGameFileHandlerException(String message, Throwable cause) { - super(message, cause); - } - - /** - * Constructs a new ChaosGameFileHandlerException with the specified message. - * - * @param message the message - */ - public ChaosGameFileHandlerException(String message) { - super(message); - } -} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/CouldNotWriteException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/CouldNotWriteException.java new file mode 100644 index 0000000000000000000000000000000000000000..6617c12052a418c3752f6bf536f9ad49714234db --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/CouldNotWriteException.java @@ -0,0 +1,32 @@ +package edu.ntnu.idatt2003.exceptions; + +/** + * Exception class for when a file could not be written to. + */ +public class CouldNotWriteException extends Exception { + /** + * Constructs a new CouldNotWriteException with the default message. + */ + public CouldNotWriteException() { + super("Could not write exception occurred."); + } + + /** + * Constructs a new CouldNotWriteException with the specified message and cause. + * + * @param message the message + * @param cause the cause + */ + public CouldNotWriteException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new CouldNotWriteException with the specified message. + * + * @param message the message + */ + public CouldNotWriteException(String message) { + super(message); + } +} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/EmptyListException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/EmptyListException.java new file mode 100644 index 0000000000000000000000000000000000000000..9e3e27bcd4f2767304f9a2e650ad4b466464693d --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/EmptyListException.java @@ -0,0 +1,32 @@ +package edu.ntnu.idatt2003.exceptions; + +/** + * Exception class for empty lists. + */ +public class EmptyListException extends Exception { + /** + * Constructs a new EmptyListException with the default message. + */ + public EmptyListException() { + super("Empty list exception occurred."); + } + + /** + * Constructs a new EmptyListException with the specified message and cause. + * + * @param message the message + * @param cause the cause + */ + public EmptyListException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new EmptyListException with the specified message. + * + * @param message the message + */ + public EmptyListException(String message) { + super(message); + } +} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidPositiveIntException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidPositiveIntException.java new file mode 100644 index 0000000000000000000000000000000000000000..ecd5d1b5ac7af609efb0d74723c6338f2f1827cf --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidPositiveIntException.java @@ -0,0 +1,32 @@ +package edu.ntnu.idatt2003.exceptions; + +/** + * Exception class for invalid positive integers. + */ +public class InvalidPositiveIntException extends Exception { + /** + * Constructs a new InvalidPositiveIntException with the default message. + */ + public InvalidPositiveIntException() { + super("Invalid positive integer exception occurred."); + } + + /** + * Constructs a new InvalidPositiveIntException with the specified message and cause. + * + * @param message the message + * @param cause the cause + */ + public InvalidPositiveIntException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new InvalidPositiveIntException with the specified message. + * + * @param message the message + */ + public InvalidPositiveIntException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidSignException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidSignException.java new file mode 100644 index 0000000000000000000000000000000000000000..8f1e11fb186a5fba0a582e2556e5eb2454ecc1a7 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidSignException.java @@ -0,0 +1,33 @@ +package edu.ntnu.idatt2003.exceptions; + +/** + * Exception class for invalid signs. + */ +public class InvalidSignException extends Exception { + + /** + * Constructs a new InvalidSignException with the default message. + */ + public InvalidSignException() { + super("Invalid sign exception occurred."); + } + + /** + * Constructs a new InvalidSignException with the specified message and cause. + * + * @param message the message + * @param cause the cause + */ + public InvalidSignException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new InvalidSignException with the specified message. + * + * @param message the message + */ + public InvalidSignException(String message) { + super(message); + } +} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidTypeException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidTypeException.java new file mode 100644 index 0000000000000000000000000000000000000000..37d2f80d4b39d966922e29cb2adecdc2d70fd759 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidTypeException.java @@ -0,0 +1,32 @@ +package edu.ntnu.idatt2003.exceptions; + +/** + * Exception class for invalid types. + */ +public class InvalidTypeException extends Exception { + /** + * Constructs a new InvalidTypeException with the default message. + */ + public InvalidTypeException() { + super("Invalid type exception occurred."); + } + + /** + * Constructs a new InvalidTypeException with the specified message and cause. + * + * @param message the message + * @param cause the cause + */ + public InvalidTypeException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new InvalidTypeException with the specified message. + * + * @param message the message + */ + public InvalidTypeException(String message) { + super(message); + } +} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidVectorRangeException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidVectorRangeException.java new file mode 100644 index 0000000000000000000000000000000000000000..38d5b2fc8fd81eeaa713e545adeee97fdf2b2517 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidVectorRangeException.java @@ -0,0 +1,33 @@ +package edu.ntnu.idatt2003.exceptions; + +/** + * Exception class for invalid vector ranges. + */ +public class InvalidVectorRangeException extends Exception { + + /** + * Constructs a new InvalidVectorRangeException with the default message. + */ + public InvalidVectorRangeException() { + super("Invalid vector range exception occurred."); + } + + /** + * Constructs a new InvalidVectorRangeException with the specified message and cause. + * + * @param message the message + * @param cause the cause + */ + public InvalidVectorRangeException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new InvalidVectorRangeException with the specified message. + * + * @param message the message + */ + public InvalidVectorRangeException(String message) { + super(message); + } +} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/IsNullException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/IsNullException.java new file mode 100644 index 0000000000000000000000000000000000000000..3e4483ced5ca54b7813b2369e918ce1eeba0d5af --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/IsNullException.java @@ -0,0 +1,32 @@ +package edu.ntnu.idatt2003.exceptions; + +/** + * Exception class for objects that are null. + */ +public class IsNullException extends Exception { + /** + * Constructs a new NullException with the default message. + */ + public IsNullException() { + super("Null exception occurred."); + } + + /** + * Constructs a new NullException with the specified message and cause. + * + * @param message the message + * @param cause the cause + */ + public IsNullException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new NullException with the specified message. + * + * @param message the message + */ + public IsNullException(String message) { + super(message); + } +} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/ObservingException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/ObservingException.java new file mode 100644 index 0000000000000000000000000000000000000000..5139a67e5fce96b346f3c67f87374104bb0adf63 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/ObservingException.java @@ -0,0 +1,32 @@ +package edu.ntnu.idatt2003.exceptions; + +/** + * Exception class for exceptions caused by observing. + */ +public class ObservingException extends Exception { + /** + * Constructs a new ObservingException with the default message. + */ + public ObservingException() { + super("Observing exception occurred."); + } + + /** + * Constructs a new ObservingException with the specified message and cause. + * + * @param message the message + * @param cause the cause + */ + public ObservingException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new ObservingException with the specified message. + * + * @param message the message + */ + public ObservingException(String message) { + super(message); + } +} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/WrongFileFormatException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/WrongFileFormatException.java index d558923028234fb3d0da1973e11bb091e205f942..d9340512831c09e78e65ef1bcb5c94a740d9a997 100644 --- a/src/main/java/edu/ntnu/idatt2003/exceptions/WrongFileFormatException.java +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/WrongFileFormatException.java @@ -1,9 +1,9 @@ package edu.ntnu.idatt2003.exceptions; /** - * Exception class for ChaosGameFileHandler. + * Exception class for wrongly formatted files. */ -public class WrongFileFormatException extends ChaosGameFileHandlerException { +public class WrongFileFormatException extends Exception { /** * Constructs a new WrongFileFormatException with the default message. */ diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/WrongLengthException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/WrongLengthException.java new file mode 100644 index 0000000000000000000000000000000000000000..5d3cd2514269261854eb3dddc81e30048c4cbdf8 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/WrongLengthException.java @@ -0,0 +1,32 @@ +package edu.ntnu.idatt2003.exceptions; + +/** + * Exception class for wrong length. + */ +public class WrongLengthException extends Exception { + /** + * Constructs a new WrongLengthException with the default message. + */ + public WrongLengthException() { + super("Wrong length exception occurred."); + } + + /** + * Constructs a new WrongLengthException with the specified message and cause. + * + * @param message the message + * @param cause the cause + */ + public WrongLengthException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new WrongLengthException with the specified message. + * + * @param message the message + */ + public WrongLengthException(String message) { + super(message); + } +} diff --git a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosCanvas.java b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosCanvas.java index 73c0ac52d9d1393377a4561473b136d05a9b4846..0be394afebabf85cf5bf6004529c8cd9456ee182 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosCanvas.java +++ b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosCanvas.java @@ -1,6 +1,8 @@ package edu.ntnu.idatt2003.model.game; -import edu.ntnu.idatt2003.exceptions.ChaosCanvasException; +import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import edu.ntnu.idatt2003.model.math.mathModel.Matrix2x2; import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; import edu.ntnu.idatt2003.model.math.transformation.AffineTransform2D; @@ -28,20 +30,20 @@ public class ChaosCanvas { * @param minCoords the minimum coordinates of the canvas. * @param maxCoords the maximum coordinates of the canvas. * - * @throws IllegalArgumentException if width is not positive, - * if height is not positive, - * if minCoords is null, - * if maxCoords is null + * @throws InvalidPositiveIntException if width is not positive, + * if height is not positive, + * if minCoords is null, + * if maxCoords is null + * @throws IsNullException if minCoords or maxCoords are null, + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the + * maximum coordinates. */ public ChaosCanvas(int width, int height, Vector2D minCoords, Vector2D maxCoords) - throws ChaosCanvasException { - try { - InputValidation.validatePositiveInt(width, "width"); - InputValidation.validatePositiveInt(height, "height"); - setMinMaxCoords(minCoords, maxCoords); - } catch (IllegalArgumentException e) { - throw new ChaosCanvasException("An error occurred while creating the ChaosCanvas class", e); - } + throws InvalidPositiveIntException, IsNullException, InvalidVectorRangeException { + InputValidation.validatePositiveInt(width, "width"); + InputValidation.validatePositiveInt(height, "height"); + + setMinMaxCoords(minCoords, maxCoords); this.width = width; this.height = height; this.canvas = new int[width][height]; @@ -69,8 +71,9 @@ public class ChaosCanvas { * Sets the minimum coordinates of the canvas. * * @param minCoords the minimum coordinates of the canvas. + * @throws IsNullException if minCoords is null */ - private void setMinCoords(Vector2D minCoords) { + private void setMinCoords(Vector2D minCoords) throws IsNullException { InputValidation.validateNotNull(minCoords, "minCoords"); this.minCoords = minCoords; } @@ -79,8 +82,9 @@ public class ChaosCanvas { * Sets the maximum coordinates of the canvas. * * @param maxCoords the maximum coordinates of the canvas. + * @throws IsNullException if maxCoords is null */ - private void setMaxCoords(Vector2D maxCoords) { + private void setMaxCoords(Vector2D maxCoords) throws IsNullException { InputValidation.validateNotNull(maxCoords, "maxCoords"); this.maxCoords = maxCoords; } @@ -91,18 +95,17 @@ public class ChaosCanvas { * @param minCoords the minimum coordinates of the canvas. * @param maxCoords the maximum coordinates of the canvas. * - * @throws IllegalArgumentException if minCoords is null, - * if maxCoords is null + * @throws IsNullException if minCoords is null, + * if maxCoords is null */ - public void setMinMaxCoords(Vector2D minCoords, Vector2D maxCoords) throws ChaosCanvasException { - try { - setMinCoords(minCoords); - setMaxCoords(maxCoords); - setTransformCoordsToIndices(); - } catch (IllegalArgumentException e) { - throw new ChaosCanvasException( - "An error occurred while setting the min and max coordinates", e); - } + public void setMinMaxCoords(Vector2D minCoords, Vector2D maxCoords) + throws IsNullException, InvalidVectorRangeException { + setMinCoords(minCoords); + setMaxCoords(maxCoords); + + InputValidation.validateVectorRange(minCoords, maxCoords); + + setTransformCoordsToIndices(); } /** diff --git a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGame.java b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGame.java index c101d84cdc3a03bff39ad2f78bd8c8f8c5646c3f..07ae75f3a8dd66321a0a212a20487bbdeab6feb2 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGame.java +++ b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGame.java @@ -1,7 +1,8 @@ package edu.ntnu.idatt2003.model.game; -import edu.ntnu.idatt2003.exceptions.ChaosCanvasException; -import edu.ntnu.idatt2003.exceptions.ChaosGameException; +import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; import edu.ntnu.idatt2003.model.math.transformation.Transform2D; import edu.ntnu.idatt2003.util.InputValidation; @@ -23,18 +24,18 @@ public class ChaosGame extends Subject { * @param description the description of the chaos game. * @param width the width of the canvas. * @param height the height of the canvas. + * @throws IsNullException if the description is null. + * @throws InvalidPositiveIntException if the width or height are not positive. + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the + * maximum coordinates. */ public ChaosGame(ChaosGameDescription description, int width, int height) - throws ChaosGameException { - try { - InputValidation.validateNotNull(description, "description"); - this.canvas = new ChaosCanvas( - width, height, description.getMinCoords(), description.getMaxCoords()); - } catch (IllegalArgumentException e) { - throw new ChaosGameException("The description of the chaos game cannot be null.", e); - } catch (ChaosCanvasException e) { - throw new ChaosGameException("An error occurred while creating the ChaosCanvas class.", e); - } + throws IsNullException, InvalidPositiveIntException, + InvalidVectorRangeException { + InputValidation.validateNotNull(description, "description"); + + this.canvas = new ChaosCanvas( + width, height, description.getMinCoords(), description.getMaxCoords()); this.description = description; this.currentPoint = new Vector2D(0, 0); this.random = new Random(); @@ -60,17 +61,17 @@ public class ChaosGame extends Subject { /** * Sets the description of the chaos game. + * + * @param description the description of the chaos game. + * @throws IsNullException if the description is null. + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the + * maximum coordinates. */ - private void setDescription(ChaosGameDescription description) throws ChaosGameException { - try { - InputValidation.validateNotNull(description, "description"); - canvas.setMinMaxCoords(description.getMinCoords(), description.getMaxCoords()); - } catch (IllegalArgumentException e) { - throw new ChaosGameException("The description of the chaos game cannot be null.", e); - } catch (ChaosCanvasException e) { - throw new ChaosGameException( - "An error occurred while setting the description of the chaos game.", e); - } + private void setDescription(ChaosGameDescription description) + throws IsNullException, InvalidVectorRangeException { + InputValidation.validateNotNull(description, "description"); + + canvas.setMinMaxCoords(description.getMinCoords(), description.getMaxCoords()); this.description = description; notifyObservers("setDescription"); } @@ -88,8 +89,11 @@ public class ChaosGame extends Subject { * Resets the canvas and sets new description for the chaos game. * * @param description the description to reset the chaos game with. + * @throws IsNullException if the description is null. + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the */ - public void resetGameWithDescription(ChaosGameDescription description) throws ChaosGameException { + public void resetGameWithDescription(ChaosGameDescription description) + throws IsNullException, InvalidVectorRangeException { setDescription(description); resetGame(); } @@ -98,13 +102,11 @@ public class ChaosGame extends Subject { * Runs the chaos game for the given number of steps. * * @param steps the number of steps to run the chaos game for. + * @throws InvalidPositiveIntException if the number of steps is not positive. */ - public void runSteps(int steps) throws ChaosGameException { - try { - InputValidation.validatePositiveInt(steps, "steps"); - } catch (IllegalArgumentException e) { - throw new ChaosGameException("The number of steps must be positive.", e); - } + public void runSteps(int steps) throws InvalidPositiveIntException { + InputValidation.validatePositiveInt(steps, "steps"); + List<Transform2D> transforms = description.getTransforms(); for (int i = 0; i < steps; i++) { Transform2D currentTransformation = transforms.get(random.nextInt(transforms.size())); diff --git a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescription.java b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescription.java index 8488aa75248c42352f8d684e8f81517e2d191696..fa61df37d42b8d7750c8b520d26bc01bdaebe758 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescription.java +++ b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescription.java @@ -1,6 +1,8 @@ package edu.ntnu.idatt2003.model.game; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; import edu.ntnu.idatt2003.model.math.transformation.Transform2D; import edu.ntnu.idatt2003.util.InputValidation; @@ -21,23 +23,19 @@ public class ChaosGameDescription { * @param minCoords the minimum coordinates. * @param maxCoords the maximum coordinates. * - * @throws ChaosGameDescriptionException if the list of transforms is null, - * if the list of transforms is empty, - * if minCoords is null, - * if maxCoords is null, - * if minCoords is greater than or equal to maxCoords + * @throws IsNullException if any of the parameters are null. + * @throws EmptyListException if the list of transforms is empty. + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the + * maximum coordinates. */ public ChaosGameDescription(List<Transform2D> transforms, Vector2D minCoords, Vector2D maxCoords) - throws ChaosGameDescriptionException { - try { - InputValidation.validateNotNull(transforms, "transforms"); - InputValidation.validateListNotEmpty(transforms, "transforms"); - InputValidation.validateNotNull(minCoords, "minCoords"); - InputValidation.validateNotNull(maxCoords, "maxCoords"); - validateCoordinates(minCoords, maxCoords); - } catch (IllegalArgumentException e) { - throw new ChaosGameDescriptionException("Invalid ChaosGameDescription", e); - } + throws IsNullException, EmptyListException, InvalidVectorRangeException { + InputValidation.validateNotNull(transforms, "transforms"); + InputValidation.validateListNotEmpty(transforms, "transforms"); + InputValidation.validateNotNull(minCoords, "minCoords"); + InputValidation.validateNotNull(maxCoords, "maxCoords"); + InputValidation.validateVectorRange(minCoords, maxCoords); + this.transforms = transforms; this.minCoords = minCoords; this.maxCoords = maxCoords; @@ -76,12 +74,12 @@ public class ChaosGameDescription { * @param minCoords the minimum coordinates. * @param maxCoords the maximum coordinates. * - * @throws ChaosGameDescriptionException if minCoords is greater than or equal to maxCoords + * @throws InvalidVectorRangeException if minCoords is greater than or equal to maxCoords */ private void validateCoordinates(Vector2D minCoords, Vector2D maxCoords) - throws ChaosGameDescriptionException { + throws InvalidVectorRangeException { if (minCoords.getX0() >= maxCoords.getX0() || minCoords.getX1() >= maxCoords.getX1()) { - throw new ChaosGameDescriptionException("minCoords must be less than maxCoords"); + throw new InvalidVectorRangeException("minCoords must be less than maxCoords"); } } diff --git a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactory.java b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactory.java index 04ad1d06d81244033f9993e9697ce10b052b7cbf..f060b1a5776b0ef5c05ecd1267bc470da75b0889 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactory.java +++ b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactory.java @@ -1,7 +1,10 @@ package edu.ntnu.idatt2003.model.game; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionFactoryException; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; +import edu.ntnu.idatt2003.exceptions.InvalidTypeException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import edu.ntnu.idatt2003.model.math.mathModel.Complex; import edu.ntnu.idatt2003.model.math.mathModel.Matrix2x2; import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; @@ -21,14 +24,21 @@ public class ChaosGameDescriptionFactory { * * @param type the type of chaos game to create. * @return a ChaosGameDescription object. - * @throws ChaosGameDescriptionFactoryException if the type is invalid. + * @throws InvalidTypeException if the transformation type is invalid. + * @throws EmptyListException if the list of transforms is empty. + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the + * maximum coordinates. + * @throws IsNullException if any of the parameters are null. + * @throws InvalidSignException if the sign of the vector is invalid. */ - public static ChaosGameDescription get(String type) throws ChaosGameDescriptionFactoryException { + public static ChaosGameDescription get(String type) + throws EmptyListException, InvalidVectorRangeException, + InvalidSignException, IsNullException, InvalidTypeException { return switch (type) { case "Sierpinski" -> createSierpinskiTriangle(); case "Barnsley" -> createBarnsleyFern(); case "Julia Set" -> createJuliaSet(); - default -> throw new ChaosGameDescriptionFactoryException("Invalid chaos game type"); + default -> throw new InvalidTypeException("Invalid description type"); }; } @@ -36,31 +46,37 @@ public class ChaosGameDescriptionFactory { * Helper method for creating a chaos game description of the Julia set. * * @return a list of the available chaos game types. - * @throws ChaosGameDescriptionFactoryException if an error occurs while creating the chaos game + * @throws EmptyListException if the list of transforms is empty. + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the + * maximum coordinates. + * @throws IsNullException if any of the parameters are null. + * @throws InvalidSignException if the sign of the vector is invalid. */ - private static ChaosGameDescription createJuliaSet() throws ChaosGameDescriptionFactoryException { + private static ChaosGameDescription createJuliaSet() + throws EmptyListException, InvalidVectorRangeException, InvalidSignException, + IsNullException { List<Transform2D> transforms = List.of( new JuliaTransform(new Complex(0, 0.8), 1), new JuliaTransform(new Complex(0, 0.8), -1) ); Vector2D minCoords = new Vector2D(-1.4, -1.4); Vector2D maxCoords = new Vector2D(1.4, 1.4); - try { - return new ChaosGameDescription(transforms, minCoords, maxCoords); - } catch (ChaosGameDescriptionException e) { - throw new ChaosGameDescriptionFactoryException( - "An error occurred while creating a ChaosGameDescription object in factory.", e); - } + + return new ChaosGameDescription(transforms, minCoords, maxCoords); } /** * Helper method for creating a chaos game description of the Barnsley fern. * * @return a list of the available chaos game types. - * @throws ChaosGameDescriptionFactoryException if an error occurs while creating the chaos game + * @throws IsNullException if any of the parameters are null. + * @throws EmptyListException if the list of transforms is empty. + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the + * maximum coordinates. */ private static ChaosGameDescription createBarnsleyFern() - throws ChaosGameDescriptionFactoryException { + throws IsNullException, EmptyListException, + InvalidVectorRangeException { List<Transform2D> transforms = List.of( new AffineTransform2D(new Matrix2x2(0, 0, 0, 0.16), new Vector2D(0, 0)), new AffineTransform2D(new Matrix2x2(0.85, 0.04, -0.04, 0.85), new Vector2D(0, 1.6)), @@ -69,22 +85,22 @@ public class ChaosGameDescriptionFactory { ); Vector2D minCoords = new Vector2D(-2.65, 0); Vector2D maxCoords = new Vector2D(2.65, 10); - try { - return new ChaosGameDescription(transforms, minCoords, maxCoords); - } catch (ChaosGameDescriptionException e) { - throw new ChaosGameDescriptionFactoryException( - "An error occurred while creating a ChaosGameDescription object in factory.", e); - } + + return new ChaosGameDescription(transforms, minCoords, maxCoords); } /** * Helper method for creating a chaos game description of the Sierpinski triangle. * * @return a list of the available chaos game types. - * @throws ChaosGameDescriptionFactoryException if an error occurs while creating the chaos game + * @throws IsNullException if any of the parameters are null. + * @throws EmptyListException if the list of transforms is empty. + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the + * maximum coordinates. */ private static ChaosGameDescription createSierpinskiTriangle() - throws ChaosGameDescriptionFactoryException { + throws IsNullException, EmptyListException, + InvalidVectorRangeException { List<Transform2D> transforms = List.of( new AffineTransform2D(new Matrix2x2(0.5, 0, 0, 0.5), new Vector2D(0, 0)), new AffineTransform2D(new Matrix2x2(0.5, 0, 0, 0.5), new Vector2D(0.5, 0)), @@ -92,11 +108,8 @@ public class ChaosGameDescriptionFactory { ); Vector2D minCoords = new Vector2D(0, 0); Vector2D maxCoords = new Vector2D(1, 1); - try { - return new ChaosGameDescription(transforms, minCoords, maxCoords); - } catch (ChaosGameDescriptionException e) { - throw new ChaosGameDescriptionFactoryException( - "An error occurred while creating a ChaosGameDescription object in factory.", e); - } + + return new ChaosGameDescription(transforms, minCoords, maxCoords); + } } diff --git a/src/main/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandler.java b/src/main/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandler.java index 5f64769ec0c1524fc4f4d53227d079e70455617a..6490c294304f49d9f90d4d319c2914f27a8223d6 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandler.java +++ b/src/main/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandler.java @@ -1,8 +1,12 @@ package edu.ntnu.idatt2003.model.io; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException; -import edu.ntnu.idatt2003.exceptions.ChaosGameFileHandlerException; +import edu.ntnu.idatt2003.exceptions.CouldNotWriteException; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import edu.ntnu.idatt2003.exceptions.WrongFileFormatException; +import edu.ntnu.idatt2003.exceptions.WrongLengthException; import edu.ntnu.idatt2003.model.game.ChaosGameDescription; import edu.ntnu.idatt2003.model.math.mathModel.Complex; import edu.ntnu.idatt2003.model.math.mathModel.Matrix2x2; @@ -34,24 +38,31 @@ public class ChaosGameFileHandler { * * @param file the file to be read. * @return the ChaosGameDescription read from the file. - * @throws ChaosGameFileHandlerException if the file is not found. - * @throws ChaosGameDescriptionException if the ChaosGameDescription could not be created. + * @throws FileNotFoundException if the file is not found. + * @throws WrongFileFormatException if the ChaosGameDescription could not be created. + * @throws IsNullException if an object is null. + * @throws EmptyListException if a list is empty. + * @throws InvalidVectorRangeException if the vector range is invalid. + * @throws InvalidSignException if the sign is invalid. */ public ChaosGameDescription readFromFile(File file) - throws ChaosGameFileHandlerException { + throws WrongFileFormatException, IsNullException, EmptyListException, + InvalidVectorRangeException, InvalidSignException, FileNotFoundException { List<List<String>> lines = divideFileToLines(file); - if (lines.size() <= 3) { - throw new WrongFileFormatException(); + + try { + InputValidation.validateListLessOrEqualThan(lines, 3, "lines"); + } catch (WrongLengthException e) { + throw new WrongFileFormatException("The file should have at least three lines", e); } + List<String> type = lines.getFirst(); try { InputValidation.validateNotNull(type, "type"); - } catch (IllegalArgumentException e) { + InputValidation.validateListLength(type, 1, "type"); + } catch (IsNullException | WrongLengthException e) { throw new WrongFileFormatException("The file should have one transformation type", e); } - if (type.size() != 1) { - throw new WrongFileFormatException("The file should have one transformation type"); - } if (!type.getFirst().equals("Affine2D") && !type.getFirst().equals("Julia")) { throw new WrongFileFormatException("The file has an unsupported transformation type"); } @@ -61,12 +72,11 @@ public class ChaosGameFileHandler { try { InputValidation.validateNotNull(minCoords, "minCoords"); InputValidation.validateNotNull(maxCoords, "maxCoords"); - } catch (IllegalArgumentException e) { + InputValidation.validateListLength(minCoords, 2, "minCoords"); + InputValidation.validateListLength(maxCoords, 2, "maxCoords"); + } catch (IllegalArgumentException | WrongLengthException e) { throw new WrongFileFormatException("The file should have two min/max coordinates each", e); } - if (minCoords.size() != 2 || maxCoords.size() != 2) { - throw new WrongFileFormatException("The file should have two min/max coordinates each"); - } double minX; double minY; @@ -79,10 +89,7 @@ public class ChaosGameFileHandler { maxY = Double.parseDouble(maxCoords.get(1)); } catch (NumberFormatException e) { throw new WrongFileFormatException("The min/max coordinates in the file are not numbers", e); - } catch (IndexOutOfBoundsException e) { - throw new WrongFileFormatException("The file is missing min/max coordinates", e); } - if (minX >= maxX || minY >= maxY) { throw new WrongFileFormatException( "The min coordinates should be less than the max coordinates"); @@ -91,12 +98,9 @@ public class ChaosGameFileHandler { List<Transform2D> transforms = (type.getFirst().equals("Affine2D")) ? packageToAffineList(lines) : packageToJuliaList(lines); - try { - return new ChaosGameDescription(transforms, new Vector2D(minX, minY), - new Vector2D(maxX, maxY)); - } catch (ChaosGameDescriptionException e) { - throw new ChaosGameFileHandlerException("Could not create ChaosGameDescription", e); - } + + return new ChaosGameDescription(transforms, new Vector2D(minX, minY), + new Vector2D(maxX, maxY)); } /** @@ -104,10 +108,10 @@ public class ChaosGameFileHandler { * * @param file the file to divide. * @return a list of lines in the file. - * @throws ChaosGameFileHandlerException if the file is not found. + * @throws FileNotFoundException if the file is not found. */ private List<List<String>> divideFileToLines(File file) - throws ChaosGameFileHandlerException { + throws FileNotFoundException { List<List<String>> lines = new ArrayList<>(); try (Scanner scanner = new Scanner(file)) { scanner.useDelimiter("#.*|\n"); @@ -126,7 +130,7 @@ public class ChaosGameFileHandler { i++; } } catch (FileNotFoundException e) { - throw new ChaosGameFileHandlerException("File not found", e); + throw new FileNotFoundException("File not found"); } return lines; } @@ -141,9 +145,11 @@ public class ChaosGameFileHandler { private List<Transform2D> packageToAffineList(List<List<String>> lines) throws WrongFileFormatException { for (int i = 3; i < lines.size(); i++) { - if (lines.get(i).size() != 6) { + try { + InputValidation.validateListLength(lines.get(i), 6, "transformation"); + } catch (WrongLengthException e) { throw new WrongFileFormatException( - "The file should have six values for each transformation"); + "The file should have six values for each transformation", e); } for (String value : lines.get(i)) { try { @@ -178,22 +184,28 @@ public class ChaosGameFileHandler { * @param lines the lines of the file. * @return a list of JuliaTransform. * @throws WrongFileFormatException if the file is not formatted correctly. + * @throws InvalidSignException if the sign is invalid. */ private List<Transform2D> packageToJuliaList(List<List<String>> lines) - throws WrongFileFormatException { + throws WrongFileFormatException, InvalidSignException { - if (lines.size() != 4) { - throw new WrongFileFormatException("The file should have one Julia transformation"); + try { + InputValidation.validateListLength(lines, 4, "Julia transformation"); + } catch (WrongLengthException e) { + throw new WrongFileFormatException("The file should have one Julia transformation", e); } + List<String> julia = lines.get(3); try { InputValidation.validateNotNull(julia, "Julia transformation"); - } catch (IllegalArgumentException e) { + } catch (IsNullException e) { throw new WrongFileFormatException("The file should have one Julia transformation", e); } - if (julia.size() != 2) { - throw new WrongFileFormatException("The Julia transformation should have two values"); + try { + InputValidation.validateListLength(julia, 2, "Julia transformation"); + } catch (WrongLengthException e) { + throw new WrongFileFormatException("The Julia transformation should have two values", e); } double real; @@ -219,10 +231,10 @@ public class ChaosGameFileHandler { * * @param chaosGameDescription the ChaosGameDescription to write. * @param path the path to the file. - * @throws ChaosGameFileHandlerException if the file could not be written to. + * @throws CouldNotWriteException if the file could not be written to. */ public void writeToFile(ChaosGameDescription chaosGameDescription, File path) - throws ChaosGameFileHandlerException { + throws CouldNotWriteException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(path))) { String type = chaosGameDescription.getTransforms().getFirst() instanceof AffineTransform2D ? "Affine2D" : "Julia"; @@ -246,7 +258,7 @@ public class ChaosGameFileHandler { writeJuliaToFile(writer, juliaTransform); } } catch (IOException e) { - throw new ChaosGameFileHandlerException("Could not write to file", e); + throw new CouldNotWriteException("Could not write to file", e); } } @@ -255,10 +267,10 @@ public class ChaosGameFileHandler { * * @param writer the writer to write to. * @param affineTransform the AffineTransform2D to write. - * @throws IOException if the AffineTransform2D could not be written to the file. + * @throws CouldNotWriteException if the AffineTransform2D could not be written to the file. */ private void writeAffineToFile(BufferedWriter writer, AffineTransform2D affineTransform) - throws IOException { + throws CouldNotWriteException { Matrix2x2 matrix = affineTransform.getMatrix(); double a00 = matrix.getA00(); double a01 = matrix.getA01(); @@ -269,7 +281,11 @@ public class ChaosGameFileHandler { double x0 = vector.getX0(); double x1 = vector.getX1(); - writer.write(a00 + ", " + a01 + ", " + a10 + ", " + a11 + ", " + x0 + ", " + x1 + "\n"); + try { + writer.write(a00 + ", " + a01 + ", " + a10 + ", " + a11 + ", " + x0 + ", " + x1 + "\n"); + } catch (IOException e) { + throw new CouldNotWriteException("Could not write to file", e); + } } /** @@ -277,24 +293,28 @@ public class ChaosGameFileHandler { * * @param writer the writer to write to. * @param juliaTransform the JuliaTransform to write. - * @throws IOException if the JuliaTransform could not be written to the file. + * @throws CouldNotWriteException if the JuliaTransform could not be written to the file. */ private void writeJuliaToFile(BufferedWriter writer, JuliaTransform juliaTransform) - throws IOException { + throws CouldNotWriteException { Complex complex = juliaTransform.getPoint(); double real = complex.getX0(); double imaginary = complex.getX1(); + try { writer.write(real + ", " + imaginary + "\n"); + } catch (IOException e) { + throw new CouldNotWriteException("Could not write to file", e); + } } /** * Lists all files in the resources directory. * * @return a list of all files in the resources directory. - * @throws ChaosGameFileHandlerException if the files could not be listed. + * @throws IOException if the files could not be listed. */ - public List<String> listFiles() throws ChaosGameFileHandlerException { + public List<String> listFiles() throws IOException { List<String> fileList = new ArrayList<>(); try { Path resourceDirectory = Paths.get("src/main/resources"); @@ -304,7 +324,7 @@ public class ChaosGameFileHandler { .forEach(path -> fileList.add(path.toString())); } } catch (IOException e) { - throw new ChaosGameFileHandlerException("Could not list files", e); + throw new IOException("Could not list files"); } return fileList; } diff --git a/src/main/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransform.java b/src/main/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransform.java index 4f29c6cdb1c3b700cd7d16dde3f035a539e582f4..529de0f1bf4fdef0455f6cb07559088ad3c3eb5a 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransform.java +++ b/src/main/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransform.java @@ -1,5 +1,6 @@ package edu.ntnu.idatt2003.model.math.transformation; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; import edu.ntnu.idatt2003.model.math.mathModel.Complex; import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; @@ -17,12 +18,12 @@ public class JuliaTransform implements Transform2D { * @param point the point to transform around. * @param sign the sign of the transformation. * - * @throws IllegalArgumentException if sign is not 1 or -1. + * @throws InvalidSignException if sign is not 1 or -1. */ - public JuliaTransform(Complex point, int sign) { + public JuliaTransform(Complex point, int sign) throws InvalidSignException { this.point = point; if (sign != 1 && sign != -1) { - throw new IllegalArgumentException("Sign must be 1 or -1"); + throw new InvalidSignException("Sign must be 1 or -1"); } this.sign = sign; } diff --git a/src/main/java/edu/ntnu/idatt2003/util/InputValidation.java b/src/main/java/edu/ntnu/idatt2003/util/InputValidation.java index 05052448e0db313eb1d450b96b7b247be137480c..433b20e02f5f41be056865f4d9efe158f81030ca 100644 --- a/src/main/java/edu/ntnu/idatt2003/util/InputValidation.java +++ b/src/main/java/edu/ntnu/idatt2003/util/InputValidation.java @@ -1,5 +1,11 @@ package edu.ntnu.idatt2003.util; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; +import edu.ntnu.idatt2003.exceptions.WrongLengthException; +import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; import java.util.List; /** @@ -13,12 +19,12 @@ public class InputValidation { * * @param object to be validated * @param parameterName the name of the object - * @throws IllegalArgumentException if the object is null + * @throws IsNullException if the object is null */ public static void validateNotNull(Object object, String parameterName) - throws IllegalArgumentException { + throws IsNullException { if (object == null) { - throw new IllegalArgumentException("Object: " + parameterName + " cannot be null"); + throw new IsNullException("Object: " + parameterName + " cannot be null"); } } @@ -27,12 +33,12 @@ public class InputValidation { * * @param number to be validated * @param parameterName the name of the int - * @throws IllegalArgumentException if the int is not positive + * @throws InvalidPositiveIntException if the int is not positive */ public static void validatePositiveInt(int number, String parameterName) - throws IllegalArgumentException { + throws InvalidPositiveIntException { if (number <= 0) { - throw new IllegalArgumentException("Number: " + parameterName + " must be positive"); + throw new InvalidPositiveIntException("Number: " + parameterName + " must be positive"); } } @@ -41,12 +47,59 @@ public class InputValidation { * * @param list to be validated * @param parameterName the name of the list - * @throws IllegalArgumentException if the list is empty + * @throws EmptyListException if the list is empty */ public static <T> void validateListNotEmpty(List<T> list, String parameterName) - throws IllegalArgumentException { + throws EmptyListException { if (list.isEmpty()) { - throw new IllegalArgumentException("List: " + parameterName + " must not be empty"); + throw new EmptyListException("List: " + parameterName + " must not be empty"); + } + } + + /** + * Validates that a list is less or equal to a given size. + * + * @param list to be validated + * @param size the maximum size of the list + * @param parameterName the name of the list + * @throws WrongLengthException if the list is bigger than the given size + */ + public static void validateListLessOrEqualThan(List<?> list, int size, String parameterName) + throws WrongLengthException { + if (list.size() <= size) { + throw new WrongLengthException("List: " + parameterName + + " must have at least " + size + " elements"); + } + } + + /** + * Validates that a list is exactly a given size. + * + * @param list to be validated + * @param size the size of the list + * @param parameterName the name of the list + * @throws WrongLengthException if the list is not the given size + */ + public static void validateListLength(List<?> list, int size, String parameterName) + throws WrongLengthException { + if (list.size() != size) { + throw new WrongLengthException("List: " + parameterName + + " must have exactly " + size + " elements"); + } + } + + /** + * Validates that the minimum coordinates are less than the maximum coordinates. + * + * @param minCoords the minimum coordinates + * @param maxCoords the maximum coordinates + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the + * maximum coordinates + */ + public static void validateVectorRange(Vector2D minCoords, Vector2D maxCoords) + throws InvalidVectorRangeException { + if (minCoords.getX0() >= maxCoords.getX0() || minCoords.getX1() >= maxCoords.getX1()) { + throw new InvalidVectorRangeException("Minimum coordinates must be less than maximum coordinates"); } } } diff --git a/src/main/java/edu/ntnu/idatt2003/view/CommandLineInterface.java b/src/main/java/edu/ntnu/idatt2003/view/CommandLineInterface.java index c0fb3fae9ec0348a6f2e58ad72b0c662e2a8dd19..3289642528553ab4a4d41eebbd97ea4bda683190 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/CommandLineInterface.java +++ b/src/main/java/edu/ntnu/idatt2003/view/CommandLineInterface.java @@ -1,14 +1,19 @@ package edu.ntnu.idatt2003.view; -import edu.ntnu.idatt2003.exceptions.ChaosCanvasException; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException; -import edu.ntnu.idatt2003.exceptions.ChaosGameException; -import edu.ntnu.idatt2003.exceptions.ChaosGameFileHandlerException; +import edu.ntnu.idatt2003.exceptions.CouldNotWriteException; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import edu.ntnu.idatt2003.exceptions.WrongFileFormatException; import edu.ntnu.idatt2003.model.game.ChaosGame; import edu.ntnu.idatt2003.model.game.ChaosGameDescription; import edu.ntnu.idatt2003.model.io.ChaosGameFileHandler; import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.List; import java.util.Scanner; /** @@ -31,11 +36,8 @@ public class CommandLineInterface { /** * Starts the command line interface. - * - * @throws ChaosGameFileHandlerException if an error occurs while reading or writing to a file. - * @throws ChaosGameException if an error occurs while running the chaos game. */ - public void start() throws ChaosGameFileHandlerException, ChaosGameException { + public void start() { boolean exit = false; while (!exit) { System.out.println("Welcome to the Chaos Game!"); @@ -59,14 +61,18 @@ public class CommandLineInterface { /** * Chooses a file to construct a ChaosGameDescription from. - * - * @throws ChaosGameFileHandlerException if an error occurs while getting the list of files - * or reading from a file. */ - private void chooseFile() throws ChaosGameFileHandlerException { + private void chooseFile() { System.out.println("Choose a file:"); int i = 1; - for (String path : chaosGameFileHandler.listFiles()) { + List<String> files; + try { + files = chaosGameFileHandler.listFiles(); + } catch (IOException e) { + System.out.println("An error occurred. Please try again."); + return; + } + for (String path : files) { String name = path.replace("src/main/resources/", "").replace(".txt", ""); System.out.println(i + ". " + name); i++; @@ -74,7 +80,7 @@ public class CommandLineInterface { int choice = scanner.nextInt(); scanner.nextLine(); boolean found = false; - for (String path : chaosGameFileHandler.listFiles()) { + for (String path : files) { choice--; if (choice == 0) { found = true; @@ -84,8 +90,11 @@ public class CommandLineInterface { System.out.println("File read successfully!"); } catch (WrongFileFormatException e) { System.out.println("Wrong file format. Please try again."); - } catch (ChaosGameFileHandlerException e) { + } catch (FileNotFoundException e) { System.out.println("File not found. Please try again."); + } catch (IsNullException | EmptyListException + | InvalidVectorRangeException | InvalidSignException e) { + System.out.println("An error occurred. Please try again."); } break; } @@ -109,21 +118,30 @@ public class CommandLineInterface { File file = new File(path); chaosGameFileHandler.writeToFile(description, file); System.out.println("File written successfully!"); - } catch (ChaosGameFileHandlerException e) { + } catch (CouldNotWriteException e) { System.out.println("An error occurred. Please try again."); } } /** * Runs the chaos game and prints the result. - * - * @throws ChaosGameException if an error occurs while running the chaos game. */ - private void runChaosGame() throws ChaosGameException { - ChaosGame chaosGame = new ChaosGame(description, width, height); + private void runChaosGame() { + ChaosGame chaosGame; + try { + chaosGame = new ChaosGame(description, width, height); + } catch (IsNullException | InvalidPositiveIntException | InvalidVectorRangeException e) { + System.out.println("An error occurred. Please try again."); + return; + } System.out.println("Choose number of steps:"); int steps = scanner.nextInt(); - chaosGame.runSteps(steps); + try { + chaosGame.runSteps(steps); + } catch (InvalidPositiveIntException e) { + System.out.println("Steps must be a positive number."); + return; + } StringBuilder sb = new StringBuilder(); for (int i = 0; i < height; i++) { diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/TopBar.java b/src/main/java/edu/ntnu/idatt2003/view/components/TopBar.java index 333f738283b97c85f49948cc6dbda8873f6ded88..db93e1276c18d5d745969af78427f9f36dde7537 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/TopBar.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/TopBar.java @@ -1,12 +1,10 @@ package edu.ntnu.idatt2003.view.components; import edu.ntnu.idatt2003.controller.ChaosGameController; -import java.io.File; - import edu.ntnu.idatt2003.view.components.Input.InputBar; import edu.ntnu.idatt2003.view.components.buttons.PrimaryButton; import edu.ntnu.idatt2003.view.components.buttons.SecondaryButton; -import edu.ntnu.idatt2003.view.components.popups.EditPopup; +import java.io.File; import javafx.geometry.Pos; import javafx.scene.control.Button; import javafx.scene.control.TextField; @@ -22,7 +20,6 @@ import javafx.stage.Window; public class TopBar extends StackPane { private final ChaosGameController controller; private int iterations; - private EditPopup editPopup; private Window ownerWindow; /** @@ -46,19 +43,13 @@ public class TopBar extends StackPane { Button juliaButton = new SecondaryButton("Julia Set"); - juliaButton.setOnAction(e -> { - this.controller.resetChaosGameWithDescription("Julia Set"); - }); + juliaButton.setOnAction(e -> this.controller.resetChaosGameWithDescription("Julia Set")); Button sierpinskiButton = new SecondaryButton("Sierpinski"); - sierpinskiButton.setOnAction(e -> { - this.controller.resetChaosGameWithDescription("Sierpinski"); - }); + sierpinskiButton.setOnAction(e -> this.controller.resetChaosGameWithDescription("Sierpinski")); Button barnsleyButton = new SecondaryButton("Barnsley"); - barnsleyButton.setOnAction(e -> { - this.controller.resetChaosGameWithDescription("Barnsley"); - }); + barnsleyButton.setOnAction(e -> this.controller.resetChaosGameWithDescription("Barnsley")); Button readFileButton = new SecondaryButton("Read File"); readFileButton.setOnAction(e -> { @@ -72,7 +63,8 @@ public class TopBar extends StackPane { Button writeFileButton = new PrimaryButton("Write File"); writeFileButton.setOnAction(e -> { FileChooser fileChooser = new FileChooser(); - FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("TXT files (*.txt)", "*.txt"); + FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter( + "TXT files (*.txt)", "*.txt"); fileChooser.getExtensionFilters().add(extFilter); File file = fileChooser.showSaveDialog(ownerWindow); if (file != null) { @@ -81,9 +73,7 @@ public class TopBar extends StackPane { }); Button editButton = new PrimaryButton("Edit"); - editButton.setOnAction(e -> { - this.controller.getPopupHandler().showEditPopup(); - }); + editButton.setOnAction(e -> this.controller.getPopupHandler().showEditPopup()); TextField iterationsField = new InputBar(); iterationsField.setPromptText("Iterations"); @@ -95,6 +85,7 @@ public class TopBar extends StackPane { try { iterations = Integer.parseInt(iterationsField.getText()); } catch (NumberFormatException ex) { + controller.logWarning(ex); this.controller.getPopupHandler().showErrorPopup("Iterations must be a number"); return; } @@ -106,7 +97,8 @@ public class TopBar extends StackPane { HBox rightButtonBox = new HBox(); leftButtonBox.getChildren().addAll(writeFileButton, editButton); - middleButtonBox.getChildren().addAll(juliaButton, sierpinskiButton, barnsleyButton, readFileButton); + middleButtonBox.getChildren().addAll( + juliaButton, sierpinskiButton, barnsleyButton, readFileButton); rightButtonBox.getChildren().addAll(iterationsField, runButton); leftButtonBox.setSpacing(8); diff --git a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosCanvasTest.java b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosCanvasTest.java index a38ec509df32894a1c8c6274c6dab3701bf7b384..e6ab5eb1bc11766f67808e9148528336c8208033 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosCanvasTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosCanvasTest.java @@ -2,7 +2,9 @@ package edu.ntnu.idatt2003.model.game; import static org.junit.jupiter.api.Assertions.*; -import edu.ntnu.idatt2003.exceptions.ChaosCanvasException; +import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -20,7 +22,8 @@ class ChaosCanvasTest { ChaosCanvas canvas; @BeforeEach - public void setUp() throws ChaosCanvasException { + public void setUp() throws InvalidPositiveIntException, IsNullException, + InvalidVectorRangeException { canvas = new ChaosCanvas(100, 100, new Vector2D(0, 0), new Vector2D(200, 200)); } @@ -102,14 +105,18 @@ class ChaosCanvasTest { public class PositiveTestsForEquals { @Test @DisplayName("Equals returns true when two canvases are equal") - void equalsReturnsTrueWhenTwoCanvasesAreEqual() throws ChaosCanvasException { + void equalsReturnsTrueWhenTwoCanvasesAreEqual() + throws InvalidPositiveIntException, IsNullException, + InvalidVectorRangeException { ChaosCanvas canvas2 = new ChaosCanvas(100, 100, new Vector2D(0, 0), new Vector2D(200, 200)); assertEquals(canvas, canvas2); } @Test @DisplayName("Equals returns false when two canvases are not equal") - void equalsReturnsFalseWhenTwoCanvasesAreNotEqual() throws ChaosCanvasException { + void equalsReturnsFalseWhenTwoCanvasesAreNotEqual() + throws InvalidPositiveIntException, IsNullException, + InvalidVectorRangeException { ChaosCanvas canvas2 = new ChaosCanvas(120, 120, new Vector2D(1, 1), new Vector2D(100, 100)); assertNotEquals(canvas, canvas2); } @@ -134,10 +141,12 @@ class ChaosCanvasTest { @Test @DisplayName("Negative tests for setMinMaxCoords") - public void setMinMaxCoordsThrowsExceptionOnNull() throws ChaosCanvasException { + public void setMinMaxCoordsThrowsExceptionOnNull() + throws InvalidPositiveIntException, IsNullException, + InvalidVectorRangeException { ChaosCanvas canvas = new ChaosCanvas(100, 100, new Vector2D(0, 0), new Vector2D(200, 200)); - assertThrows(ChaosCanvasException.class, () -> canvas.setMinMaxCoords(null, new Vector2D(200, 200))); - assertThrows(ChaosCanvasException.class, () -> canvas.setMinMaxCoords(new Vector2D(0, 0), null)); + assertThrows(IsNullException.class, () -> canvas.setMinMaxCoords(null, new Vector2D(200, 200))); + assertThrows(IsNullException.class, () -> canvas.setMinMaxCoords(new Vector2D(0, 0), null)); } @Nested @@ -147,13 +156,13 @@ class ChaosCanvasTest { @Test @DisplayName("Constructor throws exception on negative width") public void constructorThrowsExceptionOnNegativeWidth() { - assertThrows(ChaosCanvasException.class, () -> new ChaosCanvas(-100, 100, new Vector2D(0, 0), new Vector2D(200, 200))); + assertThrows(InvalidPositiveIntException.class, () -> new ChaosCanvas(-100, 100, new Vector2D(0, 0), new Vector2D(200, 200))); } @Test @DisplayName("Constructor throws exception on negative height") public void constructorThrowsExceptionOnNegativeHeight() { - assertThrows(ChaosCanvasException.class, () -> new ChaosCanvas(100, -100, new Vector2D(0, 0), new Vector2D(200, 200))); + assertThrows(InvalidPositiveIntException.class, () -> new ChaosCanvas(100, -100, new Vector2D(0, 0), new Vector2D(200, 200))); } } } diff --git a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactoryTest.java b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactoryTest.java index cfb14bcb4cb5b4babd3d33f2d6b96bb30630bde3..281b3f58b556bf00176ebdd01127b44782cb4324 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactoryTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactoryTest.java @@ -2,7 +2,11 @@ package edu.ntnu.idatt2003.model.game; import static org.junit.jupiter.api.Assertions.*; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionFactoryException; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; +import edu.ntnu.idatt2003.exceptions.InvalidTypeException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -18,7 +22,8 @@ class ChaosGameDescriptionFactoryTest { @Test @DisplayName("get Sierpinski returns a ChaosGameDescription object") public void getSierpinskiReturnsCorrectDescription() - throws ChaosGameDescriptionFactoryException { + throws InvalidSignException, IsNullException, + EmptyListException, InvalidVectorRangeException, InvalidTypeException { ChaosGameDescription chaosGameDescription = ChaosGameDescriptionFactory.get("Sierpinski"); assertNotNull(chaosGameDescription); } @@ -26,7 +31,8 @@ class ChaosGameDescriptionFactoryTest { @Test @DisplayName("get Barnsley returns a ChaosGameDescription object") public void getBarnsleyReturnsCorrectDescription() - throws ChaosGameDescriptionFactoryException { + throws InvalidSignException, IsNullException, + EmptyListException, InvalidVectorRangeException, InvalidTypeException { ChaosGameDescription chaosGameDescription = ChaosGameDescriptionFactory.get("Barnsley"); assertNotNull(chaosGameDescription); } @@ -34,7 +40,8 @@ class ChaosGameDescriptionFactoryTest { @Test @DisplayName("get Julia Set returns a ChaosGameDescription object") public void getJuliaSetReturnsCorrectDescription() - throws ChaosGameDescriptionFactoryException { + throws InvalidSignException, IsNullException, + EmptyListException, InvalidVectorRangeException, InvalidTypeException { ChaosGameDescription chaosGameDescription = ChaosGameDescriptionFactory.get("Julia Set"); assertNotNull(chaosGameDescription); } @@ -44,9 +51,9 @@ class ChaosGameDescriptionFactoryTest { @DisplayName("Negative tests") class MethodsThrowsException { @Test - @DisplayName("get with invalid type throws ChaosGameDescriptionFactoryException") + @DisplayName("get with invalid type throws InvalidTypeException") public void getWithInvalidTypeThrowsException() { - assertThrows(ChaosGameDescriptionFactoryException.class, () -> ChaosGameDescriptionFactory.get("Invalid")); + assertThrows(InvalidTypeException.class, () -> ChaosGameDescriptionFactory.get("Invalid")); } } } \ No newline at end of file diff --git a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionTest.java b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionTest.java index 55f57828d7ec32f5f638dd84cbc0cf113301d500..1ead946b30ba21adec0a3243d3132e3728818a54 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionTest.java @@ -1,6 +1,9 @@ package edu.ntnu.idatt2003.model.game; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import edu.ntnu.idatt2003.model.math.mathModel.Complex; import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; import edu.ntnu.idatt2003.model.math.transformation.JuliaTransform; @@ -26,7 +29,8 @@ class ChaosGameDescriptionTest { Vector2D maxCoords; @BeforeEach - public void setUp() throws ChaosGameDescriptionException { + public void setUp() throws InvalidSignException, IsNullException, EmptyListException, + InvalidVectorRangeException { transforms = List.of( new JuliaTransform(new Complex(-0.74543, 0.11301), 1), new JuliaTransform(new Complex(-0.74543, 0.11301), -1) @@ -59,14 +63,18 @@ class ChaosGameDescriptionTest { public class PositiveTestsForEquals { @Test @DisplayName("Equals returns true when two descriptions are equal") - void equalsReturnsTrueWhenTwoDescriptionsAreEqual() throws ChaosGameDescriptionException { + void equalsReturnsTrueWhenTwoDescriptionsAreEqual() + throws IsNullException, EmptyListException, + InvalidVectorRangeException { ChaosGameDescription description2 = new ChaosGameDescription(transforms, minCoords, maxCoords); assertEquals(description, description2); } @Test @DisplayName("Equals returns false when two descriptions are not equal") - void equalsReturnsFalseWhenTwoDescriptionsAreNotEqual() throws ChaosGameDescriptionException { + void equalsReturnsFalseWhenTwoDescriptionsAreNotEqual() + throws InvalidSignException, IsNullException, EmptyListException, + InvalidVectorRangeException { List<Transform2D> transforms2 = List.of( new JuliaTransform(new Complex(-0.7, 0.301), 1), new JuliaTransform(new Complex(-0.7, 0.301), -1) @@ -95,37 +103,37 @@ class ChaosGameDescriptionTest { @DisplayName("Negative tests") class MethodsThrowsExceptions { @Test - @DisplayName("Test constructor throws ChaosGameDescriptionException if transforms is null") + @DisplayName("Test constructor throws IsNullException if transforms is null") public void testConstructorTransformsIsNull() { - assertThrows(ChaosGameDescriptionException.class, () -> new ChaosGameDescription( + assertThrows(IsNullException.class, () -> new ChaosGameDescription( null, new Vector2D(0, 0), new Vector2D(1, 1))); } @Test - @DisplayName("Test constructor throws ChaosGameDescriptionException if transforms is empty") + @DisplayName("Test constructor throws EmptyListException if transforms is empty") public void testConstructorTransformsIsEmpty() { - assertThrows(ChaosGameDescriptionException.class, () -> new ChaosGameDescription( + assertThrows(EmptyListException.class, () -> new ChaosGameDescription( List.of(), new Vector2D(0, 0), new Vector2D(1, 1))); } @Test - @DisplayName("Test constructor throws ChaosGameDescriptionException if minCoords is null") + @DisplayName("Test constructor throws IsNullException if minCoords is null") public void testConstructorIfMinCoordsIsNull() { - assertThrows(ChaosGameDescriptionException.class, () -> new ChaosGameDescription( + assertThrows(IsNullException.class, () -> new ChaosGameDescription( List.of(new JuliaTransform(new Complex(0, 0), 1)), null, new Vector2D(1, 1))); } @Test - @DisplayName("Test constructor throws ChaosGameDescriptionException if maxCoords is null") + @DisplayName("Test constructor throws IsNullException if maxCoords is null") public void testConstructorMaxCoordsIsNull() { - assertThrows(ChaosGameDescriptionException.class, () -> new ChaosGameDescription( + assertThrows(IsNullException.class, () -> new ChaosGameDescription( List.of(new JuliaTransform(new Complex(0, 0), 1)), new Vector2D(0, 0), null)); } @Test - @DisplayName("Test constructor throws ChaosGameDescriptionException if minCoords is greater than maxCoords") + @DisplayName("Test constructor throws InvalidVectorRangeException if minCoords is greater than maxCoords") public void testConstructorMinCoordsIsGreaterThanMaxCoords() { - assertThrows(ChaosGameDescriptionException.class, () -> new ChaosGameDescription( + assertThrows(InvalidVectorRangeException.class, () -> new ChaosGameDescription( List.of(new JuliaTransform(new Complex(0, 0), 1)), new Vector2D(1, 1), new Vector2D(0, 0))); } } diff --git a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameTest.java b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameTest.java index c82810b3ac429696badd412b7efdc7e5b4f6850f..b802ef1db01376ca29290c4bd7900b88c1418ab9 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameTest.java @@ -2,13 +2,12 @@ package edu.ntnu.idatt2003.model.game; import static org.junit.jupiter.api.Assertions.*; -import edu.ntnu.idatt2003.exceptions.ChaosCanvasException; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionFactoryException; -import edu.ntnu.idatt2003.exceptions.ChaosGameException; -import edu.ntnu.idatt2003.model.math.transformation.AffineTransform2D; -import edu.ntnu.idatt2003.model.math.transformation.Transform2D; -import java.util.List; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; +import edu.ntnu.idatt2003.exceptions.InvalidTypeException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -26,8 +25,9 @@ class ChaosGameTest { @Test @DisplayName("Constructor creates a ChaosGame object") void constructorDoesNotThrowExceptionOnValidParameters() - throws ChaosGameDescriptionFactoryException, ChaosGameDescriptionException, - ChaosGameException, ChaosCanvasException { + throws InvalidSignException, IsNullException, + EmptyListException, InvalidVectorRangeException, InvalidTypeException, + InvalidPositiveIntException { ChaosGameDescription description = ChaosGameDescriptionFactory.get("Sierpinski"); ChaosGame chaosGame = new ChaosGame(description, 100, 100); assertNotNull(chaosGame); @@ -39,8 +39,9 @@ class ChaosGameTest { ChaosGame chaosGame; @BeforeEach - void setUp() throws ChaosGameDescriptionFactoryException, ChaosGameDescriptionException, - ChaosGameException, ChaosCanvasException { + void setUp() throws InvalidSignException, IsNullException, + EmptyListException, InvalidVectorRangeException, InvalidTypeException, + InvalidPositiveIntException { ChaosGameDescription description = ChaosGameDescriptionFactory.get("Sierpinski"); chaosGame = new ChaosGame(description, 100, 100); } @@ -54,7 +55,8 @@ class ChaosGameTest { @Test @DisplayName("resetGameWithNewDescription does not throw exception on valid parameters") void resetGameWithNewDescriptionDoesNotThrowException() - throws ChaosGameDescriptionFactoryException { + throws InvalidSignException, IsNullException, + EmptyListException, InvalidVectorRangeException, InvalidTypeException { ChaosGameDescription description = ChaosGameDescriptionFactory.get("Julia Set"); assertDoesNotThrow(() -> chaosGame.resetGameWithDescription(description)); } @@ -72,28 +74,30 @@ class ChaosGameTest { class MethodsThrowsExceptionOnInvalidParameters { @Test - @DisplayName("Constructor throws ChaosGameException on null description") - void constructorThrowsChaosGameExceptionOnNullDescription() { - assertThrows(ChaosGameException.class, () -> new ChaosGame(null, 100, 100)); + @DisplayName("Constructor throws IsNullException on null description") + void constructorThrowsIsNullExceptionOnNullDescription() { + assertThrows(IsNullException.class, () -> new ChaosGame(null, 100, 100)); } @Test - @DisplayName("resetGameWithNewDescription throws ChaosGameException on null description") - void resetGameWithNewDescriptionThrowsChaosGameExceptionOnNullDescription() - throws ChaosGameDescriptionFactoryException, ChaosGameException { + @DisplayName("resetGameWithNewDescription throws IsNullException on null description") + void resetGameWithNewDescriptionThrowsIsNullExceptionOnNullDescription() + throws InvalidSignException, + IsNullException, EmptyListException, InvalidVectorRangeException, InvalidTypeException, + InvalidPositiveIntException { ChaosGameDescription description = ChaosGameDescriptionFactory.get("Sierpinski"); ChaosGame chaosGame = new ChaosGame(description, 100, 100); - assertThrows(ChaosGameException.class, () -> chaosGame.resetGameWithDescription(null)); + assertThrows(IsNullException.class, () -> chaosGame.resetGameWithDescription(null)); } @Test - @DisplayName("runSteps throws ChaosGameException on negative steps") - void runStepsThrowsChaosGameExceptionOnNegativeSteps() - throws ChaosGameDescriptionFactoryException, - ChaosGameException { + @DisplayName("runSteps throws InvalidPositiveIntException on negative steps") + void runStepsThrowsInvalidPositiveIntExceptionOnNegativeSteps() + throws InvalidSignException, IsNullException, EmptyListException, + InvalidVectorRangeException, InvalidTypeException, InvalidPositiveIntException { ChaosGameDescription description = ChaosGameDescriptionFactory.get("Sierpinski"); ChaosGame chaosGame = new ChaosGame(description, 100, 100); - assertThrows(ChaosGameException.class, () -> chaosGame.runSteps(0)); + assertThrows(InvalidPositiveIntException.class, () -> chaosGame.runSteps(0)); } } } \ No newline at end of file diff --git a/src/test/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandlerTest.java b/src/test/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandlerTest.java index 2ab3432564871a5a78001dcff9e19ca6471e7d08..a14c0838833fedbca2f52ce97babfc37a2efc006 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandlerTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandlerTest.java @@ -2,8 +2,11 @@ package edu.ntnu.idatt2003.model.io; import static org.junit.jupiter.api.Assertions.*; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException; -import edu.ntnu.idatt2003.exceptions.ChaosGameFileHandlerException; +import edu.ntnu.idatt2003.exceptions.CouldNotWriteException; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import edu.ntnu.idatt2003.exceptions.WrongFileFormatException; import edu.ntnu.idatt2003.model.game.ChaosGameDescription; import edu.ntnu.idatt2003.model.math.mathModel.Complex; @@ -12,6 +15,7 @@ import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; import edu.ntnu.idatt2003.model.math.transformation.AffineTransform2D; import edu.ntnu.idatt2003.model.math.transformation.JuliaTransform; import java.io.File; +import java.io.FileNotFoundException; import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -37,7 +41,8 @@ class ChaosGameFileHandlerTest { ChaosGameDescription affine2DPositive; @BeforeEach - void setUp() throws ChaosGameDescriptionException { + void setUp() throws IsNullException, EmptyListException, + InvalidVectorRangeException, InvalidSignException { Vector2D vector1 = new Vector2D(0, 0); Vector2D vector2 = new Vector2D(0, 1.6); Vector2D vector3 = new Vector2D(0, 1.6); @@ -63,7 +68,9 @@ class ChaosGameFileHandlerTest { @Test @DisplayName("Test if readFromFile reads affine transformations correctly") void testIfReadChaosGameFileReadsAffineTransformationsCorrectly() - throws ChaosGameFileHandlerException, ChaosGameDescriptionException { + throws InvalidSignException, + WrongFileFormatException, IsNullException, FileNotFoundException, EmptyListException, + InvalidVectorRangeException { File file = new File("src/test/resources/Affine2DReadPositive.txt"); ChaosGameDescription chaosGameDescription = chaosGameFileHandler.readFromFile(file); @@ -73,7 +80,8 @@ class ChaosGameFileHandlerTest { @Test @DisplayName("Test if readFromFile reads julia transformations correctly") void testIfReadChaosGameFileReadsJuliaTransformationsCorrectly() - throws ChaosGameFileHandlerException, ChaosGameDescriptionException { + throws InvalidSignException, WrongFileFormatException, IsNullException, + FileNotFoundException, EmptyListException, InvalidVectorRangeException { File file = new File("src/test/resources/JuliaReadPositive.txt"); ChaosGameDescription chaosGameDescription = chaosGameFileHandler.readFromFile(file); @@ -83,7 +91,8 @@ class ChaosGameFileHandlerTest { @Test @DisplayName("Test if writeToFile writes affine transformations correctly") void testIfWriteChaosGameFileWritesAffineTransformationsCorrectly() - throws ChaosGameFileHandlerException, ChaosGameDescriptionException { + throws CouldNotWriteException, InvalidSignException, WrongFileFormatException, + IsNullException, FileNotFoundException, EmptyListException, InvalidVectorRangeException { File file = new File("src/test/resources/Affine2DWritePositive.txt"); chaosGameFileHandler.writeToFile(affine2DPositive, file); ChaosGameDescription chaosGameDescription = chaosGameFileHandler.readFromFile(file); @@ -95,7 +104,8 @@ class ChaosGameFileHandlerTest { @Test @DisplayName("Test if writeToFile writes julia transformations correctly") void testIfWriteChaosGameFileWritesJuliaTransformationsCorrectly() - throws ChaosGameFileHandlerException, ChaosGameDescriptionException { + throws CouldNotWriteException, InvalidSignException, WrongFileFormatException, IsNullException, + FileNotFoundException, EmptyListException, InvalidVectorRangeException { File file = new File("src/test/resources/JuliaWritePositive.txt"); chaosGameFileHandler.writeToFile(juliaPositive, file); ChaosGameDescription chaosGameDescription = chaosGameFileHandler.readFromFile(file); diff --git a/src/test/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransformTest.java b/src/test/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransformTest.java index 9f40040436e956ad5bb792a93efc8be7daa3223e..22e6f64c773970574147009862be98c3601334c9 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransformTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransformTest.java @@ -2,6 +2,7 @@ package edu.ntnu.idatt2003.model.math.transformation; import static org.junit.jupiter.api.Assertions.*; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; import edu.ntnu.idatt2003.model.math.mathModel.Complex; import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; import org.junit.jupiter.api.DisplayName; @@ -20,7 +21,7 @@ class JuliaTransformTest { @Test @DisplayName("Transform returns correct values, test 1") - void transformReturnsCorrectValues1() { + void transformReturnsCorrectValues1() throws InvalidSignException { JuliaTransform juliaTransform = new JuliaTransform(new Complex(3, 2), 1); Vector2D vector = new Vector2D(4, 1); Vector2D vector2 = juliaTransform.transform(vector); @@ -30,7 +31,7 @@ class JuliaTransformTest { @Test @DisplayName("Transform returns correct values, test 2") - void transformReturnsCorrectValues2() { + void transformReturnsCorrectValues2() throws InvalidSignException { JuliaTransform juliaTransform = new JuliaTransform(new Complex(-2, 3), 1); Vector2D vector = new Vector2D(0, 3); Vector2D vector2 = juliaTransform.transform(vector); @@ -40,7 +41,7 @@ class JuliaTransformTest { @Test @DisplayName("Transform returns correct values, test 3") - void transformReturnsCorrectValues3() { + void transformReturnsCorrectValues3() throws InvalidSignException { JuliaTransform juliaTransform = new JuliaTransform(new Complex(4, 5), 1); Vector2D vector = new Vector2D(2, 1); Vector2D vector2 = juliaTransform.transform(vector); @@ -54,7 +55,7 @@ class JuliaTransformTest { public class PositiveTestsForEquals { @Test @DisplayName("Equals returns true when two julia are equal") - void equalsReturnsTrueWhenTwoJuliaAreEqual() { + void equalsReturnsTrueWhenTwoJuliaAreEqual() throws InvalidSignException { Complex complex = new Complex(3, 2); JuliaTransform julia1 = new JuliaTransform(complex, 1); JuliaTransform julia2 = new JuliaTransform(complex, 1); @@ -63,7 +64,7 @@ class JuliaTransformTest { @Test @DisplayName("Equals returns false when two julia are not equal") - void equalsReturnsFalseWhenTwoJuliaAreNotEqual() { + void equalsReturnsFalseWhenTwoJuliaAreNotEqual() throws InvalidSignException { Complex complex1 = new Complex(3, 2); Complex complex2 = new Complex(4, 1); JuliaTransform julia1 = new JuliaTransform(complex1, 1); @@ -73,7 +74,7 @@ class JuliaTransformTest { @Test @DisplayName("Equals returns false when comparing a vector to null") - void equalsReturnsFalseWhenComparingAVectorToNull() { + void equalsReturnsFalseWhenComparingAVectorToNull() throws InvalidSignException { Complex complex = new Complex(3, 2); JuliaTransform julia = new JuliaTransform(complex, 1); assertNotEquals(julia, null); @@ -81,7 +82,7 @@ class JuliaTransformTest { @Test @DisplayName("Equals returns false when comparing a vector to a different object") - void equalsReturnsFalseWhenComparingAVectorToADifferentObject() { + void equalsReturnsFalseWhenComparingAVectorToADifferentObject() throws InvalidSignException { Complex complex = new Complex(3, 2); JuliaTransform julia = new JuliaTransform(complex, 1); assertNotEquals(julia, new Object()); @@ -94,9 +95,9 @@ class JuliaTransformTest { public class MethodsThrowsExceptions { @Test - @DisplayName("Constructor throws IllegalArgumentException if sign is not 1 or -1") - void constructorThrowsIllegalArgumentException() { - assertThrows(IllegalArgumentException.class, () -> new JuliaTransform(new Complex(3, 2), 0)); + @DisplayName("Constructor throws InvalidSignException if sign is not 1 or -1") + void constructorThrowsInvalidSignException() { + assertThrows(InvalidSignException.class, () -> new JuliaTransform(new Complex(3, 2), 0)); } } } \ No newline at end of file