From 4283b644e639b06fc8da4216a978a82d562862c0 Mon Sep 17 00:00:00 2001 From: IrumShehryar Date: Thu, 22 May 2025 23:03:17 +0300 Subject: [PATCH] Added and passed book tests --- .github/workflows/ci.yml | 32 +++++++ .idea/.gitignore | 8 ++ .idea/LibrarySystem1.iml | 10 ++ .../inspectionProfiles/profiles_settings.xml | 6 ++ .idea/misc.xml | 7 ++ .idea/modules.xml | 8 ++ .idea/vcs.xml | 6 ++ __pycache__/book.cpython-311.pyc | Bin 0 -> 949 bytes __pycache__/library.cpython-311.pyc | Bin 0 -> 1765 bytes book.py | 14 +++ library.py | 27 ++++++ main.py | 49 ++++++++++ requirments.txt | 3 + ci.yml => tests/__init__.py | 0 tests/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 171 bytes .../test_book.cpython-311-pytest-8.3.5.pyc | Bin 0 -> 7204 bytes .../test_library.cpython-311-pytest-8.3.5.pyc | Bin 0 -> 17021 bytes tests/test_book.py | 30 ++++++ tests/test_library.py | 87 ++++++++++++++++++ 19 files changed, 287 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .idea/.gitignore create mode 100644 .idea/LibrarySystem1.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 __pycache__/book.cpython-311.pyc create mode 100644 __pycache__/library.cpython-311.pyc create mode 100644 book.py create mode 100644 library.py create mode 100644 requirments.txt rename ci.yml => tests/__init__.py (100%) create mode 100644 tests/__pycache__/__init__.cpython-311.pyc create mode 100644 tests/__pycache__/test_book.cpython-311-pytest-8.3.5.pyc create mode 100644 tests/__pycache__/test_library.cpython-311-pytest-8.3.5.pyc create mode 100644 tests/test_book.py create mode 100644 tests/test_library.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b488657 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,32 @@ +name: Python CI + +on: + push: + branches: [ "**" ] + pull_request: + branches: [ "main" ] + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.9] + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Run tests with pytest + run: | + pytest \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/LibrarySystem1.iml b/.idea/LibrarySystem1.iml new file mode 100644 index 0000000..6fb6f82 --- /dev/null +++ b/.idea/LibrarySystem1.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..8a08999 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..0b47a07 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/__pycache__/book.cpython-311.pyc b/__pycache__/book.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f2d44091cc0031398bb3aed19053ee47cecb55f8 GIT binary patch literal 949 zcmZuu&1(};5TCanX+GOxYc*<1PC_nKK@mg*74#yZl6nb&$0oayt-IMeyHOK@^w2{N zJ$TE1palP+uvhgodpXnzliA&DeMm z1RuKk@)j$u&;H^*!4$?~43ex=#u|C69>j>ejE@aXm}!l}x*nU68+lHgvj$Nwz_?(2 zvRu#Vcn;-^(DB}5j_TnWLCC#owc7c^mrvU7LI=aPivz!XFzog$^basNa=KC2e&cq~ z!eMh5MvniW-67ih$HO=;rQ3HSDMuBaWPjx{tME3#3CyqGniyxr`OY0urFnIi)cSTo77Pf=0@QX!YDAwO`O>ja3w=TS+q zOC2@#E@g?^#@5-_1Vo`a-@5tj(Y(6HHl14`)E=E*BLelF7ha$ z6AiF0d2gdlMdm`J!lxOC(ZBsD290`-m)y5}N6NS;r61S>kL|LQ9|x9~X0XIvHyN%G z%s^dMJ3xM61-zH=Il)QxC7N#TC6GbUFt-!Ppe#6h8Pe)pxKS5rgB|X|J5x>1^G{Qv e&+rDtROiQJB)SkH(JF$B+>Cw>5b3h@!~Wu zE$BJZ$hzTXDu$^SZ)OWl^wFhCQ&!ddV%}8MWySqy)YBkqMg(AuG-B}$vDUc(*D2B3kRO*Ai^&m*4F`T*(6s4F&d GJJc@*ifldr literal 0 HcmV?d00001 diff --git a/book.py b/book.py new file mode 100644 index 0000000..59854ad --- /dev/null +++ b/book.py @@ -0,0 +1,14 @@ +class Book: + def __init__(self, title, author): + self.title = title + self.author = author + self.available = True + + def borrow(self): + if not self.available: + return False + self.available = False + return True + + def return_book(self): + self.available = True \ No newline at end of file diff --git a/library.py b/library.py new file mode 100644 index 0000000..4128481 --- /dev/null +++ b/library.py @@ -0,0 +1,27 @@ +from book import Book + +class Library: + def __init__(self): + self.books = [] + + def add_book(self, title, author): + self.books.append(Book(title, author)) + + def is_available(self, title): + for book in self.books: + if book.title == title: + return book.available + return False + + def borrow_book(self, title): + for book in self.books: + if book.title == title: + return book.borrow() + return False + + def return_book(self, title): + for book in self.books: + if book.title == title: + book.return_book() + return True + return False diff --git a/main.py b/main.py index 8b13789..cbbc6b6 100644 --- a/main.py +++ b/main.py @@ -1 +1,50 @@ + +from library import Library + +def main(): + lib = Library() + + print("\n📚 Welcome to the Library System") + + # Add books to the library + lib.add_book("1984", "George Orwell") + lib.add_book("The Hobbit", "J.R.R. Tolkien") + + print("\n📖 Books Added:") + for book in lib.books: + print(f"- {book.title} by {book.author} (Available: {book.available})") + + # Check availability + print(f"\n🔍 Is '1984' available? {lib.is_available('1984')}") + + # Borrow a book + print("\n📥 Borrowing '1984'...") + success = lib.borrow_book("1984") + print(f"Borrowed: {success}") + print(f"Available now? {lib.is_available('1984')}") + + # Try borrowing it again + print("\n📥 Trying to borrow '1984' again...") + success = lib.borrow_book("1984") + print(f"Borrowed: {success}") + + # Return the book + print("\n📤 Returning '1984'...") + returned = lib.return_book("1984") + print(f"Returned: {returned}") + print(f"Available now? {lib.is_available('1984')}") + + # Try returning again (already available) + print("\n📤 Returning '1984' again...") + returned = lib.return_book("1984") + print(f"Returned: {returned}") + + # Borrow a non-existent book + print("\n📥 Borrowing 'Unknown Book'...") + success = lib.borrow_book("Unknown Book") + print(f"Borrowed: {success}") + +if __name__ == "__main__": + main() + diff --git a/requirments.txt b/requirments.txt new file mode 100644 index 0000000..bad3131 --- /dev/null +++ b/requirments.txt @@ -0,0 +1,3 @@ +pytest +requests +flask \ No newline at end of file diff --git a/ci.yml b/tests/__init__.py similarity index 100% rename from ci.yml rename to tests/__init__.py diff --git a/tests/__pycache__/__init__.cpython-311.pyc b/tests/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d3798947be93d531cb1b983e9013af06e02c74fc GIT binary patch literal 171 zcmZ3^%ge<81W(KLGeGoX5CH>>P{wCAAY(d13PUi1CZpd2X#0(Sz07srGjsO4v literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_book.cpython-311-pytest-8.3.5.pyc b/tests/__pycache__/test_book.cpython-311-pytest-8.3.5.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a4009819b5c035599528edb05eeaf87b085b2f98 GIT binary patch literal 7204 zcmeHLO>f-B876nR+|{l=>{xaq!F4I6LcM4rSC--wa_qEmYP3jg7>RUo6fCGET~X#P zg&{Y#)D@rx0jd-M>O%qRkV8*S6(9Q(`Uh5qgc>}y=%J??a8Ek*d1uI3az7l$aoa;o zabLdk&NCmJq2_sJz8D%RD!Bf&ac1RHO;P?%iTKJy&f|CB+*K^aQeEY`%Ac89wwh6u znsz;>QclLzYx(PW_}NdC>jg`L9k6n+MN5Y*S?c>rIsZ?p@@iQPwYNR*W;JSnKk~3y z{2u=a{kW?HYCF?Xt;{|2=6>8GWm9P?s}ixPTIyz|sWvk=Ibt*0%=%vjxpob!R5QOU zXALQTv(2LQJM-Kn# z&ouhh09Lf&#?MjDg6#*!%)If7x)V62>ui{TWL~&zAk-uOr8}V37BtvOmq6EN&VXMCkRhA8N~3Zg;a`76>wD$-I6zZ2CSm zK_%Y+48b?BI&Vxrp?2{msp=PY)iC4uyXwZwlM0I0c5Re(eBLIyRvu)uHitRh>#+Ef zwelF?AvRuS?4nr>f-IffoP6gdsk-# z>R*Xk7Q;1@Ow1({vmzlXK9@}V*e8}S_;vW!rTL{r47|VOutsg^+In@xWVLI|Tg6x4 zFa6S4W+q#If87u4+RPFShtF+=W^sCLJv_#T$Vq)|?E7edhSL8tNN`K}M``5FVC&TE zUTJQ>G`IE6!_vrS^DS*^=OoPb{LaY-r73vgKG3H2V_!rF0dFtP5D1w>mWXW6$yisQ z4Vo7qf!H}Ii-;CrlQ(ijNdXrabT3&diHA=wcfO^aX^o$O-9C@!gA%#oKG4qW$G(Vg z2;99mM?ho}St3I37ZvUbv_ay<66JJsizJ%}kX(ZtvrSyucpl4dXfhbA5K>kHUc{e46=s$>GkccD{ zb3KVt|As=bL)P^biXAuzMLpHqwovSpfceiekpwJQ1J6|g7JJCQEX0T2%rn0D!>7u{$Ju$~ZKw$EmT_yvuE!F?wYdga<~gU!2D5_(tNX?R zYe17gdiV)s;2D>}rZ%H}4#fHcX!|av>_v@mA>=Zji=!! zDflcqB_o1|=hy@l`W_jB%p{CYJrQ&a%U(e$9OtYm`ck1`tVk8WW&oh~^#6h-rU$tW z9sT_Wzx&|R4?p{G>+-|nV=ZlL``n#{Z7kX3<37;F_G4c}2mo&{&JYNhlx4Qh$(Vp7 z0upowt8%*m_@WJIMFiz#KLkEmN`fP@ncP`yX_KIm#a3w&p12RR$^FqJ zkV$|!t=9l%qCZ+7xAf-}IQX2ffkoU^N$E&q5tGeHX*NwtbuUQJ z4Q-CQh=~&rcFFNp5sXzcvDNEjrpug}*bmSWBL-k)GCw54Ij1k>uvZB)4bzJOPIWN= z`kY{aS(GC(^IN@HKr8(A-H+e>&6Q8CY+ZSnriAg9HjWj4ar-Se;y%#E_hVl~2mo&{ z&JYNhM3#sU14L!J0upowYiGLw_@WJIMFizV6^ILbvXlgWyD8z{nC|Db|KOA$53=zw z$t%52Azb^|x@*_+W$%UQD|Rg;y`pPX?j6$Y^5boJAcn&+I{x5S=dm?*ElHg8J8^v1 zB6Cy6Z5{iYKJ|6)ZQ|qY^xlS4V|1lzl82;UdAv;uJ38Lx3cJ*J6BY8sY;N9okIQGQ zTHZ~rtA(8Ar!o-N-Ex{_cBh)|yE0vkPQuu0XfZ4$>gIa)sm1YkQ9NylYJc=8mNKpIS8eoxHoB*s*w;?9v=iTg;|Q)0%Y$JdK5pcjl5ngd4k)L^Ss;!R zrI>t v4f80gs_H}9c=Y~jDaSkRM_Nvue56P-oKs(+WMqbQ@}xN;aqSZ1@t*w$RW04S literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_library.cpython-311-pytest-8.3.5.pyc b/tests/__pycache__/test_library.cpython-311-pytest-8.3.5.pyc new file mode 100644 index 0000000000000000000000000000000000000000..40b157e0412d00ff7f671c4f8bec6d6d29de4df5 GIT binary patch literal 17021 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 J&`J0+{}n$iFJ%A# literal 0 HcmV?d00001 diff --git a/tests/test_book.py b/tests/test_book.py new file mode 100644 index 0000000..384ba99 --- /dev/null +++ b/tests/test_book.py @@ -0,0 +1,30 @@ +from book import Book + +def test_initialization(): + """Test 1: Initialization — title, author, and availability set correctly""" + book = Book("Clean Code", "Robert Cecil Martin") + assert book.title == "Clean Code" + assert book.author == "Robert Cecil Martin" + assert book.available is True + +def test_borrow_when_available(): + """Test 2: Borrow when available — borrow() returns True, sets available to False""" + book = Book("Clean Code", "Robert Cecil Martin") + result = book.borrow() + assert result is True + assert book.available is False + +def test_borrow_when_not_available(): + """Test 3: Borrow when not available — borrow() returns False, available remains False""" + book = Book("Clean Code", "Robert Cecil Martin") + book.borrow() # First borrow + result = book.borrow() # Try borrowing again + assert result is False + assert book.available is False + +def test_return_book(): + """Test 4: Return book — return_book() sets available to True""" + book = Book("Clean Code", "Robert Cecil Martin") + book.borrow() + book.return_book() + assert book.available is True diff --git a/tests/test_library.py b/tests/test_library.py new file mode 100644 index 0000000..aeba356 --- /dev/null +++ b/tests/test_library.py @@ -0,0 +1,87 @@ +from library import Library + +# 1. Library Initialization +def test_library_initialization(): + """ + Test: Library should initialize with an empty book list. + """ + lib = Library() + assert isinstance(lib.books, list) + assert len(lib.books) == 0 + +# 2. Add book +def test_add_book(): + """ + Test: Add book to the library. + - Book is added to the list with correct details. + - Book is initially available. + """ + lib = Library() + lib.add_book("1984", "George Orwell") + assert len(lib.books) == 1 + book = lib.books[0] + assert book.title == "1984" + assert book.author == "George Orwell" + assert book.available is True + +# 3. Check availability - exists +def test_is_available_true(): + lib = Library() + lib.add_book("Dune", "Frank Herbert") + assert lib.is_available("Dune") is True + +# 4. Check availability - doesn’t exist +def test_is_available_false_for_nonexistent_book(): + lib = Library() + assert lib.is_available("Nonexistent") is False + +# 5. Borrow book - available +def test_borrow_book_available(): + lib = Library() + lib.add_book("Clean Code", "Robert Martin") + result = lib.borrow_book("Clean Code") + assert result is True + assert lib.books[0].available is False + +# 6. Borrow book - already borrowed +def test_borrow_book_already_borrowed(): + lib = Library() + lib.add_book("Clean Code", "Robert Martin") + lib.borrow_book("Clean Code") + result = lib.borrow_book("Clean Code") + assert result is False + assert lib.books[0].available is False + +# 7. Borrow book - not in library +def test_borrow_book_not_in_library(): + lib = Library() + result = lib.borrow_book("Unknown Book") + assert result is False + +# 8. Return book - valid +def test_return_book_valid(): + lib = Library() + lib.add_book("Refactoring", "Martin Fowler") + lib.borrow_book("Refactoring") + result = lib.return_book("Refactoring") + assert result is True + assert lib.books[0].available is True + +# 9. Return book - doesn’t exist +def test_return_book_not_in_library(): + lib = Library() + result = lib.return_book("Nonexistent") + assert result is False + +# 10. Return book - already available +def test_return_book_already_available(): + """ + Returning a book that's already available: + - Should return True. + - Should not break logic. + """ + lib = Library() + lib.add_book("Domain-Driven Design", "Eric Evans") + result = lib.return_book("Domain-Driven Design") + assert result is True + assert lib.books[0].available is True