From 6227b0609f042e90317d6214bc7c3915714cb352 Mon Sep 17 00:00:00 2001 From: Shaili Sinha Date: Wed, 10 Dec 2025 23:22:04 -0500 Subject: [PATCH] 12/10 edits --- CHANGELOG.md | 36 +++ .../06-component-finishing-touches.md | 47 ++-- src/BookTracker.java | 205 ------------------ src/BookTrackerDemo | 44 ++++ src/LibraryDemo | 46 ++++ .../booktracker}/BookTracker1L.java | 0 .../booktracker}/BookTrackerSecondary.java | 21 -- .../booktracker/BookTracker1LTest.java | 192 ++++++++++++++++ .../booktracker/BookTrackerTest.java | 130 +++++++++++ 9 files changed, 471 insertions(+), 250 deletions(-) delete mode 100644 src/BookTracker.java create mode 100644 src/BookTrackerDemo create mode 100644 src/LibraryDemo rename src/{ => components/booktracker}/BookTracker1L.java (100%) rename src/{ => components/booktracker}/BookTrackerSecondary.java (87%) create mode 100644 test/components/booktracker/BookTracker1LTest.java create mode 100644 test/components/booktracker/BookTrackerTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ec7244..ad178d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,42 @@ the following form: YYYY.0M.0D. ## [Unreleased] +## [2025.12.10] + +### Added + +- Designed test suite for BookTracker component +- Designed two different use cases for BookTracker component + +### Updated + +- Changed design to include test cases for JUnit +- Changed design to include use cases in src +- Updated part 6 in doc and added to reflection questions + +## [2025.12.01] + +### Added + +- Designed kernel implementation for BookTracker component + +### Updated + +- Changed ChangeLog to have new additions +- Changed design to include the hasAuthor kernel method now + +# [2025.11.21] + +### Added + +- Designed abstract class for BookTracker component and created BookTrackerSecondary + +### Updated + +- Changed design to include hasAuthor as a kernel method +- Edited Component Brainstorming for resubmission +- Updated Changelog to have new additions + ## [2025.10.23] ### Added diff --git a/doc/06-component-finishing-touches/06-component-finishing-touches.md b/doc/06-component-finishing-touches/06-component-finishing-touches.md index 4a2aeda..034d8fe 100644 --- a/doc/06-component-finishing-touches/06-component-finishing-touches.md +++ b/doc/06-component-finishing-touches/06-component-finishing-touches.md @@ -1,8 +1,8 @@ # Portfolio Part 6: Finishing Touches -- **Name**: -- **Dot Number**: -- **Due Date**: +- **Name**: Shaili Sinha +- **Dot Number**: sinha.303 +- **Due Date**: 12/10 @ 11:59 PM EST ## Assignment Overview @@ -50,8 +50,6 @@ course, but just knowing about them could set you up for long term success. ## Assignment Checklist - - To be sure you have completed everything on this assignment, we have littered this document with TODO comments. You can browse all of them in VSCode by opening the TODOs window from the sidebar. The icon looks like a tree and will @@ -141,8 +139,6 @@ to see them. If you don't like this workflow, you may try following the rebase strategies described [here](https://stackoverflow.com/questions/35790561/working-while-waiting-for-pending-pr) and [here](https://stackoverflow.com/questions/18021888/continue-working-on-a-git-branch-after-making-a-pull-request). - - ## Assignment Tasks Your primary task for this assignment is to polish up your code and get it @@ -307,18 +303,18 @@ Take some time to fill them out honestly. > complete the portfolio project, how much better (or worse) do you think you > understand software development and why? - +I believe this has helped me understand software development much better. I hadn't realized that there were so many levels to coding, such as the kernel implementation, interfaces, etc. There is also, of course, the test and use cases too. All of these combine together and make the whole component actually work. Usually, in class, we have to complete a project in a couple of methods. But I believe this project took me through the whole process of a real-world project and not a school project, and I'm grateful to have done this. > Also, did the portfolio project surface any gaps in your own knowledge of > software development. If so, what are those gaps and how did you address them? - +There were several gaps that I mentioned before. First, there was the fact that I didn't know the layers to software development. I learned more about kernel implementations and interfaces in the class and project. Another gap was how to actually code these implementations and interfaces. I only usually knew how to make a method, but I had no clue how to make an interface. So, in this way, it was a learning experience for me. Lastly, an additional gap was learning about Github. I only had a brief understanding of the application, but this project helped me understand how pull requests work and how GitHub can be helpful to store and organize code. > Finally, as a part of completing the portfolio project, to what extent has > your perspective of software development changed, if at all? In other words, > is software development something you still enjoy? If not, why not? - +My perspective of software development has changed quite a lot. In the beginning of the semester, I thought a project was only a file or two full of methods. But now, I realize that there are many layers to creating a component. It is something I still enjoy, though it can be tiring to actually have to work through the whole thing. But I do believe it helps to have the project split up over the semester to better manage your time. > One of the challenges of completing the portfolio project is picking up a lot > of skills on your own. Some of these skills are, of course, software skills. @@ -326,30 +322,35 @@ Take some time to fill them out honestly. > this process. Therefore, the first question is what skills did you pick up > through this process? - +Some skills I have picked up in this process are organization, writing software documentation, time management, and being able to explain your code. This was also a little earlier on, but actually being able to draw out your component with the interfaces and classes is also a good skill to have. Lastly, another important skill was being able to work on GitHub and VScode applications, and specifically troubleshoot any issues you run into, which is something I definitely had to do this semester. > The follow-up question is: could you rephrase these skills you picked up > as bullet points that you could put on a resume? Try it below. - +- Organization +- Time management +- Creativity (coming up with the component idea) +- Technical Writing Skills +- Github +- VSCode +- Code Documentation and Explanation +- Comprehensive Communicator > Next, how has working on this project affected your career trajectory? > In other words, do you now hate the topic you picked? Or, are you even more > interested in it? Both outcomes are valuable to your personal development. - +In terms of career trajectory, I have mixed opinions about it. I enjoyed creating the methods and the idea itself, but I think I didn't really like making the abstract class. I often think of myself as pretty creative, so it makes sense to me that I would like to make the proof of concept. I also did like the topic I picked, but doing this project has made me realize what parts of the component I liked making. Overall, though, I think every part was important, as it has made me more experienced and aware of my interests for the future. > Finally, consider the skills you've picked up and your current career > trajectory. What are some things you could do to continue on your > career trajectory? Also, who are some mentors you could contact to help > you stay on your path? - +Some things I could do to continue on my career trajectory are to continue developing personal projects, take part in hackathons, and take classes I am interested in. For personal projects, I want to make things related to my interests in gaming and reading, so perhaps I can take my booktracker component to another level in the future. There are also a lot of hackathons at OSU, so I will be sure to try to attend them when I can. Lastly, OSU offers a lot of different classes based on specializations, and while I am still here, I want to take as many classes as I can so I can continue to expand what I know. I know there are some classes related to gaming, and I want to take some machine learning classes too. And overall, some mentors I could contact to stay on my path are some of the CS professors here. So far, the ones I have had have been great and knowledgeable, and in the future, I hope I can join some communities to gain some new mentors. ### Changelog - - At the end of every assignment, you should update the [CHANGELOG.md](../../CHANGELOG.md) file found in the root of the project folder. Here's what I would expect to see at the minimum: @@ -363,16 +364,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Calendar Versioning](https://calver.org/) of the following form: YYYY.0M.0D. -## YYYY.MM.DD +## 2025.12.10 ### Added -- Designed test suite for component -- Designed two different use cases for component +- Designed test suite for BookTracker component +- Designed two different use cases for BookTracker component ### Updated -- Changed design to include ... +- Changed design to include test cases for JUnit +- Changed design to include use cases in src +- Updated part 6 in doc and added to reflection questions ``` @@ -384,8 +387,6 @@ request merge (or at least tag your commits). This is not required. ### Submission - - Assuming that your project is in a GitHub repo somewhere and your changes are on a proof-of-concept branch, then what we'll want you to do is create a pull request of all your changes. Pull requests are pretty easy to make if you're @@ -436,6 +437,4 @@ If you'd like to give feedback for this assignment (or any assignment, really), make use of [this survey][survey]. Your feedback helps make assignments better for future students. - - [survey]: https://forms.gle/dumXHo6A4Enucdkq9 diff --git a/src/BookTracker.java b/src/BookTracker.java deleted file mode 100644 index 2cc5880..0000000 --- a/src/BookTracker.java +++ /dev/null @@ -1,205 +0,0 @@ -import java.util.Map; - -import components.map.Map1L; -import components.set.Set; -import components.set.Set1L; - -/** - * A program that serves as a book tracker, keeping track of all the books the - * user is reading and specific data points about them. - */ -public class BookTracker { - - /** - * Tracks all the books. - */ - private Map books; - /** - * Tracks the status of books. - */ - private Map status; - - /** - * Constructs an empty BookTracker. - */ - public BookTracker() { - books = new Map1L<>(); - status = new Map1L<>(); - } - - //Kernel Methods - - /** - * Adds a book to the tracker. But, at first, the book is marked as unread. - * - * @param title - * the title of the book - * @param genre - * the genre of the book - */ - public void addBook(String title, String genre) { - books.add(title, genre); - status.add(title, false); - } - - /** - * Removes a book from the tracker. - * - * @param title - * the title of the book to remove - * @return what book was removed - */ - public String removeBook(String title) { - String result = "Removed: "; - if (hasBook(title)) { - books.remove(title); - status.remove(title); - result = title; - } - - return result; - } - - /** - * Returns the status of the book. - * - * @param title - * the title of the book - * @return "Read", "Unread", or "Book not found." - */ - public String bookStatus(String title) { - String result = ""; - if (hasBook(title)) { - if (status.value(title)) { - result = "Read"; - } else { - result = "Unread"; - } - } else { - result = "Book not found."; - } - return result; - } - - /** - * Checks if there is any book with the specified genre. - * - * @param genre - * the genre to check - * @return true if at least one book matches the genre, false otherwise - */ - public boolean hasGenre(String genre) { - boolean check = false; - Map temp = books.newInstance(); - temp.transferFrom(books); - while (temp.size() > 0) { - Map.Pair pair = temp.removeAny(); - if (pair.value().equals(genre)) { - check = true; - } - books.add(pair.key(), pair.value()); - } - return check; - } - - /** - * Checks if the tracker contains a book with the given title. - * - * @param title - * the book title to check - * @return true if the book exists, false otherwise - */ - public boolean hasBook(String title) { - boolean check = false; - if (books.hasKey(title)) { - check = true; - } - return check; - } - - /** - * Returns the number of books tracked. - * - * @return total number of books - */ - public int size() { - return books.size(); - } - - //Secondary Methods - - /** - * Returns a set of all books belonging to a specific genre. - * - * @param genre - * the genre to filter by - * @return set of book titles in the specified genre - * @restores books - */ - public Set getBooksInGenre(String genre) { - Set bookGenres = new Set1L<>(); - Map temp = books.newInstance(); - temp.transferFrom(books); - while (temp.size() > 0) { - Map.Pair pair = temp.removeAny(); - if (pair.value().equals(genre)) { - bookGenres.add(pair.key()); - } - books.add(pair.key(), pair.value()); - } - return bookGenres; - } - - /** - * Marks a book as read. - * - * @param title - * the title of the book to mark as read - */ - public void markRead(String title) { - if (status.hasKey(title)) { - status.replaceValue(title, true); - } - } - - //Add the method countBooksByAuthors later - - /** - * Main method to showcase how BookTracker works. - * - * @param args - * command line arguments (not used) - */ - public static void main(String[] args) { - BookTracker bTrack = new BookTracker(); - - //Example field to showcase component, comments will give expected results - - //Adds the books to the map - bTrack.addBook("The Secret History", "Fiction"); - bTrack.addBook("Six of Crows", "Fantasy"); - bTrack.addBook("1984", "Dystopian"); - - //This will take out 1984 - bTrack.removeBook("1984"); - - //Status would be unread - System.out.println( - "Status of Six of Crows: " + bTrack.bookStatus("Six of Crows")); - bTrack.markRead("Six of Crows"); - //Status would now be read - System.out.println( - "Status of Six of Crows: " + bTrack.bookStatus("Six of Crows")); - - //These both should be true - bTrack.hasBook("The Secret History"); - bTrack.hasGenre("Fiction"); - - //This should be 2 - bTrack.size(); - - //This should give you The Secret History - System.out.println( - "Books in Fiction: " + bTrack.getBooksInGenre("Fiction")); - } -} diff --git a/src/BookTrackerDemo b/src/BookTrackerDemo new file mode 100644 index 0000000..fc30a91 --- /dev/null +++ b/src/BookTrackerDemo @@ -0,0 +1,44 @@ +package components.booktracker; + +import components.booktracker.BookTracker; +import components.booktracker.BookTracker1L; + +/** + * First program using BookTracker as the main data structure for tracking user's books. + * + * @author Shaili Sinha + */ +public class BookTrackerDemo { + + /** + * Private constructor. + */ + private BookTrackerDemo() { + } + + public static void main(String[] args) { + BookTracker bTrack = new BookTracker1L(); + + // Adds the books + bTrack.addBook("The Secret History", "Fiction", "Donna Tartt"); + bTrack.addBook("Six of Crows", "Fantasy", "Leigh Bardugo"); + bTrack.addBook("1984", "Dystopian", "George Orwell"); + + // Remove 1984 + bTrack.removeBook("1984"); + + // Check and mark read status + System.out.println("Status of Six of Crows: " + bTrack.bookStatus("Six of Crows")); + bTrack.markRead("Six of Crows"); + System.out.println("Status of Six of Crows after reading: " + bTrack.bookStatus("Six of Crows")); + + // Check existence and size + System.out.println("Has 'The Secret History'? " + bTrack.hasBook("The Secret History")); + System.out.println("Has genre 'Fiction'? " + bTrack.hasGenre("Fiction")); + System.out.println("Has author 'Donna Tartt'? " + bTrack.hasAuthor("Donna Tartt")); + System.out.println("Total books: " + bTrack.size()); + + // Books in a genre + System.out.println("Books in Fiction: " + bTrack.getBooksInGenre("Fiction")); + } +} \ No newline at end of file diff --git a/src/LibraryDemo b/src/LibraryDemo new file mode 100644 index 0000000..140d88f --- /dev/null +++ b/src/LibraryDemo @@ -0,0 +1,46 @@ +package components.booktracker; + +import components.booktracker.BookTracker; +import components.booktracker.BookTracker1L; + +/** + * Second program using BookTracker as the main data structure for tracking user's books. + * + * @author Shaili Sinha + */ +public class LibraryDemo { + + /** + * Private constructor. + */ + private LibraryDemo() { + } + + /** + * Demonstrates basic use of BookTracker. + */ + public static void main(String[] args) { + + BookTracker library = new BookTracker1L(); + + System.out.println("=== Library Demo ==="); + + library.addBook("Dune", "Sci-Fi", "Frank Herbert"); + library.addBook("The Hobbit", "Fantasy", "J.R.R. Tolkien"); + library.addBook("1984", "Dystopian", "George Orwell"); + + System.out.println("Size: " + library.size()); + System.out.println("Has book 'Dune'? " + library.hasBook("Dune")); + System.out.println("Has genre 'Fantasy'? " + library.hasGenre("Fantasy")); + System.out.println("Has author 'George Orwell'? " + library.hasAuthor("George Orwell")); + + System.out.println("Status of 1984: " + library.bookStatus("1984")); + library.markRead("1984"); + System.out.println("Status of 1984 after reading: " + library.bookStatus("1984")); + + library.removeBook("Dune"); + System.out.println("Size after removing Dune: " + library.size()); + + System.out.println("=== End of Demo ==="); + } +} diff --git a/src/BookTracker1L.java b/src/components/booktracker/BookTracker1L.java similarity index 100% rename from src/BookTracker1L.java rename to src/components/booktracker/BookTracker1L.java diff --git a/src/BookTrackerSecondary.java b/src/components/booktracker/BookTrackerSecondary.java similarity index 87% rename from src/BookTrackerSecondary.java rename to src/components/booktracker/BookTrackerSecondary.java index 18eeae0..f04596d 100644 --- a/src/BookTrackerSecondary.java +++ b/src/components/booktracker/BookTrackerSecondary.java @@ -12,27 +12,6 @@ */ public abstract class BookTrackerSecondary implements BookTracker { - /** - * Returns the internal map of books (title, genre). - * - * @return stores the names of the books in a map. - */ - protected abstract Map books(); - - /** - * Returns the internal map of status (title, read/unread). - * - * @return stores the status of whether something has been read or not. - */ - protected abstract Map status(); - - /** - * Returns the internal map of status (title, author). - * - * @return stores the books' authors in a map. - */ - protected abstract Map authors(); - /* * Secondary Methods */ diff --git a/test/components/booktracker/BookTracker1LTest.java b/test/components/booktracker/BookTracker1LTest.java new file mode 100644 index 0000000..0862b44 --- /dev/null +++ b/test/components/booktracker/BookTracker1LTest.java @@ -0,0 +1,192 @@ +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * Tests for kernel and standard methods of BookTracker1L. + * + * @author Shaili Sinha + */ +public abstract class BookTracker1LTest { + + /** + * Construtor that creates a tracker with one book. + * + * @param title + * the title of the book + * @param genre + * the genre of the book + * @param author + * the author of the book + * @return tracker for one book + */ + private BookTracker make(String title, String genre, String author) { + BookTracker bt = new BookTracker1L(); + bt.addBook(title, genre, author); + return bt; + } + + // Kernel Method Tests + + /** + * Test adding a book. + */ + @Test + public void testAddBookOne() { + BookTracker bt = new BookTracker1L(); + bt.addBook("T1", "Fantasy", "A1"); + + BookTracker expected = new BookTracker1L(); + expected.addBook("T1", "Fantasy", "A1"); + + assertEquals(expected, bt); + } + + /** + * Test removing a book. + */ + @Test + public void testRemoveBookOne() { + BookTracker bt = make("T1", "Fantasy", "A1"); + bt.removeBook("T1"); + + BookTracker expected = new BookTracker1L(); + assertEquals(expected, bt); + } + + /** + * Test marking a book as unread. + */ + @Test + public void testBookStatusUnread() { + BookTracker bt = make("T1", "Fantasy", "A1"); + assertEquals("Unread", bt.bookStatus("T1")); + } + + /** + * Test marking a book as read. + */ + @Test + public void testBookStatusRead() { + BookTracker bt = make("T1", "Fantasy", "A1"); + bt.markRead("T1"); + assertEquals("Read", bt.bookStatus("T1")); + } + + /** + * Test if book exists is true. + */ + @Test + public void testHasBookTrue() { + BookTracker bt = make("T1", "Fantasy", "A1"); + assertTrue(bt.hasBook("T1")); + } + + /** + * Test if book exists is false. + */ + @Test + public void testHasBookFalse() { + BookTracker bt = new BookTracker1L(); + assertFalse(bt.hasBook("No")); + } + + /** + * Test if a genre there is true. + */ + @Test + public void testHasGenreTrue() { + BookTracker bt = make("T1", "Fantasy", "A1"); + assertTrue(bt.hasGenre("Fantasy")); + } + + /** + * Test if a genre there is false. + */ + @Test + public void testHasGenreFalse() { + BookTracker bt = make("T1", "Fantasy", "A1"); + assertFalse(bt.hasGenre("Sci-Fi")); + } + + /** + * Test if an author there is true. + */ + @Test + public void testHasAuthorTrue() { + BookTracker bt = make("T1", "Fantasy", "A1"); + assertTrue(bt.hasAuthor("A1")); + } + + /** + * Test if an author there is false. + */ + @Test + public void testHasAuthorFalse() { + BookTracker bt = make("T1", "Fantasy", "A1"); + assertFalse(bt.hasAuthor("Unknown Author")); + } + + /** + * Test size if it's not empty. + */ + @Test + public void testSizeNonzero() { + BookTracker bt = make("T1", "Fantasy", "A1"); + bt.addBook("T2", "Horror", "A2"); + assertEquals(2, bt.size()); + } + + /** + * Test size if it's empty. + */ + @Test + public void testSizeZero() { + BookTracker bt = new BookTracker1L(); + assertEquals(0, bt.size()); + } + + // Standard Methods + + /** + * Test clear of booktracker. + */ + @Test + public void testClear() { + BookTracker bt = make("T1", "Fantasy", "A1"); + bt.clear(); + + BookTracker expected = new BookTracker1L(); + assertEquals(expected, bt); + } + + /** + * Test creating a new instance of booktracker. + */ + @Test + public void testNewInstance() { + BookTracker bt = new BookTracker1L(); + BookTracker bt2 = bt.newInstance(); + + assertEquals(new BookTracker1L(), bt2); + } + + /** + * Test transfering booktracker to another place. + */ + @Test + public void testTransferFrom() { + BookTracker src = make("T1", "Fantasy", "A1"); + BookTracker dst = new BookTracker1L(); + + dst.transferFrom(src); + + BookTracker expectedDst = make("T1", "Fantasy", "A1"); + BookTracker expectedSrc = new BookTracker1L(); + + assertEquals(expectedDst, dst); + assertEquals(expectedSrc, src); + } +} diff --git a/test/components/booktracker/BookTrackerTest.java b/test/components/booktracker/BookTrackerTest.java new file mode 100644 index 0000000..43635aa --- /dev/null +++ b/test/components/booktracker/BookTrackerTest.java @@ -0,0 +1,130 @@ +import org.junit.Test; + +import components.map.Map; +import components.map.Map1L; +import components.set.Set; +import components.set.Set1L; + +/** + * Tests for secondary methods and object methods of the abstract class of + * BookTracker. + * + * @author Shaili Sinha + */ +public abstract class BookTrackerSecondaryTest { + + /** + * Construtor that creates a tracker with books. + * + * @param books + * tracker for testing + * @return tracker for books + */ + private BookTracker build(String[][] books) { + BookTracker bt = new BookTracker1L(); + for (String[] entry : books) { + bt.addBook(entry[0], entry[1], entry[2]); + } + return bt; + } + + // Secondary Methods + + /** + * Test getting books from a specific genre. + */ + @Test + public void testGetBooksInGenre() { + BookTracker bt = build(new String[][] { { "T1", "Fiction", "A1" }, + { "T2", "Horror", "A2" }, { "T3", "Fiction", "A3" } }); + + Set expected = new Set1L<>(); + expected.add("T1"); + expected.add("T3"); + + assertEquals(expected, bt.getBooksInGenre("Fiction")); + } + + /** + * Test marking a book as read. + */ + @Test + public void testMarkRead() { + BookTracker bt = build(new String[][] { { "T1", "Fiction", "A1" } }); + + bt.markRead("T1"); + + BookTracker expected = build( + new String[][] { { "T1", "Fiction", "A1" } }); + expected.markRead("T1"); + + assertEquals(expected, bt); + } + + /** + * Test counting books by a specific author. + */ + @Test + public void testCountBooksByAuthor() { + BookTracker bt = build(new String[][] { { "T1", "Fiction", "A1" }, + { "T2", "Horror", "A2" }, { "T3", "SciFi", "A1" } }); + + Map expected = new Map1L<>(); + expected.add("A1", 2); + expected.add("A2", 1); + + assertEquals(expected, bt.countBooksByAuthor()); + } + + // Object Methods + + /** + * Test if two books in booktracker is true. + */ + @Test + public void testEqualsTrue() { + BookTracker bt1 = build(new String[][] { { "T1", "Fiction", "A1" } }); + + BookTracker bt2 = build(new String[][] { { "T1", "Fiction", "A1" } }); + + assertTrue(bt1.equals(bt2)); + } + + /** + * Test if two books in booktracker is false. + */ + @Test + public void testEqualsFalse() { + BookTracker bt1 = build(new String[][] { { "T1", "Fiction", "A1" } }); + + BookTracker bt2 = build(new String[][] { { "T2", "Fiction", "A1" } }); + + assertFalse(bt1.equals(bt2)); + } + + /** + * Test if the right hashcode is returned. + */ + @Test + public void testHashCode() { + BookTracker bt1 = build(new String[][] { { "T1", "Fiction", "A1" } }); + + BookTracker bt2 = build(new String[][] { { "T1", "Fiction", "A1" } }); + + assertEquals(bt1.hashCode(), bt2.hashCode()); + } + + /** + * Test if string output matches when toString is called. + */ + @Test + public void testToString() { + BookTracker bt = build(new String[][] { { "T1", "Fiction", "A1" } }); + + String result = bt.toString(); + String expected = "BookTracker with the following books:\n" + + "Title: T1, Genre: Fiction, Author: A1\n"; + + assertEquals(expected, result); + } +}