diff --git a/.idea/checkstyle-idea.xml b/.idea/checkstyle-idea.xml
index 3bab646322fd4a4653a993ecbc5d3fd14935eb71..5536a0d7400e3648af967956233c4c679e855002 100644
--- a/.idea/checkstyle-idea.xml
+++ b/.idea/checkstyle-idea.xml
@@ -2,7 +2,7 @@
 <project version="4">
   <component name="CheckStyle-IDEA" serialisationVersion="2">
     <checkstyleVersion>10.13.0</checkstyleVersion>
-    <scanScope>JavaOnly</scanScope>
+    <scanScope>JavaOnlyWithTests</scanScope>
     <option name="thirdPartyClasspath" />
     <option name="activeLocationIds" />
     <option name="locations">
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000000000000000000000000000000000000..45f76e0205cae24a7ffb39876099e3d534ab39e9
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,8 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="AutoCloseableResource" enabled="true" level="WARNING" enabled_by_default="true">
+      <option name="METHOD_MATCHER_CONFIG" value="java.util.Formatter,format,java.io.Writer,append,com.google.common.base.Preconditions,checkNotNull,org.hibernate.Session,close,java.io.PrintWriter,printf,java.io.PrintStream,printf,org.mockito.MockitoAnnotations,openMocks" />
+    </inspection_tool>
+  </profile>
+</component>
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index ba62b845c54f748f9ea0f0f7f9d34ef309002d6d..94a25f7f4cb416c083d265558da75d457237d671 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,10 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="VcsDirectoryMappings">
-<<<<<<< HEAD
     <mapping directory="$PROJECT_DIR$" vcs="Git" />
-=======
-    <mapping directory="" vcs="Git" />
->>>>>>> origin/main
   </component>
 </project>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 5425b77710f09a22f07dbeb5d1f53e768242bf55..250218dcad301f8f9f114f237cb1409fd19eb9c5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -42,7 +42,26 @@
             <artifactId>javafx-media</artifactId>
             <version>21.0.2</version>
         </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>3.12.4</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-inline</artifactId>
+            <version>3.12.4</version>
+            <scope>test</scope>
+        </dependency>
 
+        <!-- Mockito JUnit Jupiter Dependency -->
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-junit-jupiter</artifactId>
+            <version>3.11.2</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/src/main/java/org/example/chaosgame/MainApp.java b/src/main/java/org/example/chaosgame/MainApp.java
index e4c3ae764236b875119446a6909722ef9cbfd68a..631385a560d104b1cd67bf7c30d9c7b0f8bf09ac 100644
--- a/src/main/java/org/example/chaosgame/MainApp.java
+++ b/src/main/java/org/example/chaosgame/MainApp.java
@@ -24,13 +24,13 @@ public class MainApp extends Application {
     new PageController(mainPane, chaosGameController, exploreGameController);
 
     Scene scene = new Scene(mainPane, 1200, 800);
-    mainPane.prefWidthProperty().bind(scene.widthProperty());
-    mainPane.prefHeightProperty().bind(scene.heightProperty());
-    scene.getStylesheets().add(Objects.requireNonNull(
-            getClass().getResource("/global.css")).toExternalForm());
+    scene.getStylesheets().add(
+            Objects.requireNonNull(getClass()
+                    .getResource("/global.css"))
+                    .toExternalForm());
 
-    primaryStage.setMinWidth(800);
-    primaryStage.setMinHeight(600);
+    primaryStage.setMinWidth(1000);
+    primaryStage.setMinHeight(650);
 
     primaryStage.setScene(scene);
     primaryStage.setTitle("Chaos Game Canvas");
diff --git a/src/main/java/org/example/chaosgame/controller/ChaosGameController.java b/src/main/java/org/example/chaosgame/controller/ChaosGameController.java
index ead31676fc9474c2d777bf4472b85d1fd12025b3..cb8678ba34d88366259e2af8b082804b159dec34 100644
--- a/src/main/java/org/example/chaosgame/controller/ChaosGameController.java
+++ b/src/main/java/org/example/chaosgame/controller/ChaosGameController.java
@@ -17,12 +17,10 @@ import org.example.chaosgame.controller.interfaces.Observer;
 import org.example.chaosgame.controller.interfaces.Subject;
 import org.example.chaosgame.model.chaos.ChaosGame;
 import org.example.chaosgame.model.chaos.ChaosGameDescription;
-import org.example.chaosgame.model.chaos.ChaosGameDescriptionFactory;
-import org.example.chaosgame.model.chaos.ChaosGameFileHandler;
 import org.example.chaosgame.model.chaos.ChaosGameType;
 import org.example.chaosgame.model.linalg.Complex;
-import org.example.chaosgame.model.linalg.Vector2D;
 import org.example.chaosgame.model.linalg.Matrix2x2;
+import org.example.chaosgame.model.linalg.Vector2D;
 import org.example.chaosgame.model.transformations.AffineTransform2D;
 import org.example.chaosgame.model.transformations.JuliaTransform;
 import org.example.chaosgame.model.transformations.Transform2D;
@@ -105,26 +103,29 @@ public class ChaosGameController implements Observer, Subject, GameController {
     String input = stepsField.getText();
     try {
       int steps = Integer.parseInt(input);
-      if (steps < 1 || steps > 10000000) {
-        throw new NumberFormatException();
-      }
-      if (chaosGame.getDescription().getTransforms().getFirst() instanceof JuliaTransform && steps > 250000) {
-        AlertUtility.showErrorDialog("Invalid input", "Please enter a lower amount of steps for Julia transformations.");
-        return;
+      chaosGame.setSteps(steps);
+      if (chaosGame.getDescription().getTransforms().getFirst()
+              instanceof JuliaTransform && steps > 250000) {
+        throw new IllegalArgumentException(
+                "Please enter a lower amount of steps for Julia transformations.");
       }
       if (chaosGame.getTotalSteps() > Math.pow(10, 8)) {
-        AlertUtility.showErrorDialog("Invalid input", "The total number of steps is too high. Please reset the game.");
-        return;
+        throw new IllegalArgumentException(
+                "The total amount of steps is too high. Choose a lower amount.");
       }
-      chaosGame.setSteps(steps);
       chaosGame.addTotalSteps(steps);
       chaosGame.runSteps();
       stepsField.getStyleClass().remove("text-field-invalid");
-    } catch (NumberFormatException ex) {
+
+    } catch (NumberFormatException e) {
+      stepsField.clear();
+      stepsField.getStyleClass().add("text-field-invalid");
+      AlertUtility.showErrorDialog("Invalid input", "Please enter a valid number.");
+    } catch (IllegalArgumentException ex) {
       stepsField.clear();
       stepsField.getStyleClass().add("text-field-invalid");
       AlertUtility.showErrorDialog(
-              "Invalid input", "Please enter a number between 1 - 10 000 000.");
+              "Invalid input", ex.getMessage());
     }
   }
 
@@ -146,46 +147,22 @@ public class ChaosGameController implements Observer, Subject, GameController {
         Vector2D max = new Vector2D(Double.parseDouble(coords.get(2)),
                 Double.parseDouble(coords.get(3)));
 
-        if (validateCoordinates(min) && validateCoordinates(max)) {
-          updateChaosGame(new ChaosGameDescription(
-                  min, max,
-                  chaosGame.getDescription().getTransforms()));
-        } else {
-          AlertUtility.showErrorDialog("Invalid input",
-                  "Please enter a double between -50 and 50.");
-        }
+        updateChaosGame(new ChaosGameDescription(min, max,
+                chaosGame.getDescription().getTransforms()));
       } catch (NumberFormatException e) {
-
         AlertUtility.showErrorDialog("Invalid input",
                 "Please enter a valid number.");
       } catch (IndexOutOfBoundsException e) {
         AlertUtility.showErrorDialog("Invalid input",
                 "Please enter all coordinates.");
+      } catch (IllegalArgumentException e) {
+        AlertUtility.showErrorDialog("Invalid input",
+                e.getMessage());
       }
 
     }
   }
 
-  /**
-   * Method for validating the coordinates.
-   *
-   * @param vector Vector2D with the coordinates
-   * @return boolean True if the coordinates are valid, false otherwise
-   */
-  private boolean validateCoordinates(Vector2D vector) {
-    try {
-      System.out.println("parsing" + vector.getX() + " " + vector.getY());
-      double x = vector.getX();
-      double y = vector.getY();
-      if (x < -50 || x > 50 || y < -50 || y > 50) {
-        return false;
-      }
-    } catch (NumberFormatException e) {
-      return false;
-    }
-    return true;
-  }
-
   /**
    * Method for opening a file with a chaos game description.
    *
@@ -212,10 +189,12 @@ public class ChaosGameController implements Observer, Subject, GameController {
   }
 
   /**
-   * Method for creating a new fractal.
+   * Method for user creation of fractal.
+   * {@link org.example.chaosgame.view.components.CreateFractalDialog} returns either a
+   * {@link java.util.List}<{@link java.util.List}<{@link java.lang.String}>>
+   * or a {@link javafx.util.Pair}<{@link java.lang.String}, {@link java.lang.String}>.
    *
    * <p>Opens a dialog for the user to create a new fractal.
-   *
    */
   public void createOwnFractal() {
     CreateFractalDialog dialog = new CreateFractalDialog();
@@ -226,7 +205,7 @@ public class ChaosGameController implements Observer, Subject, GameController {
       List<Transform2D> transforms = new ArrayList<>();
       if (fractalData instanceof List) {
         List<List<String>> userInput = (List<List<String>>) fractalData;
-        for(List<String> input : userInput) {
+        for (List<String> input : userInput) {
           try {
             double a = Double.parseDouble(input.get(0));
             double b = Double.parseDouble(input.get(1));
@@ -235,8 +214,8 @@ public class ChaosGameController implements Observer, Subject, GameController {
             double x = Double.parseDouble(input.get(4));
             double y = Double.parseDouble(input.get(5));
 
-            if (a < -5 || a > 5 || b < -5 || b > 5 || c < -5 || c > 5 ||
-                    d < -5 || d > 5 || x < -5 || x > 5 || y < -5 || y > 5) {
+            if (a < -5 || a > 5 || b < -5 || b > 5 || c < -5 || c > 5
+                    || d < -5 || d > 5 || x < -5 || x > 5 || y < -5 || y > 5) {
               throw new NumberFormatException();
             } else {
               transforms.add(new AffineTransform2D(new Matrix2x2(a, b, c, d), new Vector2D(x, y)));
@@ -249,7 +228,6 @@ public class ChaosGameController implements Observer, Subject, GameController {
             AlertUtility.showErrorDialog("Invalid input", "Please enter a valid number.");
           }
         }
-//        List<Transform2D> transforms = new ArrayList<>(transformations);
       } else if (fractalData instanceof Pair) {
         Pair<String, String> userInput = (Pair<String, String>) fractalData;
         try { // Check if the input is a valid number
diff --git a/src/main/java/org/example/chaosgame/model/chaos/ChaosGameDescriptionFactory.java b/src/main/java/org/example/chaosgame/controller/ChaosGameDescriptionFactory.java
similarity index 84%
rename from src/main/java/org/example/chaosgame/model/chaos/ChaosGameDescriptionFactory.java
rename to src/main/java/org/example/chaosgame/controller/ChaosGameDescriptionFactory.java
index 166963ee5f073e835f347d780a82ba25e28c1e87..db3de3d27fb79488505c1f1d61df2ad70bffb01a 100644
--- a/src/main/java/org/example/chaosgame/model/chaos/ChaosGameDescriptionFactory.java
+++ b/src/main/java/org/example/chaosgame/controller/ChaosGameDescriptionFactory.java
@@ -1,6 +1,8 @@
-package org.example.chaosgame.model.chaos;
+package org.example.chaosgame.controller;
 
 import java.util.List;
+import org.example.chaosgame.model.chaos.ChaosGameDescription;
+import org.example.chaosgame.model.chaos.ChaosGameType;
 import org.example.chaosgame.model.linalg.Complex;
 import org.example.chaosgame.model.linalg.Matrix2x2;
 import org.example.chaosgame.model.linalg.Vector2D;
@@ -13,12 +15,16 @@ import org.example.chaosgame.model.transformations.JuliaTransform;
 public class ChaosGameDescriptionFactory {
 
   /**
-   * Returns a ChaosGameDescription object based on the description and complex number.
+   * Returns a ChaosGameDescription object based on the ChaosGameType-enum.
    *
    * @param type The description of the chaos game
    * @return A ChaosGameDescription object
+   * @throws IllegalArgumentException if the ChaosGameType is null
    */
-  public static ChaosGameDescription get(ChaosGameType type) {
+  public static ChaosGameDescription get(ChaosGameType type) throws IllegalArgumentException {
+    if (type == null) {
+      throw new IllegalArgumentException("ChaosGameType cannot be null");
+    }
     return switch (type) {
       case JULIA -> createJulia();
       case BARNSLEY -> createBarnsley();
diff --git a/src/main/java/org/example/chaosgame/model/chaos/ChaosGameFileHandler.java b/src/main/java/org/example/chaosgame/controller/ChaosGameFileHandler.java
similarity index 92%
rename from src/main/java/org/example/chaosgame/model/chaos/ChaosGameFileHandler.java
rename to src/main/java/org/example/chaosgame/controller/ChaosGameFileHandler.java
index e10510ef599e1a7042886c6188b9e242be01da8d..050be3f8ffd4d511b5a88037a999ac96028cce6c 100644
--- a/src/main/java/org/example/chaosgame/model/chaos/ChaosGameFileHandler.java
+++ b/src/main/java/org/example/chaosgame/controller/ChaosGameFileHandler.java
@@ -1,4 +1,4 @@
-package org.example.chaosgame.model.chaos;
+package org.example.chaosgame.controller;
 
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
@@ -7,6 +7,7 @@ import java.io.FileWriter;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import org.example.chaosgame.model.chaos.ChaosGameDescription;
 import org.example.chaosgame.model.linalg.Complex;
 import org.example.chaosgame.model.linalg.Matrix2x2;
 import org.example.chaosgame.model.linalg.Vector2D;
@@ -42,8 +43,6 @@ public class ChaosGameFileHandler {
     Vector2D maxCoords;
     try (BufferedReader reader = new BufferedReader(new FileReader(path))) {
       String typeOfTransformation = skipComments(reader.readLine());
-      System.out.println("Parsing type of transformation: " + typeOfTransformation);
-
       minCoords = parseVector(reader.readLine().trim());
       maxCoords = parseVector(reader.readLine().trim());
 
@@ -132,7 +131,7 @@ public class ChaosGameFileHandler {
    * @return the transformation
    * @throws IllegalArgumentException if the type of transformation is unknown
    */
-  private Transform2D selectTransformation(String typeOfTransformation, String line)
+  public Transform2D selectTransformation(String typeOfTransformation, String line)
           throws IllegalArgumentException {
     return switch (typeOfTransformation) {
       case "Affine2D" -> parseAffine(line);
@@ -148,7 +147,7 @@ public class ChaosGameFileHandler {
    * @param line a line of text
    * @return the first part of the line
    */
-  private String skipComments(String line) {
+  public String skipComments(String line) {
     String[] parts = line.split("#");
     return parts[0].trim();
   }
@@ -159,9 +158,8 @@ public class ChaosGameFileHandler {
    * @param line a line of text
    * @return the vector
    */
-  private Vector2D parseVector(String line) {
+  public Vector2D parseVector(String line) {
     String numbers = skipComments(line);
-    System.out.println("Parsing vector: " + numbers);
     String[] vectorParts = numbers.split(",");
     double x = Double.parseDouble(vectorParts[0].trim());
     double y = Double.parseDouble(vectorParts[1].trim());
@@ -174,9 +172,8 @@ public class ChaosGameFileHandler {
    * @param line a line of text
    * @return the transformation
    */
-  private Transform2D parseAffine(String line) {
+  public Transform2D parseAffine(String line) {
     String numbers = skipComments(line);
-    System.out.println("Parsing transform: " + numbers);
     String[] transformParts = numbers.split(",");
     double a = Double.parseDouble(transformParts[0].trim());
     double b = Double.parseDouble(transformParts[1].trim());
@@ -193,9 +190,8 @@ public class ChaosGameFileHandler {
    * @param line a line of text
    * @return the transformation
    */
-  private Transform2D parseJulia(String line) {
+  public Transform2D parseJulia(String line) {
     String numbers = skipComments(line);
-    System.out.println("Parsing transform: " + numbers);
     String[] parts = numbers.split(",");
     double r = Double.parseDouble(parts[0].trim());
     double i = Double.parseDouble(parts[1].trim());
diff --git a/src/main/java/org/example/chaosgame/controller/ExploreGameController.java b/src/main/java/org/example/chaosgame/controller/ExploreGameController.java
index 90a1ba0998309b7cc4be8abf2980f6b85b7ea080..b6ae5e8cfac2ea62c8c1e05d13df1bce44c5b727 100644
--- a/src/main/java/org/example/chaosgame/controller/ExploreGameController.java
+++ b/src/main/java/org/example/chaosgame/controller/ExploreGameController.java
@@ -40,6 +40,9 @@ public class ExploreGameController implements Observer, Subject, GameController
   private static final int WIDTH = 1200;
   private static final int HEIGHT = 800;
 
+  private Vector2D minCoords = new Vector2D(-1.6, -1);
+  private Vector2D maxCoords = new Vector2D(1.6, 1);
+
   /**
    * Constructor for ExploreGameController.
    * Initializes the ExploreGame and ExplorePage.
@@ -47,9 +50,9 @@ public class ExploreGameController implements Observer, Subject, GameController
   public ExploreGameController() {
     ExploreJulia exploreJulia = new ExploreJulia(new Complex(-0.835, 0.2321));
     this.trans = List.of(exploreJulia);
-    this.description  = new ChaosGameDescription(
-            new Vector2D(-1.6, -1),
-            new Vector2D(1.6, 1), trans);
+    this.description = new ChaosGameDescription(
+            minCoords,
+            maxCoords, trans);
     this.exploreGame = new ExploreGame(description, WIDTH, HEIGHT);
     this.chaosCanvas = exploreGame.getCanvas();
     this.pageObservers = new ArrayList<>();
@@ -101,10 +104,9 @@ public class ExploreGameController implements Observer, Subject, GameController
             canvas.getHeight() - event.getY()).subtract(dragStartTemp);
     Vector2D fractalRange = description.getMaxCoords().subtract(description.getMinCoords());
     Vector2D adjustedDragDistance = dragDistance.multiply(fractalRange)
-                    .divide(new Vector2D(canvas.getWidth(), canvas.getHeight()));
-    Vector2D newMinCoords = description.getMinCoords().subtract(adjustedDragDistance);
-    Vector2D newMaxCoords = description.getMaxCoords().subtract(adjustedDragDistance);
-    description = new ChaosGameDescription(newMinCoords, newMaxCoords, trans);
+            .divide(new Vector2D(canvas.getWidth(), canvas.getHeight()));
+    minCoords = description.getMinCoords().subtract(adjustedDragDistance);
+    maxCoords = description.getMaxCoords().subtract(adjustedDragDistance);
     updateExplorePage();
   }
 
@@ -119,12 +121,11 @@ public class ExploreGameController implements Observer, Subject, GameController
     cumulativeScaleFactor *= scaleFactor;
     Vector2D canvasCenter = chaosCanvas.transformIndicesToCoords(
             chaosCanvas.getWidth() / 2, chaosCanvas.getHeight() / 2);
-    Vector2D newMinCoords = canvasCenter.subtract(
-            canvasCenter.subtract(description.getMinCoords()).scale(scaleFactor));
-    Vector2D newMaxCoords = canvasCenter.add(
-            description.getMaxCoords().subtract(canvasCenter).scale(scaleFactor));
+    minCoords = canvasCenter.subtract(canvasCenter.subtract(
+            description.getMinCoords()).scale(scaleFactor));
+    maxCoords = canvasCenter.add(description.getMaxCoords()
+            .subtract(canvasCenter).scale(scaleFactor));
 
-    description = new ChaosGameDescription(newMinCoords, newMaxCoords, trans);
     updateExplorePage();
   }
 
@@ -166,29 +167,32 @@ public class ExploreGameController implements Observer, Subject, GameController
     canvas.setTranslateY(setTranslateY);
 
     Vector2D canvasCenter = chaosCanvas.transformIndicesToCoords((int) mouseX, (int) mouseY);
-    Vector2D newMinCoords = canvasCenter.subtract(
-            canvasCenter.subtract(description.getMinCoords()).scale(scaleFactor));
-    Vector2D newMaxCoords = canvasCenter.add(
-            description.getMaxCoords().subtract(canvasCenter).scale(scaleFactor));
-
-    description = new ChaosGameDescription(newMinCoords, newMaxCoords, trans);
+    minCoords = canvasCenter.subtract(canvasCenter.subtract(
+            description.getMinCoords()).scale(scaleFactor));
+    maxCoords = canvasCenter.add(description.getMaxCoords()
+            .subtract(canvasCenter).scale(scaleFactor));
     updateExplorePage();
   }
 
+
   private void updateExplorePage() {
-    exploreGame.removeObserver(this);
-    exploreGame = new ExploreGame(description, (int) canvas.getWidth(), (int) canvas.getHeight());
-    exploreGame.registerObserver(this);
+    this.description.setMinCoords(minCoords);
+    this.description.setMaxCoords(maxCoords);
+    this.description.setTransforms(trans);
+    this.exploreGame = new ExploreGame(
+            description, (int) canvas.getWidth(), (int) canvas.getHeight());
+    this.exploreGame.registerObserver(this);
     this.chaosCanvas = exploreGame.getCanvas();
     exploreGame.exploreFractals();
-    explorePage.updateCanvas(this.chaosCanvas);
+    explorePage.updateCanvas(exploreGame.getCanvas());
 
-    canvas.setTranslateX(0);
-    canvas.setTranslateY(0);
-    canvas.setScaleY(1);
-    canvas.setScaleX(1);
+    this.canvas.setTranslateX(0);
+    this.canvas.setTranslateY(0);
+    this.canvas.setScaleX(1);
+    this.canvas.setScaleY(1);
   }
 
+
   public void homeButtonClicked() {
     notifyObservers();
   }
@@ -213,11 +217,12 @@ public class ExploreGameController implements Observer, Subject, GameController
    * Resets the image to the default position and scale.
    */
   public void resetImage() {
-    Vector2D newMinCoords = new Vector2D(-1.6, -1);
-    Vector2D newMaxCoords = new Vector2D(1.6, 1);
+    minCoords = new Vector2D(-1.6, -1);
+    maxCoords = new Vector2D(1.6, 1);
     description = new ChaosGameDescription(
-            newMinCoords,
-            newMaxCoords, trans);
+            minCoords,
+            maxCoords, trans);
+
     cumulativeScaleFactor = 1;
     updateExplorePage();
   }
@@ -250,7 +255,6 @@ public class ExploreGameController implements Observer, Subject, GameController
             ? value : exploreTransform.getComplex().getY();
 
     trans = List.of(new ExploreJulia(new Complex(realPart, imaginaryPart)));
-    description.setTransforms(trans);
     updateExplorePage();
   }
 
diff --git a/src/main/java/org/example/chaosgame/model/chaos/ChaosCanvas.java b/src/main/java/org/example/chaosgame/model/chaos/ChaosCanvas.java
index 8ec988181845edd96b9cc2dd6ee804e86ed3b172..ed700b4911756bd4d62d8706bedc52679807e21e 100644
--- a/src/main/java/org/example/chaosgame/model/chaos/ChaosCanvas.java
+++ b/src/main/java/org/example/chaosgame/model/chaos/ChaosCanvas.java
@@ -13,7 +13,6 @@ import org.example.chaosgame.model.transformations.AffineTransform2D;
  * The canvas also has an Affine transformation that maps coordinates, {@link Vector2D},
  * to indices in the canvas array. This is used to map points to pixels in the canvas.
  */
-
 public class ChaosCanvas {
   private int width;
   private int height;
@@ -89,6 +88,11 @@ public class ChaosCanvas {
     this.height = height;
   }
 
+
+  public AffineTransform2D getTransformCoordsToIndices() {
+    return transformCoordsToIndices;
+  }
+
   /**
    * Calculates the Affine transformation that maps coordinates to indices in the canvas array.
    * The transformation is calculated based on the width, height, minimum and maximum coordinates.
@@ -105,6 +109,7 @@ public class ChaosCanvas {
                     ((height - 1.0) * maxCoords.getY()) / (maxCoords.getY() - minCoords.getY()),
                     ((width - 1.0) * minCoords.getX()) / (minCoords.getX() - maxCoords.getX())
             ));
+
   }
 
   /**
@@ -166,4 +171,23 @@ public class ChaosCanvas {
       }
     }
   }
+
+
+  /**
+   * Returns the pixel value at the given point.
+   * If the point is outside the canvas, the method returns 0.
+   *
+   * @param point The point to get the pixel value at
+   *
+   * @return The pixel value at the given point
+   */
+  public double getPixel(Vector2D point) {
+    Vector2D indices = transformCoordsToIndices.transform(point);
+    int x = (int) indices.getX();
+    int y = (int) indices.getY();
+    if (x >= 0 && x < height && y >= 0 && y < width) {
+      return canvas[x][y];
+    }
+    return 0.0;
+  }
 }
diff --git a/src/main/java/org/example/chaosgame/model/chaos/ChaosGame.java b/src/main/java/org/example/chaosgame/model/chaos/ChaosGame.java
index 19a06e0757301ce85f84e8d525b225eb8a04cf6a..6ee43e34f845e10696777fb0da4fe27442048edc 100644
--- a/src/main/java/org/example/chaosgame/model/chaos/ChaosGame.java
+++ b/src/main/java/org/example/chaosgame/model/chaos/ChaosGame.java
@@ -79,7 +79,19 @@ public class ChaosGame implements Subject {
     return totalSteps;
   }
 
-  public void setSteps(int steps) {
+  /**
+   * Method for setting the number of steps to run.
+   *
+   * @param steps Number of steps to run
+   * @throws IllegalArgumentException If steps is less than 0 or greater than 1000000
+   */
+  public void setSteps(int steps) throws IllegalArgumentException {
+    if (steps < 0) {
+      throw new IllegalArgumentException("Steps must be a positive number");
+    }
+    if (steps > 1000000) {
+      throw new IllegalArgumentException("Steps must be less than 1000000");
+    }
     this.steps = steps;
   }
 
@@ -91,8 +103,13 @@ public class ChaosGame implements Subject {
    * Method for setting the chaos game description.
    *
    * @param newDescription New description of the chaos game
+   * @throws IllegalArgumentException If newDescription is null
    */
-  public void setChaosGameDescription(ChaosGameDescription newDescription) {
+  public void setChaosGameDescription(ChaosGameDescription newDescription)
+          throws IllegalArgumentException {
+    if (newDescription == null) {
+      throw new IllegalArgumentException("Description cannot be null");
+    }
     this.description = newDescription;
     resetTotalSteps();
     setChaosCanvas(description.getMinCoords(), description.getMaxCoords());
@@ -112,7 +129,16 @@ public class ChaosGame implements Subject {
     this.canvas.setTransformCoordsToIndices();
   }
 
-  public void addTotalSteps(int newSteps) {
+  /**
+   * Method for adding steps to the total number of steps.
+   *
+   * @param newSteps Number of steps to add
+   * @throws IllegalArgumentException If newSteps is less than 0
+   */
+  public void addTotalSteps(int newSteps) throws IllegalArgumentException {
+    if (newSteps < 0) {
+      throw new IllegalArgumentException("Steps must be a positive number");
+    }
     this.totalSteps += newSteps;
   }
 
@@ -122,8 +148,9 @@ public class ChaosGame implements Subject {
 
 
   /**
-   * Method for running the chaos game. Randomly selects a transformation
-   * from the description and applies it to the current point.
+   * Method for running the chaos game.
+   * Selects which runSteps method to use based if it has a list of probabilities.
+   * Notifies observers after running the steps.
    */
   public void runSteps() {
     if (description.getProbabilities() != null) {
@@ -134,6 +161,10 @@ public class ChaosGame implements Subject {
     notifyObservers();
   }
 
+  /**
+   * Method for running the chaos game. Randomly selects a transformation
+   * from the description and applies it to the current point.
+   */
   private void runStepsUniform(int steps) {
     for (int i = 0; i < steps; i++) {
       int transformIndex = random.nextInt(description.getTransforms().size());
diff --git a/src/main/java/org/example/chaosgame/model/chaos/ChaosGameDescription.java b/src/main/java/org/example/chaosgame/model/chaos/ChaosGameDescription.java
index 7b92582cc4624895b789b626da1e074b04dba77b..8c7177f940833f147f256ae1eea7b859cd1983a2 100644
--- a/src/main/java/org/example/chaosgame/model/chaos/ChaosGameDescription.java
+++ b/src/main/java/org/example/chaosgame/model/chaos/ChaosGameDescription.java
@@ -1,6 +1,7 @@
 package org.example.chaosgame.model.chaos;
 
 import java.util.List;
+import java.util.Objects;
 import org.example.chaosgame.model.linalg.Vector2D;
 import org.example.chaosgame.model.transformations.Transform2D;
 
@@ -28,6 +29,8 @@ public class ChaosGameDescription {
    */
   public ChaosGameDescription(Vector2D minCoords, Vector2D maxCoords,
                               List<Transform2D> transforms) {
+    validateCoordinates(minCoords, maxCoords);
+    validateTransforms(transforms);
     this.minCoords = minCoords;
     this.maxCoords = maxCoords;
     this.transforms = transforms;
@@ -46,13 +49,55 @@ public class ChaosGameDescription {
    * @param probabilities List of probabilities for the transformations
    */
   public ChaosGameDescription(Vector2D minCoords, Vector2D maxCoords,
-                              List<Transform2D> transforms, List<Integer> probabilities) {
+                              List<Transform2D> transforms, List<Integer> probabilities)
+          throws IllegalArgumentException {
+    validateCoordinates(minCoords, maxCoords);
+    validateTransforms(transforms);
+    if (probabilities.size() != transforms.size()) {
+      throw new IllegalArgumentException("Probabilities must match the number of transformations");
+    }
     this.minCoords = minCoords;
     this.maxCoords = maxCoords;
     this.transforms = transforms;
     this.probabilities = probabilities;
   }
 
+  /**
+   * Method for validating the coordinates.
+   *
+   * @param minCoords Minimum coordinates of the game area
+   *
+   * @param maxCoords Maximum coordinates of the game area
+   */
+  private void validateCoordinates(Vector2D minCoords, Vector2D maxCoords) {
+    if (minCoords.getX() < -50 || minCoords.getY() < -50
+            || minCoords.getX() > 50 || minCoords.getY() > 50
+            || maxCoords.getX() > 50 || maxCoords.getY() > 50
+            || maxCoords.getX() < -50 || maxCoords.getY() < -50) {
+      throw new IllegalArgumentException("Coordinates must be between -50 and 50");
+    } else if (minCoords.getX() > maxCoords.getX() || minCoords.getY() > maxCoords.getY()) {
+      throw new IllegalArgumentException(
+              "Minimum coordinates must be less than maximum coordinates");
+    }
+    if (minCoords.equals(maxCoords)) {
+      throw new IllegalArgumentException("Minimum and maximum coordinates cannot be the same");
+    }
+  }
+
+  /**
+   * Method for validating the transformations.
+   *
+   * @param transforms List of transformations to apply to the points
+   */
+  private void validateTransforms(List<Transform2D> transforms) {
+    if (transforms == null) {
+      throw new IllegalArgumentException("Transformations cannot be null");
+    }
+    if (transforms.size() > 4 || transforms.isEmpty()) {
+      throw new IllegalArgumentException("Number of transformations must be between 1 and 4");
+    }
+  }
+
   public Vector2D getMinCoords() {
     return minCoords;
   }
@@ -70,6 +115,7 @@ public class ChaosGameDescription {
   }
 
   public void setTransforms(List<Transform2D> transforms) {
+    validateTransforms(transforms);
     this.transforms = transforms;
   }
 
@@ -80,4 +126,24 @@ public class ChaosGameDescription {
   public void setMaxCoords(Vector2D maxCoords) {
     this.maxCoords = maxCoords;
   }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    ChaosGameDescription that = (ChaosGameDescription) o;
+    return Objects.equals(minCoords, that.minCoords)
+            && Objects.equals(maxCoords, that.maxCoords)
+            && Objects.equals(transforms, that.transforms)
+            && Objects.equals(probabilities, that.probabilities);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(minCoords, maxCoords, transforms, probabilities);
+  }
 }
diff --git a/src/main/java/org/example/chaosgame/model/chaos/ExploreGame.java b/src/main/java/org/example/chaosgame/model/chaos/ExploreGame.java
index 506e325997f5858ad48c1b3eb6b750749a5abc7b..16aa2be8aad9ec1f1d27b468fd3e858ae91be351 100644
--- a/src/main/java/org/example/chaosgame/model/chaos/ExploreGame.java
+++ b/src/main/java/org/example/chaosgame/model/chaos/ExploreGame.java
@@ -7,6 +7,8 @@ import org.example.chaosgame.controller.interfaces.Observer;
 import org.example.chaosgame.controller.interfaces.Subject;
 import org.example.chaosgame.model.linalg.Vector2D;
 
+
+
 /**
  * Class for exploring julia sets.
  */
@@ -28,11 +30,28 @@ public class ExploreGame implements Subject {
    */
   public ExploreGame(ChaosGameDescription description, int width, int height) {
     this.description = description;
-    this.canvas = new ChaosCanvas(width, height,
-            description.getMinCoords(), description.getMaxCoords());
+    this.canvas = new ChaosCanvas(
+            width, height,
+            description.getMinCoords(),
+            description.getMaxCoords());
     this.gameObservers = new ArrayList<>();
   }
 
+  /**
+   * Method for setting the chaos game.
+   *
+   * @param description Description of the chaos game
+   *
+   * @param width Width of the canvas
+   *
+   * @param height Height of the canvas
+   */
+  public void setExploreGame(ChaosGameDescription description, int width, int height) {
+    this.description = description;
+    setChaosCanvas(description.getMinCoords(), description.getMaxCoords(), width, height);
+
+  }
+
   public ChaosCanvas getCanvas() {
     return canvas;
   }
@@ -41,11 +60,6 @@ public class ExploreGame implements Subject {
     return description;
   }
 
-  public void setExploreGame(ChaosGameDescription description, int width, int height) {
-    this.description = description;
-    setChaosCanvas(description.getMinCoords(), description.getMaxCoords(), width, height);
-  }
-
   /**
    * Method for setting the chaos canvas.
    *
diff --git a/src/main/java/org/example/chaosgame/model/linalg/Matrix2x2.java b/src/main/java/org/example/chaosgame/model/linalg/Matrix2x2.java
index 24a5f69fd23de18c3a0b064a7053f17b7b1c12c6..ea2b4911ee21761c87b45e26ff255d7333db036e 100644
--- a/src/main/java/org/example/chaosgame/model/linalg/Matrix2x2.java
+++ b/src/main/java/org/example/chaosgame/model/linalg/Matrix2x2.java
@@ -1,6 +1,8 @@
 package org.example.chaosgame.model.linalg;
 
 
+import java.util.Objects;
+
 /**
  * Record for 2x2 matrices.
  * The matrices are represented by four double values: a, b, c, and d.
@@ -37,4 +39,39 @@ public record Matrix2x2(double a, double b, double c, double d) {
             this.c * vector.getX() + this.d * vector.getY()
     );
   }
+
+  /**
+   * Equals method for Matrix2x2.
+   * Compares the four double values of two Matrix2x2 objects.
+   * Generated by IntelliJ IDEA.
+   *
+   * @param o the object to compare.
+   * @return true if the objects are equal, false otherwise.
+   */
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    Matrix2x2 matrix2x2 = (Matrix2x2) o;
+    return Double.compare(a, matrix2x2.a) == 0
+            && Double.compare(b, matrix2x2.b) == 0
+            && Double.compare(c, matrix2x2.c) == 0
+            && Double.compare(d, matrix2x2.d) == 0;
+  }
+
+  /**
+   * Hashcode method for Matrix2x2.
+   * Use the four double values to generate the hashcode.
+   * Generated by IntelliJ IDEA.
+   *
+   * @return the hashcode of the Matrix2x2 object.
+   */
+  @Override
+  public int hashCode() {
+    return Objects.hash(a, b, c, d);
+  }
 }
diff --git a/src/main/java/org/example/chaosgame/model/linalg/Vector2D.java b/src/main/java/org/example/chaosgame/model/linalg/Vector2D.java
index 3d9ec7a2daf3979335f7acb14ebe02923cfe79e3..c06683ae4e49f58196a970b7dfae59891df163d5 100644
--- a/src/main/java/org/example/chaosgame/model/linalg/Vector2D.java
+++ b/src/main/java/org/example/chaosgame/model/linalg/Vector2D.java
@@ -1,5 +1,7 @@
 package org.example.chaosgame.model.linalg;
 
+import java.util.Objects;
+
 /**
  * Class for 2D vectors.
  * Vectors are represented by an x-coordinate and a y-coordinate.
@@ -98,4 +100,38 @@ public class Vector2D {
   public double lengthSq() {
     return x * x + y * y;
   }
+
+
+  /**
+   * Equals method for Vector2D.
+   * Compares two vectors for equality.
+   * Overrides the default equals method.
+   * Generated by IntelliJ IDEA.
+   *
+   * @param o Object to compare
+   * @return true if the vectors are equal, false otherwise
+   */
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    Vector2D vector2D = (Vector2D) o;
+    return Double.compare(x, vector2D.x) == 0 && Double.compare(y, vector2D.y) == 0;
+  }
+
+  /**
+   * Hashcode method for Vector2D.
+   * Overrides the default hashcode method.
+   * Generated by IntelliJ IDEA.
+   *
+   * @return the hashcode of the vector
+   */
+  @Override
+  public int hashCode() {
+    return Objects.hash(x, y);
+  }
 }
diff --git a/src/main/java/org/example/chaosgame/model/transformations/AffineTransform2D.java b/src/main/java/org/example/chaosgame/model/transformations/AffineTransform2D.java
index 91c6d239e41630164e9018f27d7efab9aadda68b..da0db148c4a0ca696002e500fa59eec2bb692800 100644
--- a/src/main/java/org/example/chaosgame/model/transformations/AffineTransform2D.java
+++ b/src/main/java/org/example/chaosgame/model/transformations/AffineTransform2D.java
@@ -1,8 +1,10 @@
 package org.example.chaosgame.model.transformations;
 
+import java.util.Objects;
 import org.example.chaosgame.model.linalg.Matrix2x2;
 import org.example.chaosgame.model.linalg.Vector2D;
 
+
 /**
  * Record for 2D affine transformations.
  * The transformation is represented by a 2x2 matrix and a 2D vector.
@@ -33,4 +35,36 @@ public record AffineTransform2D(Matrix2x2 matrix, Vector2D vector) implements Tr
   public Vector2D transform(Vector2D point) {
     return matrix.multiply(point).add(vector);
   }
+
+  /**
+   * Equals method for AffineTransform2D.
+   * Compares the matrix and vector of two AffineTransform2D objects.
+   * Generated by IntelliJ IDEA.
+   *
+   * @param o the object to compare
+   * @return true if the objects are equal, false otherwise
+   */
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    AffineTransform2D that = (AffineTransform2D) o;
+    return Objects.equals(vector, that.vector) && Objects.equals(matrix, that.matrix);
+  }
+
+  /**
+   * Hashcode method for AffineTransform2D.
+   * Use the matrix and vector to generate the hashcode.
+   * Generated by IntelliJ IDEA.
+   *
+   * @return the hashcode of the AffineTransform2D object
+   */
+  @Override
+  public int hashCode() {
+    return Objects.hash(matrix, vector);
+  }
 }
diff --git a/src/main/java/org/example/chaosgame/model/transformations/JuliaTransform.java b/src/main/java/org/example/chaosgame/model/transformations/JuliaTransform.java
index 85d619f461c67429aff91032bb02f16864154001..98119ed4144a9a0758c78c3b20e5ec157244db11 100644
--- a/src/main/java/org/example/chaosgame/model/transformations/JuliaTransform.java
+++ b/src/main/java/org/example/chaosgame/model/transformations/JuliaTransform.java
@@ -1,5 +1,6 @@
 package org.example.chaosgame.model.transformations;
 
+import java.util.Objects;
 import org.example.chaosgame.model.linalg.Complex;
 import org.example.chaosgame.model.linalg.Vector2D;
 
@@ -49,4 +50,37 @@ public class JuliaTransform implements Transform2D {
     double b = sign * result.getY();
     return new Vector2D(a, b);
   }
+
+
+  /**
+   * Equals method for JuliaTransform.
+   * Compares the point and sign of two JuliaTransform objects.
+   * Generated by IntelliJ IDEA.
+   *
+   * @param o the object to compare
+   * @return true if the objects are equal, false otherwise
+   */
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    JuliaTransform that = (JuliaTransform) o;
+    return sign == that.sign && Objects.equals(point, that.point);
+  }
+
+  /**
+   * Hashcode method for JuliaTransform.
+   * Generates a hashcode based on the point and sign of the JuliaTransform object.
+   * Generated by IntelliJ IDEA.
+   *
+   * @return the hashcode of the object
+   */
+  @Override
+  public int hashCode() {
+    return Objects.hash(point, sign);
+  }
 }
diff --git a/src/main/java/org/example/chaosgame/view/ChaosPage.java b/src/main/java/org/example/chaosgame/view/ChaosPage.java
index cbb58d76538c913ad304ddca7361c4da086b07b3..5ada76ba90ee8975e1c18c1baf38e51e97a7e8a4 100644
--- a/src/main/java/org/example/chaosgame/view/ChaosPage.java
+++ b/src/main/java/org/example/chaosgame/view/ChaosPage.java
@@ -30,10 +30,10 @@ public class ChaosPage extends GamePage {
     this.bottomBar.getStyleClass().add("chaos-text");
     SideBar sideBar = new SideBar(chaosGameController);
 
+    this.setCenter(gc.getCanvas());
     this.setTop(topBar);
     this.setRight(sideBar);
     this.setBottom(bottomBar);
-    this.setLeft(gc.getCanvas());
   }
 
   /**
@@ -45,7 +45,7 @@ public class ChaosPage extends GamePage {
    * @param max            the max coordinates
    */
   public void updateInformation(Transform2D transformation, int steps, Vector2D min, Vector2D max) {
-    topBar.updateTopBar(transformation, steps, min, max);
+    topBar.updateTotalTopBar(transformation, steps, min, max);
     bottomBar.updateBottomBar(transformation);
   }
 
diff --git a/src/main/java/org/example/chaosgame/view/ExplorePage.java b/src/main/java/org/example/chaosgame/view/ExplorePage.java
index 97e6522b52bdae8e577317b26893bcbd8a709747..610dce2870d3932bea90c088c3a446789c10a1ca 100644
--- a/src/main/java/org/example/chaosgame/view/ExplorePage.java
+++ b/src/main/java/org/example/chaosgame/view/ExplorePage.java
@@ -36,13 +36,7 @@ public class ExplorePage extends GamePage {
     this.setBottom(bottomBar);
     this.setTop(topBar);
 
-    gc.getCanvas().setOnScroll(event -> {
-      try {
-        exploreGameController.onScroll(event);
-      } catch (Exception e) {
-        exploreGameController.resetImage();
-      }
-    });
+    gc.getCanvas().setOnScroll(exploreGameController::onScroll);
     this.setOnMousePressed(exploreGameController::mousePressed);
     this.setOnMouseDragged(exploreGameController::mouseDragged);
     this.setOnMouseReleased(exploreGameController::mouseReleased);
diff --git a/src/main/java/org/example/chaosgame/view/components/BottomBar.java b/src/main/java/org/example/chaosgame/view/components/BottomBar.java
index 00d8d3677d5c8916bc5c5d37845ce30af3f82b87..d0117d724f9b5fddba3930c8f23c6808ee85e8c6 100644
--- a/src/main/java/org/example/chaosgame/view/components/BottomBar.java
+++ b/src/main/java/org/example/chaosgame/view/components/BottomBar.java
@@ -30,16 +30,15 @@ public class BottomBar extends HBox {
   public BottomBar(GameController gameController) {
     this.setSpacing(10);
     this.realPartLabel = new Label();
+    this.realPartLabel.getStyleClass().add("top-bottom-padding");
     this.imaginaryPartLabel = new Label();
+    this.imaginaryPartLabel.getStyleClass().add("top-bottom-padding");
     this.sliderRealPart = new SliderRealPart(gameController);
     this.sliderImaginaryPart = new SliderImaginaryPart(gameController);
 
     realPartLabel.setMinSize(200, 20);
     imaginaryPartLabel.setMinSize(200, 20);
-    realPartLabel.setAlignment(Pos.CENTER);
-    imaginaryPartLabel.setAlignment(Pos.CENTER);
-
-    this.setAlignment(javafx.geometry.Pos.CENTER);
+    this.setAlignment(Pos.CENTER);
     this.getChildren().addAll(realPartLabel, sliderRealPart,
             sliderImaginaryPart, imaginaryPartLabel);
 
diff --git a/src/main/java/org/example/chaosgame/view/components/MinMaxDialog.java b/src/main/java/org/example/chaosgame/view/components/MinMaxDialog.java
index de0589baaeeaf30a31be6beca32ff59313c70893..3286a6b549c2d5c0a9515c11ae87e07c785e67d1 100644
--- a/src/main/java/org/example/chaosgame/view/components/MinMaxDialog.java
+++ b/src/main/java/org/example/chaosgame/view/components/MinMaxDialog.java
@@ -1,6 +1,8 @@
 package org.example.chaosgame.view.components;
 
 import java.util.List;
+
+import javafx.scene.control.ButtonBar;
 import javafx.scene.control.ButtonType;
 import javafx.scene.control.Dialog;
 import javafx.scene.control.TextField;
@@ -24,8 +26,8 @@ public class MinMaxDialog extends Dialog<List<String>> {
     setTitle("Set Min/Max Coordinates");
     setHeaderText("Please enter the min and max coordinates:");
 
-    ButtonType okButtonType = new ButtonType("OK");
-    getDialogPane().getButtonTypes().addAll(ButtonType.CANCEL, okButtonType);
+    ButtonType saveButtonType = new ButtonType("Save", ButtonBar.ButtonData.OK_DONE);
+    this.getDialogPane().getButtonTypes().addAll(saveButtonType, ButtonType.CANCEL);
 
     GridPane grid = new GridPane();
     grid.setHgap(10);
@@ -49,7 +51,7 @@ public class MinMaxDialog extends Dialog<List<String>> {
     getDialogPane().setContent(grid);
 
     setResultConverter(dialogButton -> {
-      if (dialogButton == okButtonType) {
+      if (dialogButton == saveButtonType) {
         String minX = minXField.getText();
         String minY = minYField.getText();
         String maxX = maxXField.getText();
diff --git a/src/main/java/org/example/chaosgame/view/components/NumberOfStepsInput.java b/src/main/java/org/example/chaosgame/view/components/NumberOfStepsInput.java
index 75bb62a31935405af03581c2e174827dc0bdb991..ee59938e76cb7a23b6a565220a5ee04d958c0103 100644
--- a/src/main/java/org/example/chaosgame/view/components/NumberOfStepsInput.java
+++ b/src/main/java/org/example/chaosgame/view/components/NumberOfStepsInput.java
@@ -15,7 +15,7 @@ public class NumberOfStepsInput extends TextField {
     this.setPromptText("Number of steps");
     this.setMaxWidth(180);
     this.setMinWidth(180);
-    this.setMinHeight(30);
-    this.setMaxHeight(30);
+    this.setMinHeight(40);
+    this.setMaxHeight(40);
   }
 }
diff --git a/src/main/java/org/example/chaosgame/view/components/SideBar.java b/src/main/java/org/example/chaosgame/view/components/SideBar.java
index 7102f0ea6ce0165b4c158394be74adf77fd2bc4e..d866803f75142d8bffb6016ec700a8a849e7959a 100644
--- a/src/main/java/org/example/chaosgame/view/components/SideBar.java
+++ b/src/main/java/org/example/chaosgame/view/components/SideBar.java
@@ -47,13 +47,13 @@ public class SideBar extends VBox {
             chaosGameController::updateFractalColor);
 
     this.getChildren().addAll(
-            fractalSelectionBox, colorPicker, numberOfStepsInput,
-            coordinatesButton, createOwnFractal, saveFractalButton, openFileButton,
-            runGame, resetGame);
+            fractalSelectionBox, colorPicker, coordinatesButton,
+            createOwnFractal, saveFractalButton, openFileButton,
+            numberOfStepsInput, runGame, resetGame);
     this.setAlignment(Pos.CENTER_RIGHT);
 
-    VBox.setMargin(coordinatesButton, new Insets(50, 0, 0, 0));
-    VBox.setMargin(runGame, new Insets(50, 0, 0, 0));
+    VBox.setMargin(coordinatesButton, new Insets(30, 0, 0, 0));
+    VBox.setMargin(numberOfStepsInput, new Insets(30, 0, 0, 0));
 
     this.getStyleClass().add("side-bar");
   }
diff --git a/src/main/java/org/example/chaosgame/view/components/SliderImaginaryPart.java b/src/main/java/org/example/chaosgame/view/components/SliderImaginaryPart.java
index db2f476fd378b1bacdf468427a8a003184835b20..14649a0f31469f9d64083859a2b53ec1d5b87518 100644
--- a/src/main/java/org/example/chaosgame/view/components/SliderImaginaryPart.java
+++ b/src/main/java/org/example/chaosgame/view/components/SliderImaginaryPart.java
@@ -14,6 +14,7 @@ public class SliderImaginaryPart extends BaseSlider {
    */
   public SliderImaginaryPart(GameController gameController) {
     super(gameController);
+    this.getStyleClass().add("top-bottom-padding");
   }
 
   /**
diff --git a/src/main/java/org/example/chaosgame/view/components/SliderRealPart.java b/src/main/java/org/example/chaosgame/view/components/SliderRealPart.java
index 1d9586fee9926401c6ae11fd03afb17777fddf46..48926964ef8a20808c1dc612775d2866df9feeb7 100644
--- a/src/main/java/org/example/chaosgame/view/components/SliderRealPart.java
+++ b/src/main/java/org/example/chaosgame/view/components/SliderRealPart.java
@@ -14,6 +14,7 @@ public class SliderRealPart extends BaseSlider {
    */
   public SliderRealPart(GameController gameController) {
     super(gameController);
+    this.getStyleClass().add("top-bottom-padding");
   }
 
   @Override
diff --git a/src/main/java/org/example/chaosgame/view/components/TopBar.java b/src/main/java/org/example/chaosgame/view/components/TopBar.java
index 8ffad6d296c05eadac91c21eea946166b5c5ecf0..90a397acbe8e35a9c228236fa941c7bd80153b9f 100644
--- a/src/main/java/org/example/chaosgame/view/components/TopBar.java
+++ b/src/main/java/org/example/chaosgame/view/components/TopBar.java
@@ -25,16 +25,16 @@ public class TopBar extends HBox {
   public TopBar(GameController gameController) {
     super();
     this.gameInfo = new Label();
+    this.gameInfo.getStyleClass().add("top-bottom-padding");
     this.stepsLabel = new Label();
+    this.stepsLabel.getStyleClass().add("top-bottom-padding");
     this.coordinatesLabel = new Label();
+    this.coordinatesLabel.getStyleClass().add("top-bottom-padding");
 
     Button homeButton = new HomeButton();
     homeButton.setOnAction(event -> gameController.homeButtonClicked());
 
     this.getChildren().addAll(homeButton, gameInfo, coordinatesLabel, stepsLabel);
-    this.setPadding(new javafx.geometry.Insets(10));
-
-    this.setSpacing(50);
     this.setAlignment(Pos.CENTER_LEFT);
     this.getStyleClass().add("top-bottom-bar");
   }
@@ -47,10 +47,9 @@ public class TopBar extends HBox {
    * @param min        the min coordinates
    * @param max        the max coordinates
    */
-  public void updateTopBar(Transform2D first, int totalSteps, Vector2D min, Vector2D max) {
+  public void updateTotalTopBar(Transform2D first, int totalSteps, Vector2D min, Vector2D max) {
     gameInfo.setText("Transformation: " + first.getClass().getSimpleName());
-    coordinatesLabel.setText("Min-Coordinate: " + min.getX() + ", " + min.getY()
-            + ". Max-Coordinate: " + max.getX() + ", " + max.getY());
+    updateTopBar(min, max);
     stepsLabel.setText("Total steps: " + totalSteps);
   }
 
@@ -61,9 +60,7 @@ public class TopBar extends HBox {
    * @param max the max coordinates
    */
   public void updateTopBar(Vector2D min, Vector2D max) {
-    coordinatesLabel.setText("Min-Coordinate: " + (double) Math.round(min.getX() * 100) / 100
-            + ", " + (double) Math.round(min.getY() * 100) / 100
-            + ". Max-Coordinate: " + (double) Math.round(max.getX() * 100) / 100 + ", "
-            + (double) Math.round(max.getY() * 100) / 100);
+    coordinatesLabel.setText("Coordinates: " + (double) Math.round(min.getX() * 100) / 100 + " , " + (double) Math.round(min.getY() * 100) / 100 +
+            " (min), " + (double) Math.round(max.getX() * 100) / 100 + ", " + (double) Math.round(max.getY() * 100) / 100 + " (max)");
   }
 }
diff --git a/src/main/resources/global.css b/src/main/resources/global.css
index 94ba268ec19f297e7c129e24839d5b43d31f0061..7957355911a0fff1faa5f148816c061df412d7b4 100644
--- a/src/main/resources/global.css
+++ b/src/main/resources/global.css
@@ -26,8 +26,12 @@
 }
 
 .text-field {
-    -fx-font: 14 arial;
-    -fx-border-color: black;
+    -fx-font: 20 arial;
+    -fx-background-color: white;
+    -fx-text-fill: black;
+    -fx-border-color: #3b3b3b;
+    -fx-background-radius: 20;
+    -fx-border-radius: 20;
     -fx-border-width: 2;
     -fx-background-insets: 1;
 }
@@ -56,7 +60,6 @@
 
 .combo-box .indexed-cell:selected {
     -fx-text-fill: white;
-    -fx-background-radius: 20;
 }
 
 .choose-game-button {
@@ -125,6 +128,7 @@
     -fx-padding: 20;
     -fx-spacing: 10;
 }
+
 .top-bottom-bar .text {
     -fx-font: 20 arial;
     -fx-fill: #7c7c7c;
@@ -138,6 +142,11 @@
     -fx-background-insets: 1;
 }
 
+.top-bottom-padding{
+    -fx-padding: 0 10 0 10;
+}
+
+
 
 
 
diff --git a/src/test/java/org/example/chaosgame/controller/ChaosGameControllerTest.java b/src/test/java/org/example/chaosgame/controller/ChaosGameControllerTest.java
index b8802696767470ba48dad16a0c660907c19fc0bc..1e16946f1d1a9978186686d4afb38f6e343cbe8e 100644
--- a/src/test/java/org/example/chaosgame/controller/ChaosGameControllerTest.java
+++ b/src/test/java/org/example/chaosgame/controller/ChaosGameControllerTest.java
@@ -2,71 +2,69 @@ package org.example.chaosgame.controller;
 
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.*;
-
 class ChaosGameControllerTest {
 
-    @Test
-    void gameSelection() {
-    }
-
-    @Test
-    void runStepsValidation() {
-    }
-
-    @Test
-    void openFromFile() {
-    }
-
-    @Test
-    void updateFractalColor() {
-    }
-
-    @Test
-    void createOwnJuliaFractal() {
-    }
-
-    @Test
-    void createOwnAffineFractal() {
-    }
-
-    @Test
-    void updateJuliaValue() {
-    }
-
-    @Test
-    void isJuliaShowing() {
-    }
-
-    @Test
-    void saveFractal() {
-    }
-
-    @Test
-    void homeButtonClicked() {
-    }
-
-    @Test
-    void update() {
-    }
-
-    @Test
-    void registerObserver() {
-    }
-
-    @Test
-    void removeObserver() {
-    }
-
-    @Test
-    void notifyObservers() {
-    }
-
-    @Test
-    void setCanvas() {
-    }
-
-    @Test
-    void setBind() {
-    }
+  @Test
+  void gameSelection() {
+  }
+  
+  @Test
+  void runStepsValidation() {
+  }
+  
+  @Test
+  void openFromFile() {
+  }
+  
+  @Test
+  void updateFractalColor() {
+  }
+  
+  @Test
+  void createOwnJuliaFractal() {
+  }
+  
+  @Test
+  void createOwnAffineFractal() {
+  }
+  
+  @Test
+  void updateJuliaValue() {
+  }
+  
+  @Test
+  void isJuliaShowing() {
+  }
+  
+  @Test
+  void saveFractal() {
+  }
+  
+  @Test
+  void homeButtonClicked() {
+  }
+  
+  @Test
+  void update() {
+  }
+  
+  @Test
+  void registerObserver() {
+  }
+  
+  @Test
+  void removeObserver() {
+  }
+  
+  @Test
+  void notifyObservers() {
+  }
+  
+  @Test
+  void setCanvas() {
+  }
+  
+  @Test
+  void setBind() {
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/org/example/chaosgame/controller/ExploreGameControllerTest.java b/src/test/java/org/example/chaosgame/controller/ExploreGameControllerTest.java
index e999b1b47ee1487ca70f70de3fc999be8830e97d..05f43e043ac30ae963730e3b8c98e4a8d67a78ea 100644
--- a/src/test/java/org/example/chaosgame/controller/ExploreGameControllerTest.java
+++ b/src/test/java/org/example/chaosgame/controller/ExploreGameControllerTest.java
@@ -2,71 +2,69 @@ package org.example.chaosgame.controller;
 
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.*;
-
 class ExploreGameControllerTest {
 
-    @Test
-    void mousePressed() {
-    }
+  @Test
+  void mousePressed() {
+  }
 
-    @Test
-    void mouseDragged() {
-    }
+  @Test
+  void mouseDragged() {
+  }
 
-    @Test
-    void mouseReleased() {
-    }
+  @Test
+  void mouseReleased() {
+  }
 
-    @Test
-    void zoomButtonClicked() {
-    }
+  @Test
+  void zoomButtonClicked() {
+  }
 
-    @Test
-    void onScroll() {
-    }
+  @Test
+  void onScroll() {
+  }
 
-    @Test
-    void homeButtonClicked() {
-    }
+  @Test
+  void homeButtonClicked() {
+  }
 
-    @Test
-    void getExplorePage() {
-    }
+  @Test
+  void getExplorePage() {
+  }
 
-    @Test
-    void updateFractalColor() {
-    }
+  @Test
+  void updateFractalColor() {
+  }
 
-    @Test
-    void update() {
-    }
+  @Test
+  void update() {
+  }
 
-    @Test
-    void registerObserver() {
-    }
+  @Test
+  void registerObserver() {
+  }
 
-    @Test
-    void removeObserver() {
-    }
+  @Test
+  void removeObserver() {
+  }
 
-    @Test
-    void notifyObservers() {
-    }
+  @Test
+  void notifyObservers() {
+  }
 
-    @Test
-    void updateExploreGame() {
-    }
+  @Test
+  void updateExploreGame() {
+  }
 
-    @Test
-    void resetImage() {
-    }
+  @Test
+  void resetImage() {
+  }
 
-    @Test
-    void setCanvas() {
-    }
+  @Test
+  void setCanvas() {
+  }
 
-    @Test
-    void updateJuliaValue() {
-    }
+  @Test
+  void updateJuliaValue() {
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/org/example/chaosgame/controller/HomeControllerTest.java b/src/test/java/org/example/chaosgame/controller/HomeControllerTest.java
index 6822a1539696115645d52e73d001d9b55da5a70a..c32f31ad6d11ba9334513ff41893d28879e4a99a 100644
--- a/src/test/java/org/example/chaosgame/controller/HomeControllerTest.java
+++ b/src/test/java/org/example/chaosgame/controller/HomeControllerTest.java
@@ -2,15 +2,13 @@ package org.example.chaosgame.controller;
 
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.*;
-
 class HomeControllerTest {
 
-    @Test
-    void getHomePage() {
-    }
+  @Test
+  void getHomePage() {
+  }
 
-    @Test
-    void mouseEvent() {
-    }
+  @Test
+  void mouseEvent() {
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/org/example/chaosgame/controller/PageControllerTest.java b/src/test/java/org/example/chaosgame/controller/PageControllerTest.java
index 79fca41197a16e135c9f3b8260766221980b9ae3..7cc833bfb1dc27426e54df472030aa6002e7e3ed 100644
--- a/src/test/java/org/example/chaosgame/controller/PageControllerTest.java
+++ b/src/test/java/org/example/chaosgame/controller/PageControllerTest.java
@@ -6,15 +6,15 @@ import static org.junit.jupiter.api.Assertions.*;
 
 class PageControllerTest {
 
-    @Test
-    void goToPage() {
-    }
+  @Test
+  void goToPage() {
+  }
 
-    @Test
-    void exitGame() {
-    }
+  @Test
+  void exitGame() {
+  }
 
-    @Test
-    void update() {
-    }
+  @Test
+  void update() {
+  }
 }
\ No newline at end of file
diff --git a/src/test/java/org/example/chaosgame/linalg/Vector2DTest.java b/src/test/java/org/example/chaosgame/linalg/Vector2DTest.java
deleted file mode 100644
index 5fecb5d6d240041de927b00efe392440a06520a6..0000000000000000000000000000000000000000
--- a/src/test/java/org/example/chaosgame/linalg/Vector2DTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package org.example.chaosgame.linalg;
-
-import org.example.chaosgame.model.linalg.Vector2D;
-import org.junit.jupiter.api.*;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-class Vector2DTest {
-  private double x;
-  private double y;
-  private Vector2D vector;
-  private Vector2D otherVector;
-
-  @BeforeEach
-  void setUp() {
-    x = 1.0;
-    y = 2.0;
-    vector = new Vector2D(x, y);
-    otherVector = new Vector2D(1.0, 1.0);
-  }
-
-  @AfterEach
-  void tearDown() {
-    vector = null;
-    otherVector = null;
-  }
-
-  @Nested
-  @DisplayName("Test getX and getY")
-  class TestGetters {
-    @Test
-    @DisplayName("Test getX")
-    void getX() {
-      assertEquals(x, vector.getX());
-    }
-
-    @Test
-    @DisplayName("Test getY")
-    void getY() {
-      assertEquals(y, vector.getY());
-    }
-  }
-
-  @Nested
-  @DisplayName("Test add and subtract")
-  class TestAddAndSubtract {
-    @Test
-    @DisplayName("Test add should work")
-    void add() {
-      Vector2D w = vector.add(otherVector);
-      assertEquals(2.0, w.getX());
-      assertEquals(3.0, w.getY());
-    }
-
-    @Test
-    @DisplayName("Test add should not work")
-    void addFail() {
-      Vector2D w = vector.add(otherVector);
-      assertNotEquals(1.0, w.getX());
-      assertNotEquals(2.0, w.getY());
-    }
-
-    @Test
-    @DisplayName("Test subtract should work")
-    void subtract() {
-      Vector2D w = vector.subtract(otherVector);
-      assertEquals(0.0, w.getX());
-      assertEquals(1.0, w.getY());
-    }
-
-    @Test
-    @DisplayName("Test subtract should not work")
-    void subtractFail() {
-      Vector2D w = vector.subtract(otherVector);
-      assertNotEquals(1.0, w.getX());
-      assertNotEquals(2.0, w.getY());
-    }
-  }
-}
\ No newline at end of file
diff --git a/src/test/java/org/example/chaosgame/model/chaos/ChaosCanvasTest.java b/src/test/java/org/example/chaosgame/model/chaos/ChaosCanvasTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..a55ef4c5ce55787d116f5675911918a616002274
--- /dev/null
+++ b/src/test/java/org/example/chaosgame/model/chaos/ChaosCanvasTest.java
@@ -0,0 +1,188 @@
+package org.example.chaosgame.model.chaos;
+
+import org.example.chaosgame.model.linalg.Vector2D;
+import org.example.chaosgame.model.transformations.AffineTransform2D;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.AfterEach;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class ChaosCanvasTest {
+  private static ChaosCanvas chaosCanvas;
+  private static Vector2D minCoords;
+  private static Vector2D maxCoords;
+  private static final int WIDTH = 100;
+  private static final int HEIGHT = 100;
+
+  @BeforeEach
+  void setUp() {
+    minCoords = new Vector2D(0, 0);
+    maxCoords = new Vector2D(1, 1);
+    chaosCanvas = new ChaosCanvas(WIDTH, HEIGHT, minCoords, maxCoords);
+  }
+
+  @AfterEach
+  void tearDown() {
+    minCoords = null;
+    maxCoords = null;
+    chaosCanvas = null;
+  }
+
+  @Nested
+  @DisplayName("Test getPixel")
+  class TestGetPixel {
+    @Test
+    @DisplayName("Test positive getPixel")
+    void getPixel() {
+      double pixel = chaosCanvas.getPixel(new Vector2D(0.5, 0.5));
+      assertEquals(0.0, pixel);
+    }
+
+    @Test
+    @DisplayName("Test negative getPixel")
+    void getPixelFail() {
+      double pixel = chaosCanvas.getPixel(new Vector2D(0, 0));
+      assertNotEquals(1.0, pixel);
+    }
+  }
+
+  @Nested
+  @DisplayName("Test putPixel")
+  class TestPutPixel {
+    @Test
+    @DisplayName("Test positive putPixel(Vector2D)")
+    void putPixel() {
+      chaosCanvas.putPixelChaos(new Vector2D(0, 0));
+      assertEquals(1.0, chaosCanvas.getPixel(new Vector2D(0, 0)));
+    }
+
+    @Test
+    @DisplayName("Test negative putPixel(Vector2D)")
+    void putPixelFail() {
+      chaosCanvas.putPixelChaos(new Vector2D(0, 0));
+      assertNotEquals(0.0, chaosCanvas.getPixel(new Vector2D(0, 0)));
+    }
+
+    @Test
+    @DisplayName("Test positive putPixel(int, int, double)")
+    void putPixelInt() {
+      chaosCanvas.putPixelExplore(0, 0, 1.0);
+      assertEquals(1.0, chaosCanvas.getPixel(new Vector2D(0, 1)));
+    }
+
+    @Test
+    @DisplayName("Test negative putPixel(int, int, double)")
+    void putPixelIntFail() {
+      chaosCanvas.putPixelExplore(0, 0, 1.0);
+      assertNotEquals(0.0, chaosCanvas.getPixel(new Vector2D(0, 1)));
+    }
+  }
+
+  @Nested
+  @DisplayName("Test transformIndicesToCoords")
+  class TestTransformIndicesToCoords {
+    @Test
+    @DisplayName("Test positive transformIndicesToCoords")
+    void transformIndicesToCoords() {
+      Vector2D coords = chaosCanvas.transformIndicesToCoords(0, 0);
+      assertEquals(0.0, coords.getX());
+      assertEquals(1.0, coords.getY());
+    }
+
+    @Test
+    @DisplayName("Test negative transformIndicesToCoords")
+    void transformIndicesToCoordsFail() {
+      Vector2D coords = chaosCanvas.transformIndicesToCoords(0, 0);
+      assertNotEquals(1.0, coords.getX());
+      assertNotEquals(0.0, coords.getY());
+    }
+  }
+
+  @Nested
+  @DisplayName("Test clearCanvas")
+  class TestClearCanvas {
+    @Test
+    @DisplayName("Test positive clearCanvas")
+    void clearCanvas() {
+      chaosCanvas.putPixelChaos(new Vector2D(0, 0));
+      chaosCanvas.clearCanvas();
+      assertEquals(0.0, chaosCanvas.getPixel(new Vector2D(0, 0)));
+    }
+
+    @Test
+    @DisplayName("Test negative clearCanvas")
+    void clearCanvasFail() {
+      chaosCanvas.putPixelChaos(new Vector2D(0, 0));
+      chaosCanvas.clearCanvas();
+      double[][] canvas = chaosCanvas.getCanvasArray();
+      for (double[] row : canvas) {
+        for (double value : row) {
+          assertNotEquals(1.0, value);
+        }
+      }
+    }
+  }
+
+  @Test
+  void getWidth() {
+    assertEquals(WIDTH, chaosCanvas.getWidth());
+  }
+
+  @Test
+  void getHeight() {
+    assertEquals(HEIGHT, chaosCanvas.getHeight());
+  }
+
+  @Test
+  void getMinCoords() {
+    assertEquals(minCoords, chaosCanvas.getMinCoords());
+  }
+
+  @Test
+  void getMaxCoords() {
+    assertEquals(maxCoords, chaosCanvas.getMaxCoords());
+  }
+
+  @Test
+  void setMinCoords() {
+    Vector2D newMinCoords = new Vector2D(-1, -1);
+    chaosCanvas.setMinCoords(newMinCoords);
+    assertEquals(newMinCoords, chaosCanvas.getMinCoords());
+  }
+
+  @Test
+  void setMaxCoords() {
+    Vector2D newMaxCoords = new Vector2D(2, 2);
+    chaosCanvas.setMaxCoords(newMaxCoords);
+    assertEquals(newMaxCoords, chaosCanvas.getMaxCoords());
+  }
+
+  @Test
+  void setTransformCoordsToIndices() {
+    Vector2D newMinCoords = new Vector2D(-1, -1);
+    Vector2D newMaxCoords = new Vector2D(2, 2);
+    chaosCanvas.setMinCoords(newMinCoords);
+    chaosCanvas.setMaxCoords(newMaxCoords);
+    chaosCanvas.setTransformCoordsToIndices();
+    AffineTransform2D transform = chaosCanvas.getTransformCoordsToIndices();
+    assertNotNull(transform);
+    assertEquals(transform, chaosCanvas.getTransformCoordsToIndices());
+  }
+
+  @Test
+  void setWidth() {
+    int newWidth = 200;
+    chaosCanvas.setWidth(newWidth);
+    assertEquals(newWidth, chaosCanvas.getWidth());
+  }
+
+  @Test
+  void setHeight() {
+    int newHeight = 200;
+    chaosCanvas.setHeight(newHeight);
+    assertEquals(newHeight, chaosCanvas.getHeight());
+  }
+}
diff --git a/src/test/java/org/example/chaosgame/model/chaos/ChaosGameDescriptionFactoryTest.java b/src/test/java/org/example/chaosgame/model/chaos/ChaosGameDescriptionFactoryTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..00e0ad8b31c767e8df81fd56b14cb5b5f93fb962
--- /dev/null
+++ b/src/test/java/org/example/chaosgame/model/chaos/ChaosGameDescriptionFactoryTest.java
@@ -0,0 +1,143 @@
+package org.example.chaosgame.model.chaos;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.List;
+import org.example.chaosgame.controller.ChaosGameDescriptionFactory;
+import org.example.chaosgame.model.linalg.Complex;
+import org.example.chaosgame.model.linalg.Matrix2x2;
+import org.example.chaosgame.model.linalg.Vector2D;
+import org.example.chaosgame.model.transformations.AffineTransform2D;
+import org.example.chaosgame.model.transformations.JuliaTransform;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+class ChaosGameDescriptionFactoryTest {
+  private static ChaosGameDescription expectedJulia;
+  private static ChaosGameDescription expectedSierpinski;
+  private static ChaosGameDescription expectedBarnsley;
+
+  @BeforeAll
+  static void setUp() {
+    expectedJulia = new ChaosGameDescription(
+            new Vector2D(-1.6, -1.0),
+            new Vector2D(1.6, 1.0),
+            List.of(
+                    new JuliaTransform(new Complex(-0.70176, -0.3842), 1)
+            )
+    );
+
+    expectedSierpinski = new ChaosGameDescription(
+            new Vector2D(0.0, 0.0),
+            new Vector2D(1.0, 1.0),
+            List.of(
+                    new AffineTransform2D(new Matrix2x2(0.5, 0.0, 0.0, 0.5),
+                            new Vector2D(0.0, 0.0)),
+                    new AffineTransform2D(new Matrix2x2(0.5, 0.0, 0.0, 0.5),
+                            new Vector2D(0.25, 0.50)),
+                    new AffineTransform2D(new Matrix2x2(0.5, 0.0, 0.0, 0.5),
+                            new Vector2D(0.5, 0.0))
+            )
+    );
+
+    expectedBarnsley = new ChaosGameDescription(
+            new Vector2D(-2.65, 0.0),
+            new Vector2D(2.65, 10.0),
+            List.of(
+                    new AffineTransform2D(new Matrix2x2(0.0, 0.0, 0.0, 0.16),
+                            new Vector2D(0.0, 0.0)),
+                    new AffineTransform2D(new Matrix2x2(0.85, 0.04, -0.04, 0.85),
+                            new Vector2D(0.0, 1.60)),
+                    new AffineTransform2D(new Matrix2x2(0.20, -0.26, 0.23, 0.22),
+                            new Vector2D(0.0, 1.60)),
+                    new AffineTransform2D(new Matrix2x2(-0.15, 0.28, 0.26, 0.24),
+                            new Vector2D(0.0, 0.44))
+            ), List.of(2, 84, 7, 7)
+    );
+  }
+
+
+  @Nested
+  class JuliaTests {
+    @Test
+    void testJuliaNotNull() {
+      ChaosGameDescription juliaResult = ChaosGameDescriptionFactory.get(ChaosGameType.JULIA);
+      assertNotNull(juliaResult);
+    }
+
+    @Test
+    void testJuliaInstanceOf() {
+      ChaosGameDescription juliaResult = ChaosGameDescriptionFactory.get(ChaosGameType.JULIA);
+      assertInstanceOf(ChaosGameDescription.class, juliaResult);
+    }
+
+    @Test
+    void testJuliaEquals() {
+      ChaosGameDescription juliaResult = ChaosGameDescriptionFactory.get(ChaosGameType.JULIA);
+      assertEquals(expectedJulia, juliaResult);
+    }
+  }
+
+  @Nested
+  class SierpinskiTests {
+    @Test
+    void testSierpinskiNotNull() {
+      ChaosGameDescription sierpinskiResult =
+              ChaosGameDescriptionFactory.get(ChaosGameType.SIERPINSKI);
+      assertNotNull(sierpinskiResult);
+    }
+
+    @Test
+    void testSierpinskiInstanceOf() {
+      ChaosGameDescription sierpinskiResult =
+              ChaosGameDescriptionFactory.get(ChaosGameType.SIERPINSKI);
+      assertInstanceOf(ChaosGameDescription.class, sierpinskiResult);
+    }
+
+    @Test
+    void testSierpinskiEquals() {
+      ChaosGameDescription sierpinskiResult =
+              ChaosGameDescriptionFactory.get(ChaosGameType.SIERPINSKI);
+      assertEquals(expectedSierpinski, sierpinskiResult);
+    }
+  }
+
+  @Nested
+  class BarnsleyTests {
+    @Test
+    void testBarnsleyNotNull() {
+      ChaosGameDescription barnsleyResult =
+              ChaosGameDescriptionFactory.get(ChaosGameType.BARNSLEY);
+      assertNotNull(barnsleyResult);
+    }
+
+    @Test
+    void testBarnsleyInstanceOf() {
+      ChaosGameDescription barnsleyResult = ChaosGameDescriptionFactory.get(ChaosGameType.BARNSLEY);
+      assertInstanceOf(ChaosGameDescription.class, barnsleyResult);
+    }
+
+    @Test
+    void testBarnsleyEquals() {
+      ChaosGameDescription barnsleyResult = ChaosGameDescriptionFactory.get(ChaosGameType.BARNSLEY);
+      assertEquals(expectedBarnsley, barnsleyResult);
+    }
+  }
+
+  @Test
+  void testInvalidType() {
+    assertThrows(IllegalArgumentException.class, () -> ChaosGameDescriptionFactory.get(null));
+  }
+
+  @AfterAll
+  static void tearDown() {
+    expectedJulia = null;
+    expectedSierpinski = null;
+    expectedBarnsley = null;
+  }
+}
\ No newline at end of file
diff --git a/src/test/java/org/example/chaosgame/model/chaos/ChaosGameDescriptionTest.java b/src/test/java/org/example/chaosgame/model/chaos/ChaosGameDescriptionTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..c85c23b3fcbc496ad9fb13f41cdba2b9932a7eab
--- /dev/null
+++ b/src/test/java/org/example/chaosgame/model/chaos/ChaosGameDescriptionTest.java
@@ -0,0 +1,174 @@
+package org.example.chaosgame.model.chaos;
+
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.Arrays;
+import java.util.List;
+import org.example.chaosgame.model.linalg.Matrix2x2;
+import org.example.chaosgame.model.linalg.Vector2D;
+import org.example.chaosgame.model.transformations.AffineTransform2D;
+import org.example.chaosgame.model.transformations.Transform2D;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+class ChaosGameDescriptionTest {
+  private ChaosGameDescription chaosGameDescription;
+  private Vector2D minCoords;
+  private Vector2D maxCoords;
+  private Matrix2x2 matrixA;
+  private Vector2D vectorPartA;
+  private Matrix2x2 matrixB;
+  private Vector2D vectorPartB;
+  private List<Transform2D> transforms;
+  private List<Integer> probabilities;
+
+  @BeforeEach
+  void setUp() {
+    minCoords = new Vector2D(0, 0);
+    maxCoords = new Vector2D(1, 1);
+
+    matrixA = new Matrix2x2(0.5, 0.0, 0.0, 0.5);
+    vectorPartA = new Vector2D(0.0, 0.0);
+    matrixB = new Matrix2x2(0.5, 0.0, 0.0, 0.5);
+    vectorPartB = new Vector2D(0.25, 0.50);
+    transforms = Arrays.asList(new AffineTransform2D(matrixA, vectorPartA),
+            new AffineTransform2D(matrixB, vectorPartB));
+    probabilities = Arrays.asList(50, 50);
+    chaosGameDescription = new ChaosGameDescription(
+            minCoords, maxCoords, transforms, probabilities);
+  }
+
+  @AfterEach
+  void tearDown() {
+    minCoords = null;
+    maxCoords = null;
+    transforms = null;
+    probabilities = null;
+    chaosGameDescription = null;
+  }
+
+  @Test
+  void testGetMinCoords() {
+    assertEquals(minCoords, chaosGameDescription.getMinCoords());
+  }
+
+  @Test
+  void testGetMaxCoords() {
+    assertEquals(maxCoords, chaosGameDescription.getMaxCoords());
+  }
+
+  @Test
+  void testGetTransforms() {
+    assertEquals(transforms, chaosGameDescription.getTransforms());
+  }
+
+  @Test
+  void testGetProbabilities() {
+    assertEquals(probabilities, chaosGameDescription.getProbabilities());
+  }
+
+  @Nested
+  @DisplayName("SetTransforms")
+  class SetTransforms {
+    @Test
+    @DisplayName("Set null transforms")
+    void testSetNullTransforms() {
+      assertThrows(IllegalArgumentException.class, () -> chaosGameDescription.setTransforms(null));
+    }
+
+    @Test
+    @DisplayName("Set empty transforms")
+    void testSetEmptyTransforms() {
+      assertThrows(IllegalArgumentException.class,
+              () -> chaosGameDescription.setTransforms(List.of()));
+    }
+
+    @Test
+    @DisplayName("Set too many transforms")
+    void testSetTooManyTransforms() {
+      List<Transform2D> tooManyTransforms = Arrays.asList(
+              new AffineTransform2D(matrixA, vectorPartA),
+              new AffineTransform2D(matrixB, vectorPartB),
+              new AffineTransform2D(matrixA, vectorPartA),
+              new AffineTransform2D(matrixB, vectorPartB),
+              new AffineTransform2D(matrixA, vectorPartA)
+      );
+      assertThrows(IllegalArgumentException.class,
+              () -> chaosGameDescription.setTransforms(tooManyTransforms));
+    }
+
+    @Test
+    @DisplayName("Set valid transforms")
+    void testSetValidTransforms() {
+      Matrix2x2 newMatrix = new Matrix2x2(9.9, 9.9, 9.9, 9.9);
+      Vector2D newVector = new Vector2D(9.9, 9.9);
+      List<Transform2D> newTransforms = List.of(new AffineTransform2D(newMatrix, newVector));
+      chaosGameDescription.setTransforms(newTransforms);
+      assertEquals(newTransforms, chaosGameDescription.getTransforms());
+    }
+  }
+
+  @Nested
+  @DisplayName("Set coordinates")
+  class SetCoordinates {
+    @Test
+    @DisplayName("Set min coordinates")
+    void testSetMinCoords() {
+      Vector2D newMinCoords = new Vector2D(-1, -1);
+      chaosGameDescription.setMinCoords(newMinCoords);
+      assertEquals(newMinCoords, chaosGameDescription.getMinCoords());
+    }
+
+    @Test
+    @DisplayName("Set max coordinates")
+    void testSetMaxCoords() {
+      Vector2D newMaxCoords = new Vector2D(2, 2);
+      chaosGameDescription.setMaxCoords(newMaxCoords);
+      assertEquals(newMaxCoords, chaosGameDescription.getMaxCoords());
+    }
+
+    @Test
+    @DisplayName("Set min and max coordinates")
+    void testSetMinAndMaxCoords() {
+      Vector2D newMinCoords = new Vector2D(-99, -99);
+
+      assertThrows(IllegalArgumentException.class,
+              () -> new ChaosGameDescription(newMinCoords, maxCoords, transforms, probabilities));
+      assertThrows(IllegalArgumentException.class,
+              () -> new ChaosGameDescription(maxCoords, minCoords, transforms, probabilities));
+      assertThrows(IllegalArgumentException.class,
+              () -> new ChaosGameDescription(minCoords, minCoords, transforms, probabilities));
+    }
+  }
+
+  @Test
+  void testEquals() {
+    ChaosGameDescription sameChaosGameDescription =
+            new ChaosGameDescription(minCoords, maxCoords, transforms, probabilities);
+    assertEquals(chaosGameDescription, sameChaosGameDescription);
+    assertNotNull(chaosGameDescription);
+    assertNotEquals(chaosGameDescription, new Object());
+    ChaosGameDescription differentChaosGameDescription =
+            new ChaosGameDescription(
+                    new Vector2D(1, 1),
+                    new Vector2D(2, 2),
+                    transforms, probabilities);
+    assertNotEquals(chaosGameDescription, differentChaosGameDescription);
+  }
+
+  @Test
+  void testHashCode() {
+    ChaosGameDescription sameChaosGameDescription
+            = new ChaosGameDescription(
+                    minCoords, maxCoords,
+            transforms, probabilities);
+    assertEquals(chaosGameDescription.hashCode(), sameChaosGameDescription.hashCode());
+  }
+}
diff --git a/src/test/java/org/example/chaosgame/model/chaos/ChaosGameFileHandlerTest.java b/src/test/java/org/example/chaosgame/model/chaos/ChaosGameFileHandlerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..32c0fa2d95254b55ec7692efd67634e8735a3659
--- /dev/null
+++ b/src/test/java/org/example/chaosgame/model/chaos/ChaosGameFileHandlerTest.java
@@ -0,0 +1,354 @@
+package org.example.chaosgame.model.chaos;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import org.example.chaosgame.controller.ChaosGameFileHandler;
+import org.example.chaosgame.model.linalg.Complex;
+import org.example.chaosgame.model.linalg.Matrix2x2;
+import org.example.chaosgame.model.linalg.Vector2D;
+import org.example.chaosgame.model.transformations.AffineTransform2D;
+import org.example.chaosgame.model.transformations.JuliaTransform;
+import org.example.chaosgame.model.transformations.Transform2D;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+
+
+
+
+class ChaosGameFileHandlerTest {
+  private static ChaosGameFileHandler fileHandler;
+  private static String validAffineContent;
+  private static String validJuliaContent;
+  private static String invalidNumbersContent;
+  private static String invalidTypeContent;
+
+  @BeforeAll
+  static void setUp() {
+    fileHandler = new ChaosGameFileHandler();
+    validAffineContent = """
+            Affine2D # Type of Transformation
+            -2.65, 0.0 # Min-coordinate
+            2.65, 10.0 # Max-coordinate
+            0.0, 0.0, 0.0, 0.16, 0.0, 0.0 # 1 transformation
+            0.85, 0.04, -0.04, 0.85, 0.0, 1.6 # 2 transformation
+            0.2, -0.26, 0.23, 0.22, 0.0, 1.6 # 3 transformation
+            -0.15, 0.28, 0.26, 0.24, 0.0, 0.44 # 4 transformation
+            """;
+
+    validJuliaContent = """
+            Julia # Type of Transformation
+            -1.6, -1.0    # Min-coordinate
+            1.6, 1.0    # Max-coordinate
+            -0.70176, -0.3842 # Real and imaginary part of the complex number
+            """;
+
+    invalidNumbersContent = """
+            Affine2D # Type of Transformation
+            INVALID, 0.0 # Min-coordinate
+            2.65, 10.0 # Max-coordinate
+            0.0, 0.0, 0.0, WRONG, 0.0, 0.0 # 1 transformation
+            0.85, 0.04, -0.04, 0.85, 0.0, 1.6 # 2 transformation
+            0.2, WRONG, 0.23, 0.22, 0.0, 1.6 # 3 transformation
+            -0.15, 0.28, 0.26, 0.24ERROROOROR, 0.44 # 4 transformation
+            """;
+
+    invalidTypeContent = """
+            Unknown # Type of Transformation
+            -2.65, 0.0 # Min-coordinate
+            2.65, 10.0 # Max-coordinate
+            0.0, 0.0, 0.0, 0.16, 0.0, 0.0 # 1 transformation
+            0.85, 0.04, -0.04, 0.85, 0.0, 1.6 # 2 transformation
+            0.2, -0.26, 0.23, 0.22, 0.0, 1.6 # 3 transformation
+            -0.15, 0.28, 0.26, 0.24, 0.0, 0.44 # 4 transformation
+            """;
+
+  }
+
+  private Path createTempFileWithContent(String content) throws IOException {
+    Path tempFile = Files.createTempFile("chaosGame", ".txt");
+    try (BufferedWriter writer = Files.newBufferedWriter(tempFile)) {
+      writer.write(content);
+    }
+    return tempFile;
+  }
+
+  @Nested
+  class ReadFromFileTests {
+    @Test
+    void testReadValidAffine() throws IOException {
+      Path tempFile = createTempFileWithContent(validAffineContent);
+      ChaosGameDescription description = fileHandler.readFromFile(tempFile.toString());
+
+      Vector2D expectedMin = new Vector2D(-2.65, 0.0);
+      Vector2D expectedMax = new Vector2D(2.65, 10.0);
+      List<Transform2D> expectedTransforms = List.of(
+              new AffineTransform2D(new Matrix2x2(0.0, 0.0, 0.0, 0.16), new Vector2D(0.0, 0.0)),
+              new AffineTransform2D(new Matrix2x2(0.85, 0.04, -0.04, 0.85), new Vector2D(0.0, 1.6)),
+              new AffineTransform2D(new Matrix2x2(0.2, -0.26, 0.23, 0.22), new Vector2D(0.0, 1.6)),
+              new AffineTransform2D(new Matrix2x2(-0.15, 0.28, 0.26, 0.24), new Vector2D(0.0, 0.44))
+      );
+
+      assertEquals(expectedMin, description.getMinCoords());
+      assertEquals(expectedMax, description.getMaxCoords());
+      assertEquals(expectedTransforms, description.getTransforms());
+
+      Files.delete(tempFile);
+    }
+
+    @Test
+    void testReadValidJulia() throws IOException {
+      Path tempFile = createTempFileWithContent(validJuliaContent);
+      ChaosGameDescription description = fileHandler.readFromFile(tempFile.toString());
+
+      Vector2D expectedMin = new Vector2D(-1.6, -1.0);
+      Vector2D expectedMax = new Vector2D(1.6, 1.0);
+      List<Transform2D> expectedTransforms = List.of(
+              new JuliaTransform(new Complex(-0.70176, -0.3842), 1)
+      );
+
+      assertEquals(expectedMin, description.getMinCoords());
+      assertEquals(expectedMax, description.getMaxCoords());
+      assertEquals(expectedTransforms, description.getTransforms());
+
+      Files.delete(tempFile);
+    }
+
+    @Test
+    void testReadUnknownType() throws IOException {
+      Path tempFile = createTempFileWithContent(invalidTypeContent);
+      assertThrows(IllegalArgumentException.class,
+              () -> fileHandler.readFromFile(tempFile.toString()),
+              "Unknown type of transformation should throw IllegalArgumentException");
+
+      Files.delete(tempFile);
+    }
+
+    @Test
+    void testReadInvalidVector() throws IOException {
+      Path tempFile = createTempFileWithContent(invalidNumbersContent);
+      assertThrows(NumberFormatException.class, () -> fileHandler.readFromFile(tempFile.toString()),
+              "Invalid vector data should throw NumberFormatException");
+
+      Files.delete(tempFile);
+    }
+  }
+
+  @Nested
+  class WriteToFileTests {
+    @Test
+    void testWriteValidAffine() throws IOException {
+      ChaosGameDescription description = new ChaosGameDescription(
+              new Vector2D(-2.65, 0.0),
+              new Vector2D(2.65, 10.0),
+              List.of(
+                      new AffineTransform2D(new Matrix2x2(0.0, 0.0, 0.0, 0.16),
+                              new Vector2D(0.0, 0.0)),
+                      new AffineTransform2D(new Matrix2x2(0.85, 0.04, -0.04, 0.85),
+                              new Vector2D(0.0, 1.6)),
+                      new AffineTransform2D(new Matrix2x2(0.2, -0.26, 0.23, 0.22),
+                              new Vector2D(0.0, 1.6)),
+                      new AffineTransform2D(new Matrix2x2(-0.15, 0.28, 0.26, 0.24),
+                              new Vector2D(0.0, 0.44))
+              )
+      );
+
+      Path tempFile = Files.createTempFile("chaosGame", ".txt");
+      fileHandler.writeToFile(description, tempFile.toString());
+
+      String expectedContent =
+              """
+                      Affine2D    # Type of transformation
+                      -2.65, 0.0    # Min-coordinate
+                      2.65, 10.0    # Max-coordinate
+                      0.0, 0.0, 0.0, 0.16, 0.0, 0.0    # 1 transformation
+                      0.85, 0.04, -0.04, 0.85, 0.0, 1.6    # 2 transformation
+                      0.2, -0.26, 0.23, 0.22, 0.0, 1.6    # 3 transformation
+                      -0.15, 0.28, 0.26, 0.24, 0.0, 0.44    # 4 transformation
+                      """;
+
+      StringBuilder actualContent = new StringBuilder();
+      try (BufferedReader reader = Files.newBufferedReader(tempFile)) {
+        String line;
+        while ((line = reader.readLine()) != null) {
+          actualContent.append(line).append("\n");
+        }
+      }
+
+      assertEquals(expectedContent.trim(), actualContent.toString().trim());
+
+      Files.delete(tempFile);
+    }
+
+    @Test
+    void testWriteValidJulia() throws IOException {
+      ChaosGameDescription description = new ChaosGameDescription(
+              new Vector2D(-1.6, -1.0),
+              new Vector2D(1.6, 1.0),
+              List.of(new JuliaTransform(new Complex(-0.70176, -0.3842), 1))
+      );
+
+      Path tempFile = Files.createTempFile("chaosGame", ".txt");
+      fileHandler.writeToFile(description, tempFile.toString());
+
+      String expectedContent =
+              """
+                      Julia    # Type of transformation
+                      -1.6, -1.0    # Min-coordinate
+                      1.6, 1.0    # Max-coordinate
+                      -0.70176, -0.3842    # Real and imaginary part of the complex number
+                      """;
+
+      StringBuilder actualContent = new StringBuilder();
+      try (BufferedReader reader = Files.newBufferedReader(tempFile)) {
+        String line;
+        while ((line = reader.readLine()) != null) {
+          actualContent.append(line).append("\n");
+        }
+      }
+
+      assertEquals(expectedContent.trim(), actualContent.toString().trim());
+
+      Files.delete(tempFile);
+    }
+  }
+
+  @Nested
+  class SkipCommentsTests {
+    @Test
+    void testSkipCommentsWithComment() {
+      String line = "0.5, 0.0, 0.0, 0.5, 0.0, 0.0 # This is a comment";
+      String result = fileHandler.skipComments(line);
+      assertEquals("0.5, 0.0, 0.0, 0.5, 0.0, 0.0", result);
+    }
+
+    @Test
+    void testSkipCommentsWithoutComment() {
+      String line = "0.5, 0.0, 0.0, 0.5, 0.0, 0.0";
+      String result = fileHandler.skipComments(line);
+      assertEquals(line, result);
+    }
+
+    @Test
+    void testSkipCommentsEmptyLine() {
+      String line = "# This is a comment";
+      String result = fileHandler.skipComments(line);
+      assertEquals("", result);
+    }
+  }
+
+  @Nested
+  class SelectTransformationTests {
+    @Test
+    void testSelectAffineTransformation() {
+      String line = "0.5, 0.0, 0.0, 0.5, 0.0, 0.0";
+      Transform2D transform = fileHandler.selectTransformation("Affine2D", line);
+      assertInstanceOf(AffineTransform2D.class, transform);
+    }
+
+    @Test
+    void testSelectJuliaTransformation() {
+      String line = "-0.70176, -0.3842";
+      Transform2D transform = fileHandler.selectTransformation("Julia", line);
+      assertInstanceOf(JuliaTransform.class, transform);
+    }
+
+    @Test
+    void testSelectUnknownTransformation() {
+      String line = "0.5, 0.0, 0.0, 0.5, 0.0, 0.0";
+      assertThrows(IllegalArgumentException.class, () ->
+                      fileHandler.selectTransformation("Unknown", line),
+              "Unknown type of transformation should throw IllegalArgumentException");
+    }
+  }
+
+  @Nested
+  class ParseVectorTests {
+    @Test
+    void testParseValidVector() {
+      String line = "0.0, 1.0";
+      Vector2D vector = fileHandler.parseVector(line);
+      assertEquals(new Vector2D(0.0, 1.0), vector);
+    }
+
+    @Test
+    void testParseInvalidVector() {
+      String line = "invalid, data";
+      assertThrows(NumberFormatException.class, () -> fileHandler.parseVector(line));
+    }
+
+    @Test
+    void testParseVectorWithComments() {
+      String line = "0.0, 1.0 # Comment";
+      Vector2D vector = fileHandler.parseVector(line);
+      assertEquals(new Vector2D(0.0, 1.0), vector);
+    }
+  }
+
+  @Nested
+  class ParseAffineTests {
+    @Test
+    void testParseValidAffine() {
+      String line = "0.5, 0.0, 0.0, 0.5, 0.0, 0.0";
+      AffineTransform2D affine = (AffineTransform2D) fileHandler.parseAffine(line);
+      assertEquals(new Matrix2x2(0.5, 0.0, 0.0, 0.5), affine.matrix());
+      assertEquals(new Vector2D(0.0, 0.0), affine.vector());
+    }
+
+    @Test
+    void testParseInvalidAffine() {
+      String line = "invalid, data, 0.0, 0.5, 0.0, 0.0, invalid here too";
+      assertThrows(NumberFormatException.class, () -> fileHandler.parseAffine(line));
+    }
+
+    @Test
+    void testParseAffineWithComments() {
+      String line = "0.5, 0.0, 0.0, 0.5, 0.0, 0.0 # Comment";
+      AffineTransform2D affine = (AffineTransform2D) fileHandler.parseAffine(line);
+      assertEquals(new Matrix2x2(0.5, 0.0, 0.0, 0.5), affine.matrix());
+      assertEquals(new Vector2D(0.0, 0.0), affine.vector());
+    }
+  }
+
+  @Nested
+  class ParseJuliaTests {
+    @Test
+    void testParseValidJulia() {
+      String line = "-0.70176, -0.3842";
+      JuliaTransform julia = (JuliaTransform) fileHandler.parseJulia(line);
+      assertEquals(new Complex(-0.70176, -0.3842), julia.getComplex());
+    }
+
+    @Test
+    void testParseInvalidJulia() {
+      String line = "invalid, data";
+      assertThrows(NumberFormatException.class, () -> fileHandler.parseJulia(line));
+    }
+
+    @Test
+    void testParseJuliaWithComments() {
+      String line = "-0.70176, -0.3842 # Comment";
+      JuliaTransform julia = (JuliaTransform) fileHandler.parseJulia(line);
+      assertEquals(new Complex(-0.70176, -0.3842), julia.getComplex());
+    }
+  }
+
+  @AfterAll
+  static void tearDown() {
+    fileHandler = null;
+    validAffineContent = null;
+    validJuliaContent = null;
+    invalidNumbersContent = null;
+    invalidTypeContent = null;
+  }
+}
\ No newline at end of file
diff --git a/src/test/java/org/example/chaosgame/model/chaos/ChaosGameTest.java b/src/test/java/org/example/chaosgame/model/chaos/ChaosGameTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5d967a7f1718f0bdc92c934b2abb08212207de42
--- /dev/null
+++ b/src/test/java/org/example/chaosgame/model/chaos/ChaosGameTest.java
@@ -0,0 +1,216 @@
+package org.example.chaosgame.model.chaos;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.util.List;
+import org.example.chaosgame.controller.interfaces.Observer;
+import org.example.chaosgame.model.linalg.Complex;
+import org.example.chaosgame.model.linalg.Matrix2x2;
+import org.example.chaosgame.model.linalg.Vector2D;
+import org.example.chaosgame.model.transformations.AffineTransform2D;
+import org.example.chaosgame.model.transformations.JuliaTransform;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+class ChaosGameTest {
+  private static ChaosGameDescription juliaDescription;
+  private static ChaosGameDescription affineDescriptionWithProb;
+  private static ChaosGame instance;
+
+  @BeforeEach
+  void init() {
+    juliaDescription = new ChaosGameDescription(
+            new Vector2D(-1.6, -1),
+            new Vector2D(1.6, 1),
+            List.of(
+                    new JuliaTransform(new Complex(-0.70176, -0.3842), 1)
+            ));
+
+    affineDescriptionWithProb = new ChaosGameDescription(
+            new Vector2D(-2.65, 0.0),
+            new Vector2D(2.65, 10.0),
+            List.of(
+                    new AffineTransform2D(new Matrix2x2(0.0, 0.0, 0.0, 0.16),
+                            new Vector2D(0.0, 0.0)),
+                    new AffineTransform2D(new Matrix2x2(0.85, 0.04, -0.04, 0.85),
+                            new Vector2D(0.0, 1.60)),
+                    new AffineTransform2D(new Matrix2x2(0.20, -0.26, 0.23, 0.22),
+                            new Vector2D(0.0, 1.60)),
+                    new AffineTransform2D(new Matrix2x2(-0.15, 0.28, 0.26, 0.24),
+                            new Vector2D(0.0, 0.44))
+            ), List.of(2, 84, 7, 7));
+    instance = ChaosGame.getInstance(juliaDescription, 500, 500);
+    instance.setChaosGameDescription(juliaDescription);
+    instance.setSteps(0);
+    instance.setTotalSteps(0);
+  }
+
+  @Nested
+  class SingletonTests {
+    @Test
+    void testSingletonInstanceIsNull() {
+      assertNotNull(instance, "The singleton instance should not be null");
+    }
+
+    @Test
+    void testSingletonInstanceIsNotNull() {
+      ChaosGame instance2 = ChaosGame.getInstance(juliaDescription, 500, 500);
+      assertEquals(instance, instance2, "The singleton instance should be the same");
+    }
+  }
+
+
+  @Nested
+  class GetterTests {
+    @Test
+    void getCanvas() {
+      assertNotNull(instance.getCanvas(), "The canvas should not be null");
+    }
+
+    @Test
+    void getDescription() {
+      assertEquals(juliaDescription,
+              instance.getDescription(),
+              "The description should be the same");
+    }
+
+    @Test
+    void getSteps() {
+      assertEquals(0, instance.getSteps(), "The steps should be 0");
+    }
+
+    @Test
+    void getTotalSteps() {
+      assertEquals(0, instance.getTotalSteps(), "The total steps should be 0");
+    }
+  }
+
+  @Nested
+  class TestSteps {
+    @Test
+    void setSteps() {
+      instance.setSteps(10);
+      assertEquals(10, instance.getSteps(), "The steps should be 10");
+    }
+
+    @Test
+    void setStepsNegative() {
+      assertThrows(IllegalArgumentException.class, () -> instance.setSteps(-10),
+              "The steps should be positive");
+    }
+
+    @Test
+    void setStepsTooLarge() {
+      assertThrows(IllegalArgumentException.class, () -> instance.setSteps(1000001),
+              "The steps should be less than 1000000");
+    }
+
+    @Test
+    void setTotalSteps() {
+      instance.setTotalSteps(10);
+      assertEquals(10, instance.getTotalSteps(), "The total steps should be 10");
+    }
+
+    @Test
+    void addTotalStepsNegative() {
+      assertThrows(IllegalArgumentException.class, () -> instance.addTotalSteps(-10),
+              "The steps should be positive");
+    }
+
+    @Test
+    void addTotalSteps() {
+      instance.addTotalSteps(10);
+      instance.addTotalSteps(10);
+      assertEquals(20, instance.getTotalSteps(), "The total steps should be 10");
+    }
+
+    @Test
+    void resetTotalSteps() {
+      instance.addTotalSteps(10);
+      instance.resetTotalSteps();
+      assertEquals(0, instance.getTotalSteps(), "The total steps should be 0");
+    }
+
+    @Test
+    void runSteps() {
+      instance.setSteps(10);
+      instance.runSteps();
+      assertEquals(10, instance.getSteps(), "The total steps should be 10");
+    }
+
+    @Test
+    void runStepsUniform() {
+      instance = ChaosGame.getInstance(juliaDescription, 500, 500);
+      instance.setSteps(10);
+      assertEquals(10, instance.getSteps());
+    }
+
+    @Test
+    void runStepsWithProbabilities() {
+      instance.setChaosGameDescription(affineDescriptionWithProb);
+      instance.setSteps(10);
+      instance.runSteps();
+      assertEquals(10, instance.getSteps());
+    }
+  }
+
+  @Nested
+  class SetDescription {
+    @Test
+    void setChaosGameDescription() {
+      instance.setChaosGameDescription(affineDescriptionWithProb);
+      assertEquals(affineDescriptionWithProb, instance.getDescription(),
+              "The description should be the same");
+      assertEquals(0, instance.getTotalSteps(),
+              "The total steps should be 0");
+      assertEquals(500, instance.getCanvas().getWidth(),
+              "The width should be 500");
+      assertEquals(500, instance.getCanvas().getHeight(),
+              "The height should be 500");
+    }
+
+    @Test
+    void setChaosGameDescriptionNull() {
+      assertThrows(IllegalArgumentException.class, () -> instance.setChaosGameDescription(null),
+              "The description should not be null");
+    }
+  }
+
+  @Test
+  void setChaosCanvas() {
+    instance.setChaosCanvas(new Vector2D(-1.6, -1), new Vector2D(1.6, 1));
+    assertEquals(new Vector2D(-1.6, -1),
+            instance.getDescription().getMinCoords(),
+            "The min coords should be the same");
+    assertEquals(new Vector2D(1.6, 1),
+            instance.getDescription().getMaxCoords(),
+            "The max coords should be the same");
+  }
+
+  @Test
+  void registerAndNotifyObservers() {
+    Observer observer = () -> assertTrue(true, "Observer should be notified");
+    instance.registerObserver(observer);
+    instance.notifyObservers();
+  }
+
+  @Test
+  void removeObserver() {
+    Observer observer = () -> fail("Observer should not be notified");
+    instance.registerObserver(observer);
+    instance.removeObserver(observer);
+    instance.notifyObservers();
+  }
+
+  @AfterEach
+  void tearDown() {
+    instance = null;
+  }
+
+}
\ No newline at end of file
diff --git a/src/test/java/org/example/chaosgame/model/chaos/ExploreGameTest.java b/src/test/java/org/example/chaosgame/model/chaos/ExploreGameTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ab56bbba654425e121d2513449db4646e630adce
--- /dev/null
+++ b/src/test/java/org/example/chaosgame/model/chaos/ExploreGameTest.java
@@ -0,0 +1,115 @@
+package org.example.chaosgame.model.chaos;
+
+import org.example.chaosgame.model.linalg.Complex;
+import org.example.chaosgame.model.linalg.Vector2D;
+import org.example.chaosgame.model.transformations.ExploreJulia;
+import org.example.chaosgame.model.transformations.Transform2D;
+import org.example.chaosgame.controller.interfaces.Observer;
+import org.junit.jupiter.api.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class ExploreGameTest {
+  private ExploreGame exploreGame;
+  private ChaosGameDescription description;
+  private static final int WIDTH = 100;
+  private static final int HEIGHT = 100;
+  private List<Transform2D> transforms;
+
+  private ExploreJulia exploreJulia;
+  @BeforeEach
+  void setUp() {
+    Vector2D minCoords = new Vector2D(-1.6, -1);
+    Vector2D maxCoords = new Vector2D(1.6, 1);
+    transforms = new ArrayList<>();
+    exploreJulia = new ExploreJulia(new Complex(0, 1));
+    transforms.add(exploreJulia);
+    description = new ChaosGameDescription(minCoords, maxCoords, transforms);
+    exploreGame = new ExploreGame(description, WIDTH, HEIGHT);
+  }
+
+  @AfterEach
+  void tearDown() {
+    transforms = null;
+    exploreJulia = null;
+    exploreGame = null;
+    description = null;
+  }
+
+  @Test
+  void testSetExploreGame() {
+    Vector2D newMinCoords = new Vector2D(-1.6, -1);
+    Vector2D newMaxCoords = new Vector2D(1.6, 1);
+    List<Transform2D> newTransforms = new ArrayList<>();
+    newTransforms.add(new ExploreJulia(new Complex(1, 1)));
+    ChaosGameDescription newDescription = new ChaosGameDescription(newMinCoords, newMaxCoords, newTransforms);
+
+    exploreGame.setExploreGame(newDescription, 200, 200);
+
+    assertEquals(newDescription, exploreGame.getDescription());
+    ChaosCanvas canvas = exploreGame.getCanvas();
+    assertEquals(200, canvas.getWidth());
+    assertEquals(200, canvas.getHeight());
+    assertEquals(newMinCoords, canvas.getMinCoords());
+    assertEquals(newMaxCoords, canvas.getMaxCoords());
+  }
+
+  @Test
+  void testGetCanvas() {
+    ChaosCanvas canvas = exploreGame.getCanvas();
+    assertNotNull(canvas);
+    assertEquals(WIDTH, canvas.getWidth());
+    assertEquals(HEIGHT, canvas.getHeight());
+  }
+
+  @Test
+  void testGetDescription() {
+    assertEquals(description, exploreGame.getDescription());
+  }
+
+  @Test
+  void testSetChaosCanvas() {
+    Vector2D newMinCoords = new Vector2D(-2, -2);
+    Vector2D newMaxCoords = new Vector2D(2, 2);
+    exploreGame.setChaosCanvas(newMinCoords, newMaxCoords, 300, 300);
+
+    ChaosCanvas canvas = exploreGame.getCanvas();
+    assertEquals(300, canvas.getWidth());
+    assertEquals(300, canvas.getHeight());
+    assertEquals(newMinCoords, canvas.getMinCoords());
+    assertEquals(newMaxCoords, canvas.getMaxCoords());
+  }
+
+  @Test
+  void testExploreFractals() {
+
+    exploreGame.exploreFractals();
+
+    ChaosCanvas canvas = exploreGame.getCanvas();
+    for (int i = 0; i < canvas.getHeight(); i++) {
+      for (int j = 0; j < canvas.getWidth(); j++) {
+        assertTrue(canvas.getPixel(new Vector2D(i, j)) >= 0);
+      }
+    }
+  }
+
+  @Test
+  void testRemoveObserver() {
+    Observer observer = () -> fail("Observer should not be notified");
+    exploreGame.registerObserver(observer);
+    exploreGame.removeObserver(observer);
+//    exploreGame.notifyObservers();
+  }
+
+  @Test
+  void testRegisterAndNotifyObservers() {
+    Observer observer1 = () -> assertTrue(true,"Observer should be notified");
+    Observer observer2 = () -> assertTrue(true,"Observer should be notified");
+    exploreGame.registerObserver(observer1);
+    exploreGame.registerObserver(observer2);
+    exploreGame.notifyObservers();
+  }
+}
diff --git a/src/test/java/org/example/chaosgame/linalg/ComplexTest.java b/src/test/java/org/example/chaosgame/model/linalg/ComplexTest.java
similarity index 71%
rename from src/test/java/org/example/chaosgame/linalg/ComplexTest.java
rename to src/test/java/org/example/chaosgame/model/linalg/ComplexTest.java
index 6297a60712700134098be00b67f63ff35c708808..5cb701a87fba88d8556f81947b3abaa1fb582555 100644
--- a/src/test/java/org/example/chaosgame/linalg/ComplexTest.java
+++ b/src/test/java/org/example/chaosgame/model/linalg/ComplexTest.java
@@ -1,4 +1,4 @@
-package org.example.chaosgame.linalg;
+package org.example.chaosgame.model.linalg;
 
 import org.example.chaosgame.model.linalg.Complex;
 import org.junit.jupiter.api.*;
@@ -30,8 +30,8 @@ class ComplexTest {
     @DisplayName("Test sqrt should work")
     void sqrt() {
       Complex newComplex = complex.sqrt(x, y);
-      assertEquals(0.5061178531536732, newComplex.getX()); //r-part is based on the example in the task description.
-      assertEquals(-0.3951648786024424, newComplex.getY()); //i-part is based on the example in the task description.
+      assertEquals(Math.abs(0.5061178531536732), Math.abs(newComplex.getX())); //r-part is based on the example in the task description.
+      assertEquals(Math.abs(-0.3951648786024424), Math.abs(newComplex.getY())); //i-part is based on the example in the task description.
     }
 
     @Test
diff --git a/src/test/java/org/example/chaosgame/linalg/Matrix2x2Test.java b/src/test/java/org/example/chaosgame/model/linalg/Matrix2x2Test.java
similarity index 97%
rename from src/test/java/org/example/chaosgame/linalg/Matrix2x2Test.java
rename to src/test/java/org/example/chaosgame/model/linalg/Matrix2x2Test.java
index 11ea00fbe6b85631de2e220b425df2ce2aa969f7..bb210cb61a55047bdd3e67f1d9deb27190bd0a40 100644
--- a/src/test/java/org/example/chaosgame/linalg/Matrix2x2Test.java
+++ b/src/test/java/org/example/chaosgame/model/linalg/Matrix2x2Test.java
@@ -1,4 +1,4 @@
-package org.example.chaosgame.linalg;
+package org.example.chaosgame.model.linalg;
 
 import org.example.chaosgame.model.linalg.Matrix2x2;
 import org.example.chaosgame.model.linalg.Vector2D;
diff --git a/src/test/java/org/example/chaosgame/model/linalg/Vector2DTest.java b/src/test/java/org/example/chaosgame/model/linalg/Vector2DTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..3d432956948a6ea1985ddd1c3c3e02d6d9fd85a2
--- /dev/null
+++ b/src/test/java/org/example/chaosgame/model/linalg/Vector2DTest.java
@@ -0,0 +1,149 @@
+package org.example.chaosgame.model.linalg;
+
+import org.example.chaosgame.model.linalg.Vector2D;
+import org.junit.jupiter.api.*;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class Vector2DTest {
+  private double x;
+  private double y;
+  private Vector2D vector;
+  private Vector2D otherVector;
+
+  @BeforeEach
+  void setUp() {
+    x = 1.0;
+    y = 2.0;
+    vector = new Vector2D(x, y);
+    otherVector = new Vector2D(1.0, 1.0);
+  }
+
+  @AfterEach
+  void tearDown() {
+    vector = null;
+    otherVector = null;
+  }
+
+  @Nested
+  @DisplayName("Test getX and getY")
+  class TestGetters {
+    @Test
+    @DisplayName("Test getX")
+    void getX() {
+      assertEquals(x, vector.getX());
+    }
+
+    @Test
+    @DisplayName("Test getY")
+    void getY() {
+      assertEquals(y, vector.getY());
+    }
+  }
+
+  @Nested
+  @DisplayName("Test add and subtract")
+  class TestAddAndSubtract {
+    @Test
+    @DisplayName("Test add should work")
+    void add() {
+      Vector2D w = vector.add(otherVector);
+      assertEquals(2.0, w.getX());
+      assertEquals(3.0, w.getY());
+    }
+
+    @Test
+    @DisplayName("Test add should not work")
+    void addFail() {
+      Vector2D w = vector.add(otherVector);
+      assertNotEquals(1.0, w.getX());
+      assertNotEquals(2.0, w.getY());
+    }
+
+    @Test
+    @DisplayName("Test subtract should work")
+    void subtract() {
+      Vector2D w = vector.subtract(otherVector);
+      assertEquals(0.0, w.getX());
+      assertEquals(1.0, w.getY());
+    }
+
+    @Test
+    @DisplayName("Test subtract should not work")
+    void subtractFail() {
+      Vector2D w = vector.subtract(otherVector);
+      assertNotEquals(1.0, w.getX());
+      assertNotEquals(2.0, w.getY());
+    }
+  }
+
+  @Nested
+  @DisplayName("Test scale and multiply")
+  class TestScaleAndMultiply {
+    @Test
+    @DisplayName("Test scale should work")
+    void scale() {
+      Vector2D w = vector.scale(2.0);
+      assertEquals(2.0, w.getX());
+      assertEquals(4.0, w.getY());
+    }
+
+    @Test
+    @DisplayName("Test scale should not work")
+    void scaleFail() {
+      Vector2D w = vector.scale(2.0);
+      assertNotEquals(1.0, w.getX());
+      assertNotEquals(2.0, w.getY());
+    }
+
+    @Test
+    @DisplayName("Test multiply should work")
+    void multiply() {
+      Vector2D w = vector.multiply(otherVector);
+      assertEquals(1.0, w.getX());
+      assertEquals(2.0, w.getY());
+    }
+
+    @Test
+    @DisplayName("Test multiply should not work")
+    void multiplyFail() {
+      Vector2D w = vector.multiply(otherVector);
+      assertNotEquals(2.0, w.getX());
+      assertNotEquals(4.0, w.getY());
+    }
+  }
+
+  @Nested
+  @DisplayName("Test divide and length")
+  class TestDivide {
+    @Test
+    @DisplayName("Test divide should work")
+    void divide() {
+      Vector2D w = vector.divide(otherVector);
+      assertEquals(1.0, w.getX());
+      assertEquals(2.0, w.getY());
+    }
+
+    @Test
+    @DisplayName("Test divide should not work")
+    void divideFail() {
+      Vector2D w = vector.divide(otherVector);
+      assertNotEquals(2.0, w.getX());
+      assertNotEquals(4.0, w.getY());
+    }
+
+    @Test
+    @DisplayName("Test length should work")
+    void length() {
+      double l = vector.lengthSq();
+      assertEquals(5.0, l);
+    }
+
+    @Test
+    @DisplayName("Test length should not work")
+    void lengthFail() {
+      double l = vector.lengthSq();
+      assertNotEquals(2.0, l);
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/test/java/org/example/chaosgame/transformations/AffineTransform2DTest.java b/src/test/java/org/example/chaosgame/model/transformations/AffineTransform2DTest.java
similarity index 92%
rename from src/test/java/org/example/chaosgame/transformations/AffineTransform2DTest.java
rename to src/test/java/org/example/chaosgame/model/transformations/AffineTransform2DTest.java
index e19e189d0382ffc5d6d5feac9755bb58b9826600..3ac169cfe2adc38c08c7f344a1d8fad92fb9248b 100644
--- a/src/test/java/org/example/chaosgame/transformations/AffineTransform2DTest.java
+++ b/src/test/java/org/example/chaosgame/model/transformations/AffineTransform2DTest.java
@@ -1,4 +1,4 @@
-package org.example.chaosgame.transformations;
+package org.example.chaosgame.model.transformations;
 
 import org.example.chaosgame.model.linalg.Matrix2x2;
 import org.example.chaosgame.model.linalg.Vector2D;
diff --git a/src/test/java/org/example/chaosgame/model/transformations/ExploreJuliaTest.java b/src/test/java/org/example/chaosgame/model/transformations/ExploreJuliaTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..55900355656ec5fd5f0d02927ff67eb57adb5392
--- /dev/null
+++ b/src/test/java/org/example/chaosgame/model/transformations/ExploreJuliaTest.java
@@ -0,0 +1,48 @@
+package org.example.chaosgame.model.transformations;
+
+import org.example.chaosgame.model.linalg.Complex;
+import org.example.chaosgame.model.linalg.Vector2D;
+import org.junit.jupiter.api.*;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class ExploreJuliaTest {
+  private ExploreJulia exploreJulia;
+  private Complex complexPoint;
+
+  @BeforeEach
+  void setUp() {
+    complexPoint = new Complex(0.355, 0.355);
+    exploreJulia = new ExploreJulia(complexPoint);
+  }
+
+  @AfterEach
+  void tearDown() {
+    complexPoint = null;
+    exploreJulia = null;
+  }
+
+  @Test
+  void testGetComplex() {
+    assertEquals(complexPoint, exploreJulia.getComplex());
+  }
+  @Nested
+  @DisplayName("Test transforms")
+  class TestTransforms {
+    @Test
+    @DisplayName("Test positive transform")
+    void testTransform() {
+      Vector2D point = new Vector2D(0.5, 0.5);
+      Vector2D transformedPoint = exploreJulia.transform(point);
+      assertEquals(new Vector2D(0.355, 0.855), transformedPoint);
+    }
+
+    @Test
+    @DisplayName("Test negative transform")
+    void testTransformFail() {
+      Vector2D point = new Vector2D(-0.5, -0.5);
+      Vector2D transformedPoint = exploreJulia.transform(point);
+      assertNotEquals(new Vector2D(0.355, -0.145), transformedPoint);
+    }
+  }
+}
diff --git a/src/test/java/org/example/chaosgame/transformations/JuliaTransformTest.java b/src/test/java/org/example/chaosgame/model/transformations/JuliaTransformTest.java
similarity index 73%
rename from src/test/java/org/example/chaosgame/transformations/JuliaTransformTest.java
rename to src/test/java/org/example/chaosgame/model/transformations/JuliaTransformTest.java
index f1807cd770b536a5a45f7fda20c18377d451ed0d..ef90b6a8acdb156d34e38aa36f7cd84f88f5257b 100644
--- a/src/test/java/org/example/chaosgame/transformations/JuliaTransformTest.java
+++ b/src/test/java/org/example/chaosgame/model/transformations/JuliaTransformTest.java
@@ -1,4 +1,4 @@
-package org.example.chaosgame.transformations;
+package org.example.chaosgame.model.transformations;
 
 import org.example.chaosgame.model.linalg.Complex;
 import org.example.chaosgame.model.linalg.Vector2D;
@@ -15,8 +15,7 @@ class JuliaTransformTest {
   @Test
   void transform() {
     Vector2D testJulia = juliaTransform.transform(new Vector2D(0.4, 0.2));
-    assertEquals(0.5061178531536732, testJulia.getX());
-    assertEquals(-0.3951648786024423, testJulia.getY());
-
+    assertEquals(Math.abs(0.5061178531536732), Math.abs(testJulia.getX()));
+    assertEquals(Math.abs(-0.3951648786024423), Math.abs(testJulia.getY()));
   }
 }
\ No newline at end of file