diff --git a/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/taliacrockett/Anime.java b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/taliacrockett/Anime.java new file mode 100644 index 000000000..500ae8c08 --- /dev/null +++ b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/taliacrockett/Anime.java @@ -0,0 +1,148 @@ +package com.codedifferently.lesson16.taliacrockett; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents an anime with various properties and behaviors. This class meets the assignment + * requirements for a custom data type. + */ +public class Anime { + private String title; + private int episodes; + private double rating; + private boolean isCompleted; + private List characters; + private AnimeGenre genre; + private String studio; + + // Constructor + public Anime(String title, int episodes, double rating, AnimeGenre genre, String studio) { + this.title = title; + this.episodes = episodes; + this.rating = rating; + this.genre = genre; + this.studio = studio; + this.isCompleted = false; + this.characters = new ArrayList<>(); + } + + // Member functions (3+ functions required) + + public Anime(String title, AnimeGenre genre, double rating) { + this.title = title; + this.episodes = 0; // Default value + this.rating = rating; + this.genre = genre; + this.studio = ""; // Default value + this.isCompleted = false; + this.characters = new ArrayList<>(); + } + + /** + * Function 1: Uses conditional expression Determines if the anime is worth watching based on + * rating + */ + public String getRecommendation() { + return rating >= 8.0 + ? "Highly Recommended!" + : rating >= 6.0 ? "Worth Watching" : "Skip This One"; + } + + /** Function 2: Uses collection member variable Adds a character to the anime's character list */ + public void addCharacter(String characterName) { + if (characterName != null && !characterName.trim().isEmpty()) { + characters.add(characterName); + } + } + + /** Function 3: Uses a loop Searches for a character in the character list */ + public boolean hasCharacter(String characterName) { + for (String character : characters) { + if (character.equalsIgnoreCase(characterName)) { + return true; + } + } + return false; + } + + /** + * Additional function: Uses collection and conditional Gets character count with status message + */ + public String getCharacterSummary() { + return "Characters: " + String.join(", ", characters); + } + + // Getters and Setters + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public int getEpisodes() { + return episodes; + } + + public void setEpisodes(int episodes) { + this.episodes = episodes; + } + + public double getRating() { + return rating; + } + + public void setRating(double rating) { + this.rating = rating; + } + + public boolean isCompleted() { + return isCompleted; + } + + public void setCompleted(boolean completed) { + isCompleted = completed; + } + + public List getCharacters() { + return new ArrayList<>(characters); // Return defensive copy + } + + public AnimeGenre getGenre() { + return genre; + } + + public void setGenre(AnimeGenre genre) { + this.genre = genre; + } + + public String getStudio() { + return studio; + } + + public void setStudio(String studio) { + this.studio = studio; + } + + @Override + public String toString() { + return String.format( + "Anime{title='%s', episodes=%d, rating=%.1f, genre=%s, studio='%s', completed=%s}", + title, episodes, rating, genre, studio, isCompleted); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + Anime anime = (Anime) obj; + return title != null ? title.equals(anime.title) : anime.title == null; + } + + @Override + public int hashCode() { + return title != null ? title.hashCode() : 0; + } +} diff --git a/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/taliacrockett/AnimeGenre.java b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/taliacrockett/AnimeGenre.java new file mode 100644 index 000000000..df66e4535 --- /dev/null +++ b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/taliacrockett/AnimeGenre.java @@ -0,0 +1,37 @@ +package com.codedifferently.lesson16.taliacrockett; + +public enum AnimeGenre { + SHONEN("Shonen"), + SHOUJO("Shoujo"), + SEINEN("Seinen"), + JOSEI("Josei"), + ISEKAI("Isekai"), + MECHA("Mecha"), + SLICE_OF_LIFE("Slice of Life"), + ROMANCE("Romance"), + ACTION("Action"), + COMEDY("Comedy"), + DRAMA("Drama"), + FANTASY("Fantasy"), + SUPERNATURAL("Supernatural"), + THRILLER("Thriller"), + HORROR("Horror"); + + public String displayName; + + AnimeGenre(String displayName) { + this.displayName = displayName; + } + + public String getDisplayName() { + if (displayName == null) { + return "Unknown Genre"; + } + return displayName; + } + + @Override + public String toString() { + return displayName; + } +} diff --git a/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/taliacrockett/AnimeNotFoundException.java b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/taliacrockett/AnimeNotFoundException.java new file mode 100644 index 000000000..96d7d0cb2 --- /dev/null +++ b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/taliacrockett/AnimeNotFoundException.java @@ -0,0 +1,8 @@ +package com.codedifferently.lesson16.taliacrockett; + +/** Custom exception thrown when an anime is not found in the collection. */ +public class AnimeNotFoundException extends Exception { + public AnimeNotFoundException(String message) { + super(message); + } +} diff --git a/lesson_16/objects/objects_app/src/test/java/com/codedifferently/lesson16/taliacrockett/AnimeGenreTest.java b/lesson_16/objects/objects_app/src/test/java/com/codedifferently/lesson16/taliacrockett/AnimeGenreTest.java new file mode 100644 index 000000000..bef22221c --- /dev/null +++ b/lesson_16/objects/objects_app/src/test/java/com/codedifferently/lesson16/taliacrockett/AnimeGenreTest.java @@ -0,0 +1,19 @@ +package com.codedifferently.lesson16.taliacrockett; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class AnimeGenreTest { + @Test + public void testDisplayName() { + AnimeGenre genre = AnimeGenre.SHONEN; + assertEquals("Shonen", genre.getDisplayName()); + } + + @Test + public void testToString() { + AnimeGenre genre = AnimeGenre.FANTASY; + assertEquals("Fantasy", genre.toString()); + } +} diff --git a/lesson_16/objects/objects_app/src/test/java/com/codedifferently/lesson16/taliacrockett/AnimeTest.java b/lesson_16/objects/objects_app/src/test/java/com/codedifferently/lesson16/taliacrockett/AnimeTest.java new file mode 100644 index 000000000..3ea7d28f1 --- /dev/null +++ b/lesson_16/objects/objects_app/src/test/java/com/codedifferently/lesson16/taliacrockett/AnimeTest.java @@ -0,0 +1,168 @@ +package com.codedifferently.lesson16.taliacrockett; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +public class AnimeTest { + // Test methods for Anime class + @Test + public void testGetRecommendation() { + Anime anime1 = new Anime("Test Anime 1", 12, 8.5, AnimeGenre.SHONEN, "Studio A"); + assertEquals("Highly Recommended!", anime1.getRecommendation()); + + Anime anime2 = new Anime("Test Anime 2", 24, 7.0, AnimeGenre.SHOUJO, "Studio B"); + assertEquals("Worth Watching", anime2.getRecommendation()); + + Anime anime3 = new Anime("Test Anime 3", 10, 5.5, AnimeGenre.ACTION, "Studio C"); + assertEquals("Skip This One", anime3.getRecommendation()); + } + + @Test + public void testAddCharacter() { + Anime anime = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + anime.addCharacter("Character A"); + anime.addCharacter("Character B"); + + assertTrue(anime.hasCharacter("Character A")); + assertTrue(anime.hasCharacter("Character B")); + assertFalse(anime.hasCharacter("Character C")); + } + + @Test + public void testHasCharacter() { + Anime anime = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + anime.addCharacter("Character A"); + assertTrue(anime.hasCharacter("Character A")); + assertFalse(anime.hasCharacter("Character B")); + } + + @Test + public void testGetCharacterSummary() { + Anime anime = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + anime.addCharacter("Character A"); + anime.addCharacter("Character B"); + String summary = anime.getCharacterSummary(); + assertEquals("Characters: Character A, Character B", summary); + } + + @Test + public void testGetTitle() { + Anime anime = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + assertEquals("Test Anime", anime.getTitle()); + } + + @Test + public void testSetTitle() { + Anime anime = new Anime("Old Title", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + anime.setTitle("New Title"); + assertEquals("New Title", anime.getTitle()); + } + + @Test + public void testGetEpisodes() { + Anime anime = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + assertEquals(12, anime.getEpisodes()); + } + + @Test + public void testSetEpisodes() { + Anime anime = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + anime.setEpisodes(24); + assertEquals(24, anime.getEpisodes()); + } + + @Test + public void testGetRating() { + Anime anime = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + assertEquals(8.0, anime.getRating()); + } + + @Test + public void testSetRating() { + Anime anime = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + anime.setRating(9.5); + assertEquals(9.5, anime.getRating()); + } + + @Test + public void testIsCompleted() { + Anime anime = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + assertFalse(anime.isCompleted()); + anime.setCompleted(true); + assertTrue(anime.isCompleted()); + } + + @Test + public void testSetCompleted() { + Anime anime = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + anime.setCompleted(true); + assertTrue(anime.isCompleted()); + anime.setCompleted(false); + assertFalse(anime.isCompleted()); + } + + @Test + public void testGetCharacters() { + Anime anime = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + anime.addCharacter("Character A"); + anime.addCharacter("Character B"); + assertEquals(2, anime.getCharacters().size()); + assertTrue(anime.getCharacters().contains("Character A")); + assertTrue(anime.getCharacters().contains("Character B")); + } + + @Test + public void testGetGenre() { + Anime anime = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + assertEquals(AnimeGenre.FANTASY, anime.getGenre()); + } + + @Test + public void testSetGenre() { + Anime anime = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + anime.setGenre(AnimeGenre.HORROR); + assertEquals(AnimeGenre.HORROR, anime.getGenre()); + } + + @Test + public void testGetStudio() { + Anime anime = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + assertEquals("Studio D", anime.getStudio()); + } + + @Test + public void testSetStudio() { + Anime anime = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + anime.setStudio("Studio E"); + assertEquals("Studio E", anime.getStudio()); + } + + @Test + public void testToString() { + Anime anime = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + String expected = + "Anime{title='Test Anime', episodes=12, rating=8.0, genre=Fantasy, studio='Studio D', completed=false}"; + assertEquals(expected, anime.toString()); + } + + @Test + public void testEquals() { + Anime anime1 = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + Anime anime2 = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + Anime anime3 = new Anime("Different Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + assertEquals(anime1, anime2); + assertNotEquals(anime1, anime3); + assertNotEquals(anime1, null); + assertNotEquals(anime1, "Some String"); + } + + @Test + public void testHashCode() { + Anime anime1 = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + Anime anime2 = new Anime("Test Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + assertEquals(anime1.hashCode(), anime2.hashCode()); + Anime anime3 = new Anime("Different Anime", 12, 8.0, AnimeGenre.FANTASY, "Studio D"); + assertNotEquals(anime1.hashCode(), anime3.hashCode()); + } +}