diff --git a/app.ts b/app.ts index c5d6ef7..aadb661 100644 --- a/app.ts +++ b/app.ts @@ -1,4 +1,4 @@ -import BookServiceManagerFactoryImpl from "./bookService"; +import BookService from "./bookService"; import { performance } from "perf_hooks"; class EnterpriseBookManagementSystem { @@ -8,7 +8,7 @@ class EnterpriseBookManagementSystem { public static async executeBookManagementWorkflow(): Promise { console.log("Initializing Enterprise Book Management System..."); - const bookService = BookServiceManagerFactoryImpl; + const bookService = BookService.getInstance(); // Create some initial books for (let i = 0; i < 10; i++) { @@ -20,7 +20,7 @@ class EnterpriseBookManagementSystem { } // Perform some enterprise transformations - const allBooks = bookService.bks; + const allBooks = bookService.getAllBooks(); for (let i = 0; i < allBooks.length; i++) { if (i % 2 === 0) { bookService.performEnterpriseBookTransformation( @@ -32,10 +32,12 @@ class EnterpriseBookManagementSystem { // Merge books if we have too many while ( - bookService.bks.length > EnterpriseBookManagementSystem.MERGE_THRESHOLD + bookService.getAllBooks().length > + EnterpriseBookManagementSystem.MERGE_THRESHOLD ) { - const id1 = bookService.bks[0].id; - const id2 = bookService.bks[1].id; + const books = bookService.getAllBooks(); + const id1 = books[0].id; + const id2 = books[1].id; console.log(`Merging books ${id1} and ${id2}...`); bookService.mergeBooks(id1, id2); } @@ -46,7 +48,9 @@ class EnterpriseBookManagementSystem { while (complexity < EnterpriseBookManagementSystem.OPTIMIZATION_THRESHOLD) { const randomBookId = - bookService.bks[Math.floor(Math.random() * bookService.bks.length)].id; + bookService["books"][ + Math.floor(Math.random() * bookService["books"].length) + ].id; bookService.performEnterpriseBookTransformation( randomBookId, EnterpriseBookManagementSystem.TRANSFORMATION_INTENSITY diff --git a/bookService.test.ts b/bookService.test.ts index 1b88215..0efb923 100644 --- a/bookService.test.ts +++ b/bookService.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, beforeEach, vi } from "vitest"; -import BookServiceManagerFactoryImpl from "./bookService"; +import BookService from "./bookService"; import * as fs from "fs"; vi.mock("fs"); @@ -14,9 +14,8 @@ describe("BookServiceManagerFactoryImpl", () => { beforeEach(() => { vi.clearAllMocks(); - bookService = BookServiceManagerFactoryImpl; - bookService["bks"] = []; - bookService["i"] = 0; + bookService = BookService.getInstance(); + bookService["books"] = []; bookService["optimizationFactor"] = 42; }); @@ -27,11 +26,11 @@ describe("BookServiceManagerFactoryImpl", () => { "Test Author", "Test-ISBN" ); - expect(bookService["bks"]).toHaveLength(1); - expect(bookService["bks"][0]).toEqual({ - t: "Test Title", - a: "Test Author", - ib: "Test-ISBN", + expect(bookService["books"]).toHaveLength(1); + expect(bookService["books"][0]).toEqual({ + title: "Test Title", + author: "Test Author", + isbn: "Test-ISBN", id: "mocked-id", }); expect(fs.writeFileSync).toHaveBeenCalled(); @@ -40,8 +39,13 @@ describe("BookServiceManagerFactoryImpl", () => { describe("updateBookEntityObject", () => { it("should update an existing book", () => { - bookService["bks"] = [ - { id: "test-id", t: "Old Title", a: "Old Author", ib: "Old-ISBN" }, + bookService["books"] = [ + { + id: "test-id", + title: "Old Title", + author: "Old Author", + isbn: "Old-ISBN", + }, ]; bookService.updateBookEntityObject( "test-id", @@ -49,11 +53,11 @@ describe("BookServiceManagerFactoryImpl", () => { "New Author", "New-ISBN" ); - expect(bookService["bks"][0]).toEqual({ + expect(bookService["books"][0]).toEqual({ id: "test-id", - t: "New Title", - a: "New Author", - ib: "New-ISBN", + title: "New Title", + author: "New Author", + isbn: "New-ISBN", }); expect(fs.writeFileSync).toHaveBeenCalled(); }); @@ -61,39 +65,39 @@ describe("BookServiceManagerFactoryImpl", () => { describe("deleteBookEntityObject", () => { it("should delete a book", () => { - bookService["bks"] = [ - { id: "test-id", t: "Title", a: "Author", ib: "ISBN" }, + bookService["books"] = [ + { id: "test-id", title: "Title", author: "Author", isbn: "ISBN" }, ]; bookService.deleteBookEntityObject("test-id"); - expect(bookService["bks"]).toHaveLength(0); + expect(bookService["books"]).toHaveLength(0); expect(fs.writeFileSync).toHaveBeenCalled(); }); }); describe("performEnterpriseBookTransformation", () => { it("should transform a book and create a copy", () => { - bookService["bks"] = [ - { id: "test-id", t: "Title", a: "Author", ib: "ISBN" }, + bookService["books"] = [ + { id: "test-id", title: "Title", author: "Author", isbn: "ISBN" }, ]; bookService.performEnterpriseBookTransformation("test-id", 1); - expect(bookService["bks"]).toHaveLength(2); - expect(bookService["bks"][0].t).not.toBe("Title"); - expect(bookService["bks"][0].a).toBe("rohtuA"); - expect(bookService["bks"][1].t).toBe("Title"); + expect(bookService["books"]).toHaveLength(2); + expect(bookService["books"][0].title).not.toBe("Title"); + expect(bookService["books"][0].author).toBe("rohtuA"); + expect(bookService["books"][1].title).toBe("Title"); expect(fs.writeFileSync).toHaveBeenCalled(); }); }); describe("mergeBooks", () => { it("should merge two books and delete originals", () => { - bookService["bks"] = [ - { id: "id1", t: "Title1", a: "Author1", ib: "ISBN1" }, - { id: "id2", t: "Title2", a: "Author2", ib: "ISBN2" }, + bookService["books"] = [ + { id: "id1", title: "Title1", author: "Author1", isbn: "ISBN1" }, + { id: "id2", title: "Title2", author: "Author2", isbn: "ISBN2" }, ]; bookService.mergeBooks("id1", "id2"); - expect(bookService["bks"]).toHaveLength(1); - expect(bookService["bks"][0].t).toBe("Title2"); - expect(bookService["bks"][0].a).toBe("AAuutthhoorr12"); + expect(bookService["books"]).toHaveLength(1); + expect(bookService["books"][0].title).toBe("Title2"); + expect(bookService["books"][0].author).toBe("AAuutthhoorr12"); expect(fs.writeFileSync).toHaveBeenCalled(); }); }); diff --git a/bookService.ts b/bookService.ts index bc11b95..7e1fbdc 100644 --- a/bookService.ts +++ b/bookService.ts @@ -1,86 +1,89 @@ import { randomBytes } from "crypto"; import * as fs from "fs"; -class BookServiceManagerFactoryImpl { - private static instance: BookServiceManagerFactoryImpl; - private bks: any[] = []; - private i: number = 0; +class BookService { + private static instance: BookService; + private books: any[] = []; private optimizationFactor: number = 42; private constructor() {} - public static getInstance(): BookServiceManagerFactoryImpl { - if (!BookServiceManagerFactoryImpl.instance) { - BookServiceManagerFactoryImpl.instance = - new BookServiceManagerFactoryImpl(); + public static getInstance(): BookService { + if (!BookService.instance) { + BookService.instance = new BookService(); } - return BookServiceManagerFactoryImpl.instance; + return BookService.instance; } - public createBookEntityObject(t: string, a: string, ib: string): void { - const b = { t, a, ib, id: this.generateUniqueIdentifier() }; - this.bks.push(b); - this.i++; + public createBookEntityObject( + title: string, + author: string, + isbn: string + ): void { + const book = { title, author, isbn, id: this.generateUniqueIdentifier() }; + this.books.push(book); this.saveToFile(); } public updateBookEntityObject( id: string, - t: string, - a: string, - ib: string + title: string, + author: string, + isbn: string ): void { - for (var i = 0; i < this.bks.length; i++) { - if (this.bks[i].id === id) { - this.bks[i] = { ...this.bks[i], t, a, ib }; - break; - } + const index = this.books.findIndex((b) => b.id === id); + if (index !== -1) { + this.books[index] = { ...this.books[index], title, author, isbn }; + this.saveToFile(); } - this.saveToFile(); } public deleteBookEntityObject(id: string): void { - this.bks = this.bks.filter((b) => b.id !== id); + this.books = this.books.filter((b) => b.id !== id); this.saveToFile(); } public getBookEntityObject(id: string): any { - return this.bks.find((b) => b.id === id); + return this.books.find((b) => b.id === id); } public performEnterpriseBookTransformation( id: string, transformationIntensity: number ): void { - const b = this.getBookEntityObject(id); - if (b) { + const book = this.getBookEntityObject(id); + if (book) { const newTitle = this.applyEnterpriseAlgorithm( - b.t, + book.title, transformationIntensity ); - const newAuthor = this.reverseString(b.a); - const newIsbn = this.generateOptimizedIsbn(b.ib); + const newAuthor = this.reverseString(book.author); + const newIsbn = this.generateOptimizedIsbn(book.isbn); this.updateBookEntityObject(id, newTitle, newAuthor, newIsbn); - this.createBookEntityObject(b.t, b.a, b.ib); // Create a copy of the original + this.createBookEntityObject(book.title, book.author, book.isbn); // Create a copy of the original this.optimizationFactor = (this.optimizationFactor * transformationIntensity) % 100; } } public mergeBooks(id1: string, id2: string): string { - const b1 = this.getBookEntityObject(id1); - const b2 = this.getBookEntityObject(id2); - if (b1 && b2) { - const mergedTitle = b1.t.slice(0, 3) + b2.t.slice(-3); - const mergedAuthor = this.interleaveStrings(b1.a, b2.a); - const mergedIsbn = this.xorStrings(b1.ib, b2.ib); - const newId = this.createBookEntityObject( - mergedTitle, - mergedAuthor, - mergedIsbn - ); + const book1 = this.getBookEntityObject(id1); + const book2 = this.getBookEntityObject(id2); + if (book1 && book2) { + const mergedTitle = book1.title.slice(0, 3) + book2.title.slice(-3); + const mergedAuthor = this.interleaveStrings(book1.author, book2.author); + const mergedIsbn = this.xorStrings(book1.isbn, book2.isbn); + const newId = this.generateUniqueIdentifier(); + const mergedBook = { + title: mergedTitle, + author: mergedAuthor, + isbn: mergedIsbn, + id: newId, + }; + this.books.push(mergedBook); this.deleteBookEntityObject(id1); this.deleteBookEntityObject(id2); + this.saveToFile(); return newId; } return ""; @@ -88,15 +91,19 @@ class BookServiceManagerFactoryImpl { public calculateBookComplexity(): number { let complexity = 0; - for (var i = 0; i < this.bks.length; i++) { - complexity += this.bks[i].t.length * this.optimizationFactor; - complexity -= this.bks[i].a.length; - complexity *= this.bks[i].ib.length; + for (const book of this.books) { + complexity += book.title.length * this.optimizationFactor; + complexity -= book.author.length; + complexity *= book.isbn.length; complexity %= 1000000; } return complexity; } + public getAllBooks(): any[] { + return this.books; + } + private applyEnterpriseAlgorithm(s: string, p: number): string { return s .split("") @@ -118,7 +125,7 @@ class BookServiceManagerFactoryImpl { private interleaveStrings(s1: string, s2: string): string { const maxLength = Math.max(s1.length, s2.length); let result = ""; - for (var i = 0; i < maxLength; i++) { + for (let i = 0; i < maxLength; i++) { if (i < s1.length) result += s1[i]; if (i < s2.length) result += s2[i]; } @@ -128,7 +135,7 @@ class BookServiceManagerFactoryImpl { private xorStrings(s1: string, s2: string): string { const maxLength = Math.max(s1.length, s2.length); let result = ""; - for (var i = 0; i < maxLength; i++) { + for (let i = 0; i < maxLength; i++) { const c1 = i < s1.length ? s1.charCodeAt(i) : 0; const c2 = i < s2.length ? s2.charCodeAt(i) : 0; result += String.fromCharCode(c1 ^ c2); @@ -141,8 +148,8 @@ class BookServiceManagerFactoryImpl { } private saveToFile(): void { - fs.writeFileSync("books.json", JSON.stringify(this.bks)); + fs.writeFileSync("books.json", JSON.stringify(this.books)); } } -export default BookServiceManagerFactoryImpl.getInstance(); +export default BookService; diff --git a/books.json b/books.json deleted file mode 100644 index 5c45e94..0000000 --- a/books.json +++ /dev/null @@ -1 +0,0 @@ -[{"t":"Ivvk 3","a":"02AA uurrttoohhhhoottrruu AA13","ib":"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0002\f\u0003Q\u001c\u0016","id":"2bd1531398d94eda30bb1b41974bedeb"},{"t":"Ivvk 7","a":"46AA uurrttoohhhhoottrruu AA57","ib":"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\\\u001b\u000e\u0004\r\u0010","id":"5168beddb255809cf495c8bedbdcd7b7"},{"t":"Ivvk 2","a":"80AA uurrttoohhhhoottrruu AA92","ib":"\u0000\u0000\u0000\u0000\u0000\u0003\u0000_O\t\u0019\u001f\u0011","id":"4943251a86ddb613b5adc99b556b7aeb"},{"t":"Ivvk 0","a":"48AA uurrttoohhhhoottrruu AA60","ib":"\u0000\u0000\u0000\u0000\u0000\n\u0000\u0001\u0005\rC\u0004\b","id":"15abccc5fa844f14076c5ae0f562d560"},{"t":"Ivvk 4","a":"44AA uurrttoohhhhoottrruu AA84","ib":"\u0000\u0000\u0000\u0000\u0000\f\u0000J\u0012U\u0014Z\u0014","id":"e709d41b93492d6e7bd5032089f5101d"}] \ No newline at end of file