diff --git a/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/chelseaogbonnia/Bookshelf/Book.java b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/chelseaogbonnia/Bookshelf/Book.java new file mode 100644 index 000000000..2e7788db4 --- /dev/null +++ b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/chelseaogbonnia/Bookshelf/Book.java @@ -0,0 +1,53 @@ +package com.codedifferently.lesson16.chelseaogbonnia.bookshelf; + +enum Genre { + FICTION, + NON_FICTION, + MYSTERY, + SCIENCE_FICTION, + FANTASY, + HORROR, + ROMANCE, + ADVENTURE, + HISTORY, + CRIME +} + +enum BookType { + HARDCOVER, + PAPERBACK, + MAGAZINE, + NOVEL, + POEM, + COMICS +} + +public class Book { + private String title; + private String author; + private Genre genre; + private BookType bookType; + + public Book(String title, String author, Genre genre, BookType bookType) { + this.title = title; + this.author = author; + this.genre = genre; + this.bookType = bookType; + } + + public String getTitle() { + return title; + } + + public String getAuthor() { + return author; + } + + public Genre getGenre() { + return genre; + } + + public BookType getBookType() { + return bookType; + } +} diff --git a/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/chelseaogbonnia/Bookshelf/Bookshelf.java b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/chelseaogbonnia/Bookshelf/Bookshelf.java new file mode 100644 index 000000000..ac0381ddd --- /dev/null +++ b/lesson_16/objects/objects_app/src/main/java/com/codedifferently/lesson16/chelseaogbonnia/Bookshelf/Bookshelf.java @@ -0,0 +1,80 @@ +package com.codedifferently.lesson16.chelseaogbonnia.bookshelf; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +class BookNotFoundException extends Exception { + public BookNotFoundException(String message) { + super(message); + } +} + +public class Bookshelf { + private String owner; + private int capacity; + private List books; + private HashMap bookMap; + private boolean isPublic; + + public Bookshelf(String owner, int capacity, boolean isPublic) { + this.owner = owner; + this.capacity = capacity; + this.isPublic = isPublic; + this.books = new ArrayList<>(); + this.bookMap = new HashMap<>(); + } + + public List listBooks() { + return Collections.unmodifiableList(books); + } + + public void addBook(Book book) throws Exception { + if (books.size() >= capacity) { + throw new Exception("Bookshelf is full. Cannot add more books."); + } + books.add(book); + bookMap.put(book.getTitle(), book); + } + + public Book findBook(String title) throws BookNotFoundException { + if (bookMap.containsKey(title)) { + return bookMap.get(title); + } + throw new BookNotFoundException("Book titled \"" + title + "\" not found."); + } + + public boolean hasBook(String title) { + return bookMap.containsKey(title); + } + + public int countBooksByGenre(Genre genre) { + int count = 0; + for (Book book : books) { + if (book.getGenre() == genre) { + count++; + } + } + return count; + } + + public String getOwner() { + return owner; + } + + public boolean isPublic() { + return isPublic; + } + + @Override + public String toString() { + return "Bookshelf owned by " + + owner + + " with capacity " + + capacity + + " (Public: " + + isPublic + + ")"; + } +} diff --git a/lesson_16/objects/objects_app/src/test/java/com/codedifferently/lesson16/chelseaogbonnia/Bookshelf/BookshelfTest.java b/lesson_16/objects/objects_app/src/test/java/com/codedifferently/lesson16/chelseaogbonnia/Bookshelf/BookshelfTest.java new file mode 100644 index 000000000..b903bcde2 --- /dev/null +++ b/lesson_16/objects/objects_app/src/test/java/com/codedifferently/lesson16/chelseaogbonnia/Bookshelf/BookshelfTest.java @@ -0,0 +1,130 @@ +package com.codedifferently.lesson16.chelseaogbonnia.bookshelf; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class BookshelfTest { + private Bookshelf bookshelf; + + @BeforeEach + public void setUp() { + bookshelf = new Bookshelf("Chelsea", 10, true); + } + + @Test + public void testAddBook() throws Exception { + // Arrange + Book book = new Book("Frankenstein", "Mary Shelly", Genre.HORROR, BookType.NOVEL); + + // Act + bookshelf.addBook(book); + + // Assert + assertTrue(bookshelf.hasBook("Frankenstein")); + } + + @Test + public void testFindBookExists() throws Exception { + // Arrange + Book book = + new Book("Brave New World", "Aldous Huxley", Genre.SCIENCE_FICTION, BookType.PAPERBACK); + bookshelf.addBook(book); + + // Act + Book foundBook = bookshelf.findBook("Brave New World"); + + // Assert + assertEquals(book, foundBook); + } + + @Test + public void testFindBookNotExists() { + // Arrange + String nonExistentBookTitle = "Non-Existent Book"; + + // Act & Assert + Exception exception = + assertThrows( + BookNotFoundException.class, + () -> { + bookshelf.findBook(nonExistentBookTitle); + }); + assertEquals("Book titled \"" + nonExistentBookTitle + "\" not found.", exception.getMessage()); + } + + @Test + public void testCountBooksByGenre() throws Exception { + // Arrange + bookshelf.addBook(new Book("The Hobbit", "J.R.R. Tolkien", Genre.FANTASY, BookType.HARDCOVER)); + bookshelf.addBook(new Book("Dune", "Frank Herbert", Genre.SCIENCE_FICTION, BookType.HARDCOVER)); + + // Act & Assert + assertEquals(1, bookshelf.countBooksByGenre(Genre.SCIENCE_FICTION)); + assertEquals(1, bookshelf.countBooksByGenre(Genre.FANTASY)); + } + + @Test + public void testAddBookToFullShelf() throws Exception { + // Arrange + for (int i = 0; i < 10; i++) { + bookshelf.addBook(new Book("Book " + i, "Author " + i, Genre.FICTION, BookType.PAPERBACK)); + } + Book extraBook = new Book("Extra Book", "Author Extra", Genre.FICTION, BookType.HARDCOVER); + + // Act & Assert + Exception exception = + assertThrows( + Exception.class, + () -> { + bookshelf.addBook(extraBook); + }); + assertEquals("Bookshelf is full. Cannot add more books.", exception.getMessage()); + } + + @Test + public void testCountBooksByGenreNoBooks() { + // Arrange + Genre genreToCheck = Genre.ADVENTURE; + + // Act & Assert + assertEquals(0, bookshelf.countBooksByGenre(genreToCheck)); + } + + @Test + public void testListBooks() throws Exception { + // Arrange + bookshelf.addBook( + new Book("The Adventures of Tintin", "Hergé", Genre.ADVENTURE, BookType.COMICS)); + bookshelf.addBook(new Book("The Big Sleep", "Raymond Chandler", Genre.CRIME, BookType.NOVEL)); + bookshelf.addBook( + new Book("Don Quixote", "Miguel de Cervantes", Genre.ADVENTURE, BookType.NOVEL)); + bookshelf.addBook(new Book("Sonnet 18", "William Shakespeare", Genre.ROMANCE, BookType.POEM)); + + // Act + int bookCount = bookshelf.listBooks().size(); + + // Assert + assertEquals(4, bookCount); + } + + @Test + public void checksMagazineBooks() throws Exception { + // Arrange + Book magazine = + new Book("National Geographic", "Various", Genre.NON_FICTION, BookType.MAGAZINE); + bookshelf.addBook(magazine); + + // Act + boolean hasMagazine = bookshelf.hasBook("National Geographic"); + int magazineCount = bookshelf.countBooksByGenre(Genre.NON_FICTION); + + // Assert + assertTrue(hasMagazine, "Bookshelf should contain the magazine 'National Geographic'."); + assertEquals( + 1, magazineCount, "There should be 1 magazine in the bookshelf under NON_FICTION."); + } +}