Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
Loading items

Target

Select target project
  • z22024794/prog-av-exercices-fadl-zemzem
  • n23017542/progavexercices
  • l23024794/saratp-1
  • d24029849/progavexercices
  • gnaves/progavexercices
5 results
Select Git revision
Loading items
Show changes
Showing
with 795 additions and 0 deletions
package fr.univamu.progav.td9;
public enum BookStatus { AVAILABLE, BORROWED; }
package fr.univamu.progav.td9;
public class BookUnavailableException extends BookException {
// TODO
}
package fr.univamu.progav.td9;
import java.util.ArrayList;
import java.util.List;
public record BulkCheckoutResult(
List<Book> successfulCheckouts,
List<BookException> failedCheckouts
) {
public BulkCheckoutResult() {
this(new ArrayList<>(), new ArrayList<>());
}
public boolean isCompletelySuccessful() {
// TODO
return false;
}
}
package fr.univamu.progav.td9;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Library {
private final Map<String, Book> collection = new HashMap<>();
private final Map<Book, BookStatus> bookStatuses = new HashMap<>();
public void addBook(Book book) {
collection.put(book.isbn(), book);
bookStatuses.put(book, BookStatus.AVAILABLE);
}
public Book findBook(String isbn) {
// TODO
return null;
}
public BookStatus getBookStatus(String isbn) {
// TODO
return null;
}
public Book checkoutBook(String isbn) {
// TODO
return null;
}
public BulkCheckoutResult checkoutBooks(List<String> isbns) {
// TODO
return null;
}
}
Ces exercices portent sur la gestion des exceptions. Le contexte est la
gestion des livres d'une bibliothèque, qui n'est pas un exemple très
pertinent pour l'utilisation d'exceptions, mais qui a l'avantage d'être
relativement simple pour apprendre les bases de la manipulation des exceptions.
La bibliothèque ```Library``` possède une collection de livres ```Book```, et
les clients peuvent venir emprunter un ou plusieurs livres (méthodes
```checkoutBook``` et ```checkoutBooks```). Un livre peut donc être
disponible ou indisponible (classe ```BookStatus```), ou bien ne pas faire
partie de la bibliothèque.
Si un client veut emprunter un livre déjà prêté, l'exception
```BookUnavailableException``` sera levée. Si le livre n'est pas possédé par la
bibliothèque, l'exception ```BookNotFoundException``` sera levée.
Exercice 1
==========
Compléter les 2 extensions ```BookNotFoundException``` (possédant un code
ISBN) et ```BookUnavailable``` (possédant un livre) de la
classe```BookException```. Assurez-vous que la méthode ```getMessage``` de
chacune délivre un message adapté et mentionnant soit le code ISBN, soit le
livre concerné.
Exercice 2
==========
Compléter la méthode ```findBook``` de la classe ```Library```. Elle doit
retourner le livre dont le code ISBN est fourni. S'il n'existe pas un tel
livre, il faut émettre l'exception ```BookNotFoundException```. Ajouter la
déclaration d'exception à la méthode.
Exercice 3
==========
Compléter la méthode ```checkBookStatus``` de la classe ```Library```,
retournant le status d'un livre précisé par son code ISBN. Si le livre
n'existe pas, l'exception ```BookNotFound``` sera émise. Ajouter la
déclaration d'exception à la méthode.
Exercice 4
==========
Compléter la méthode ```checkoutBook``` de la classe ```Library```.
La méthode vérifie l'existence et la disponibilité du livre (donné par son
code ISBN), et modifie alors son status à ```BORROWED```. Si les conditions
ne sont pas respectées, la méthode émet l'exception appropriée. Ajouter la
déclaration d'exception à la méthode.
Exercice 5
==========
Compléter la méthode ```isCompletelySuccessful``` de la classe
```BulkCheckoutResult```. Cette classe contiendra les résultats de la
réservation d'une liste de livres, comprenant :
- la liste des livres empruntés;
- la liste des échecs des tentatives d'emprunt.
Exercice 6
==========
Compléter la méthode ```checkoutBooks``` de la classe ```Library```.
Vérifier votre travail à l'aide des tests fournis.
\ No newline at end of file
package fr.univamu.progav.td5;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class WarriorTest {
@Test
void newWarrior() {
Warrior warrior = new Warrior();
assertEquals(30,warrior.getHealth());
warrior.reduceHealth(8);
assertEquals(22,warrior.getHealth());
warrior.setHealth(25);
assertEquals(25,warrior.getHealth());
}
@Test
void attack() {
Warrior warrior = new Warrior();
Blow b = warrior.attack();
assertEquals(3,b.physicalDamage());
assertEquals(0,b.magicalDamage());
}
@Test
void defend() {
Warrior warrior = new Warrior();
warrior.defend(new Blow(10,2));
assertEquals(23,warrior.getHealth());
warrior.defend(new Blow(1,5));
assertEquals(18,warrior.getHealth());
}
@Test
void specialAction() {
Warrior warrior = new Warrior();
warrior.specialAction();
Blow b = warrior.attack();
assertEquals(6,b.physicalDamage());
assertEquals(0,b.magicalDamage());
b = warrior.attack();
b = warrior.attack();
assertEquals(6,b.physicalDamage());
assertEquals(0,b.magicalDamage());
b = warrior.attack();
assertEquals(3,b.physicalDamage());
assertEquals(0,b.magicalDamage());
}
@Test
void getRage() {
Warrior warrior = new Warrior();
assertEquals(0,warrior.getRage());
warrior.specialAction();
assertEquals(3,warrior.getRage());
warrior.attack();
assertEquals(2,warrior.getRage());
warrior.specialAction();
assertEquals(3,warrior.getRage());
}
@Test
void defendIncreaseRage() {
Warrior warrior = new Warrior();
warrior.defend(new Blow(4,4));
assertEquals(0,warrior.getRage(), "Warrior does not enter rage by receiving a blow");
warrior.specialAction();
warrior.defend(new Blow(0,5));
assertEquals(4,warrior.getRage(), "Increase rage when 5 health lost");
warrior.defend(new Blow(0,4));
assertEquals(4,warrior.getRage(), "Do not increase rage when <5 health lost");
warrior.defend(new Blow(6,0));
assertEquals(4,warrior.getRage(),"Do not increase rage when <5 health lost");
}
}
\ No newline at end of file
package fr.univamu.progav.td5;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class WizardTest {
@Test
void newWizard() {
Wizard wizard = new Wizard();
assertEquals(20,wizard.getHealth());
assertEquals(0,wizard.getShield());
assertTrue(wizard.isAlive());
}
@Test
void attack() {
Wizard wizard = new Wizard();
Blow b = wizard.attack();
assertEquals(4, b.magicalDamage());
assertEquals(0, b.physicalDamage());
wizard.specialAction();
b = wizard.attack();
assertEquals(4, b.magicalDamage());
assertEquals(0,b.physicalDamage());
}
@Test
void defend() {
Wizard wizard = new Wizard();
assertEquals(20,wizard.getHealth());
wizard.defend(new Blow(6,2));
assertEquals(15,wizard.getHealth(), "Wizard loses life on physical attack, but physical damage is reduced by half of magical damage");
wizard.defend(new Blow(0,10));
assertEquals(15,wizard.getHealth(), "Wizard does not gain life on magical attack.");
}
@Test
void specialAction() {
Wizard wizard = new Wizard();
wizard.specialAction();
assertEquals(20, wizard.getHealth());
wizard.defend(new Blow(6, 2));
assertEquals(20, wizard.getHealth(), "Wizard's shield absorbs physical damage");
assertEquals(2, wizard.getShield());
wizard.defend(new Blow(6, 2));
assertEquals(
17,
wizard.getHealth(),
"Wizard's shield absorbs physical damage until depleted, then normal rules apply"
);
assertEquals(0, wizard.getShield());
}
@Test
void maxShieldValue() {
Wizard wizard = new Wizard();
wizard.specialAction();
wizard.defend(new Blow(5,0));
wizard.specialAction();
wizard.defend(new Blow(5,0));
assertEquals(3, wizard.getShield(),"Wizard's special action sets shield to 8 (not an addition)");
}
}
\ No newline at end of file
package fr.univamu.progav.td6;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
class ArrayCellLensTest {
@Test
void testGet() {
Integer[] array = {4, 3, 2, 1};
Lens<Integer> lens1 = new ArrayCellLens<>(array, 1);
assertEquals(3, lens1.get());
array[1] = 5;
assertEquals(5, lens1.get());
}
@Test
void testSet() {
Integer[] array = {4, 3, 2, 1};
Lens<Integer> lens1 = new ArrayCellLens<>(array, 1);
lens1.set(8);
assertEquals(8, lens1.get());
}
@Test
void testSetModifyArray() {
Integer[] array = {4, 3, 2, 1};
Lens<Integer> lens1 = new ArrayCellLens<>(array, 1);
lens1.set(5);
assertEquals(5, lens1.get());
assertEquals(5, array[1]);
assertEquals(4, array[0]);
assertEquals(2, array[2]);
}
}
package fr.univamu.progav.td6;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class BoxTest {
@Test
void testGet() {
Lens<Integer> box = new Box(0);
assertEquals(0,box.get());
box = new Box(42);
assertEquals(42,box.get());
}
@Test
void testSet() {
Lens<Integer> box = new Box(0);
box.set(3);
assertEquals(3,box.get());
box.set(5);
assertEquals(5,box.get());
box.set(-3);
assertEquals(-3,box.get());
}
@Test
void genericBox() {
Lens<String> box = null; // TODO créer une boîte contenant "foo"
assertEquals("foo", box.get());
box.set("bar");
assertEquals("bar", box.get());
Lens<Lens<Integer>> boxbox = null; // TODO créer une boîte contenant une boîte contenant 0
boxbox.get().set(2);
assertEquals(2,boxbox.get().get());
}
}
\ No newline at end of file
package fr.univamu.progav.td6;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
class ListCellLensTest {
@Test
void testGet() {
List<Integer> list = new ArrayList<>(List.of(4,3,2,1));
Lens<Integer> lens1 = new ListCellLens<>(list, 1);
assertEquals(3, lens1.get());
list.set(1,5);
assertEquals(5, lens1.get());
}
@Test
void testSet() {
List<Integer> list = new ArrayList<>(List.of(4,3,2,1));
Lens<Integer> lens1 = new ListCellLens<>(list, 1);
lens1.set(8);
assertEquals(8, lens1.get());
}
@Test
void testSetModifyList() {
List<Integer> list = new ArrayList<>(List.of(4,3,2,1));
Lens<Integer> lens1 = new ListCellLens<>(list, 1);
lens1.set(5);
assertEquals(5, lens1.get());
assertEquals(5, list.get(1));
assertEquals(4, list.get(0));
assertEquals(2, list.get(2));
}
}
\ No newline at end of file
package fr.univamu.progav.td7;
import org.junit.jupiter.api.Test;
import static fr.univamu.progav.td7.IntervalSequences.*;
import static org.junit.jupiter.api.Assertions.*;
class IntervalSequencesTest {
private final Sequence<Interval> seq1 = new ListSequence<>(
new Interval(2,8),
new Interval(-4,5),
new Interval(3,-2),
new Interval(-9,-3)
);
private final Sequence<Interval> seq2 = new ListSequence<>(
new Interval(0,0),
new Interval(0,10),
new Interval(-10,5),
new Interval(-3,-3)
);
private final Sequence<Interval> seqEmpty = new ListSequence<>();
@Test
void testContainsEmptyInterval() {
assertTrue(containsEmptyInterval(seq1));
assertFalse(containsEmptyInterval(seq2));
assertFalse(containsEmptyInterval(seqEmpty));
}
@Test
void testSumOfSizes() {
assertEquals(24, sumOfSizes(seq1));
assertEquals(29, sumOfSizes(seq2));
assertEquals(0, sumOfSizes(seqEmpty));
}
@Test
void testLongestInterval() {
assertEquals(10,longestInterval(seq1).size());
assertEquals(16,longestInterval(seq2).size());
assertNull(longestInterval(seqEmpty));
}
}
\ No newline at end of file
package fr.univamu.progav.td7;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import static org.junit.jupiter.api.Assertions.*;
class IntervalTest {
@Test
void contains() {
Interval range = new Interval(-2, 5);
assertTrue(range.contains(-2));
assertTrue(range.contains(0));
assertTrue(range.contains(1));
assertTrue(range.contains(4));
assertTrue(range.contains(5));
assertFalse(range.contains(-3));
assertFalse(range.contains(-30));
assertFalse(range.contains(6));
assertFalse(range.contains(42));
assertFalse(range.contains(2904429));
}
@Test
void size() {
assertEquals(5, new Interval(0,4).size());
assertEquals(0, new Interval(4,0).size());
assertEquals(6, new Interval(4,9).size());
assertEquals(7, new Interval(-7,-1).size());
assertEquals(8, new Interval(-3,4).size());
assertEquals(1, new Interval(3,3).size());
}
@Test
void isEmpty() {
assertTrue(new Interval(5,3).isEmpty());
assertTrue(new Interval(2,-5).isEmpty());
assertTrue(new Interval(0,-1).isEmpty());
assertTrue(new Interval(1,0).isEmpty());
assertFalse(new Interval(1,1).isEmpty());
assertFalse(new Interval(0,0).isEmpty());
assertFalse(new Interval(-3,3).isEmpty());
}
@Test
void intersects() {
assertTrue(new Interval(1,5).intersects(new Interval(2,3)));
assertTrue(new Interval(-5,5).intersects(new Interval(-3,-2)));
assertTrue(new Interval(-5,5).intersects(new Interval(-2,3)));
assertTrue(new Interval(-5,5).intersects(new Interval(-6,-5)));
assertTrue(new Interval(-5,5).intersects(new Interval(5,7)));
assertTrue(new Interval(-3,4).intersects(new Interval(-4,8)));
assertFalse(new Interval(-3,4).intersects(new Interval(2,-2)));
assertFalse(new Interval(-3,4).intersects(new Interval(5,8)));
assertFalse(new Interval(-3,4).intersects(new Interval(-7,-4)));
assertFalse(new Interval(-3,4).intersects(new Interval(12,35)));
assertFalse(new Interval(-3,4).intersects(new Interval(67,-21)));
}
@Test
void iterator() {
Iterator<Integer> iterator = new Interval(-2,8).iterator();
List<Integer> elements = new ArrayList<>();
while (iterator.hasNext()) {
elements.add(iterator.next());
}
assertEquals(List.of(-2,-1,0,1,2,3,4,5,6,7,8), elements);
assertThrows(NoSuchElementException.class, iterator::next, "Iterator.next() must throw NoSuchElementException when iteration is over");
iterator = new Interval(0,-1).iterator();
assertFalse(iterator.hasNext());
assertThrows(NoSuchElementException.class, iterator::next, "Iterator.next() must throw NoSuchElementException when iteration is over");
}
}
\ No newline at end of file
package fr.univamu.progav.td7;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
public class ListSequence<T> implements Sequence<T> {
// Ne pas modifier cette classe !
private final List<T> elements;
public ListSequence(List<T> elements) {
this.elements = elements;
}
@SafeVarargs
public ListSequence(T... elements) {
this.elements = Arrays.asList(elements);
}
public void forEach(Consumer<T> action) {
elements.forEach(action);
}
public boolean anyMatch(Predicate<T> predicate) {
return elements.stream().anyMatch(predicate);
}
public T maximum(Comparator<T> compare) {
return elements.stream().max(compare).orElse(null);
}
}
package fr.univamu.progav.td8;
import fr.univamu.progav.td8.ExercicesStream;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static fr.univamu.progav.td8.ExercicesStream.Person;
import static org.junit.jupiter.api.Assertions.*;
class ExercicesStreamTest {
private record MockPerson(
int age,
String name,
boolean isFemale,
Person mother,
Person father,
List<Person> children
) implements Person {
@Override
public String toString() {
return this.name;
}
}
private static final Person alfa =
new MockPerson(78,"Alfa",true,null,null, new ArrayList<>());
private static final Person bravo =
new MockPerson(82,"Bravo",false,null,null, new ArrayList<>());
private static final Person charlie =
new MockPerson(42,"Charlie",false, alfa,bravo,List.of());
private static final Person delta =
new MockPerson(38,"Delta",false, alfa,bravo, new ArrayList<>());
private static final Person echo =
new MockPerson(41,"Echo",true,null,null, new ArrayList<>());
private static final Person foxtrot =
new MockPerson(7,"Foxtrot",true,echo,delta, List.of());
private static final Person golf =
new MockPerson(25,"Golf",true,null,null, new ArrayList<>());
private static final Person hotel =
new MockPerson(2,"Hotel",false,golf,null, List.of());
private static final Person india =
new MockPerson(8,"India",true,null,null, List.of());
private static final Person juliett =
new MockPerson(18,"Juliett",false,null,null,List.of());
static {
alfa.children().addAll(List.of(charlie, delta));
bravo.children().addAll(List.of(charlie, delta));
delta.children().add(foxtrot);
echo.children().add(foxtrot);
golf.children().add(hotel);
}
private static final List<Person> ALL =
List.of(alfa,bravo,charlie,delta,echo,foxtrot,golf,hotel,india,juliett);
private static Stream<Person> femaleStream() {
return Stream.of(alfa, echo, foxtrot, golf, india);
}
private static Stream<Person> maleStream() {
return Stream.of(bravo,charlie,delta,hotel,juliett);
}
@Test
void hasFemale() {
assertTrue(ExercicesStream.hasFemale(ALL.stream()));
assertFalse(ExercicesStream.hasFemale(Stream.of(bravo,charlie,delta)));
assertTrue(ExercicesStream.hasFemale(Stream.of(alfa)));
assertFalse(ExercicesStream.hasFemale(Stream.of()), "Cas de la stream vide");
}
@Test
void containsMinorMale() {
assertTrue(ExercicesStream.containsMinorMale(ALL.stream()));
assertFalse(ExercicesStream.containsMinorMale(Stream.of(bravo,charlie,delta)), "Pas de mineurs");
assertFalse(ExercicesStream.containsMinorMale(Stream.of(foxtrot,india)), "Pas d'hommes");
assertFalse(ExercicesStream.containsMinorMale(Stream.of()), "Cas de la stream vide");
}
@Test
void findMother() {
Optional<Person> found = ExercicesStream.findMother(ALL.stream());
assertTrue(found.isPresent());
assertTrue(found.get().isFemale() && !found.get().children().isEmpty());
assertEquals(Optional.of(golf),ExercicesStream.findMother(Stream.of(bravo,charlie,delta,golf,hotel,india)));
assertEquals(Optional.empty(), ExercicesStream.findMother(Stream.of(bravo,charlie,delta,foxtrot,hotel,india)));
assertEquals(Optional.empty(), ExercicesStream.findMother(Stream.of()), "Cas de la stream vide");
}
@Test
void areAllMajor() {
assertFalse(ExercicesStream.areAllMajor(ALL.stream()));
assertTrue(ExercicesStream.areAllMajor(Stream.of(alfa,bravo,charlie,delta,echo,golf)));
assertTrue(ExercicesStream.areAllMajor(Stream.of(alfa,bravo,charlie,delta,echo,golf,juliett)), "Cas d'un individu ayant 18 ans");
assertFalse(ExercicesStream.areAllMajor(Stream.of(foxtrot,hotel,india)));
assertTrue(ExercicesStream.areAllMajor(Stream.of()), "Cas de la stream vide");
}
@Test
void ageOfSomeChild() {
Optional<Integer> maybeAge =
ExercicesStream.ageOfSomeChild(Stream.of(hotel, india, juliett, alfa, foxtrot, charlie));
assertTrue(maybeAge.isPresent());
assertTrue(List.of(charlie.age(),delta.age()).contains(maybeAge.get()));
assertTrue(ExercicesStream.ageOfSomeChild(Stream.of(charlie,foxtrot,hotel,india,juliett)).isEmpty());
assertTrue(ExercicesStream.ageOfSomeChild(Stream.of()).isEmpty(),"Cas de la stream vide");
}
@Test
void males() {
List<Person> allMales = ExercicesStream.males(ALL.stream());
List<Person> expected = ALL.stream().filter(p -> !p.isFemale()).toList();
assertNotNull(allMales);
assertEquals(expected.size(), allMales.size(), "Nombre d'hommes incorrect");
for (Person p : expected ) {
assertTrue(allMales.contains(p), p.name() + " est un homme qui n'est pas dans la stream");
}
List<Person> neitherMaleNorFemale = ExercicesStream.males(femaleStream());
assertNotNull(neitherMaleNorFemale);
assertTrue(neitherMaleNorFemale.isEmpty());
List<Person> empty = ExercicesStream.males(Stream.of());
assertNotNull(empty, "Cas de la stream vide");
assertTrue(empty.isEmpty(), "Cas de la stream vide");
}
@Test
void nbFemales() {
assertEquals(0,ExercicesStream.nbFemales(Stream.of()), "Cas de la stream vide");
assertEquals(5,ExercicesStream.nbFemales(ALL.stream()));
assertEquals(0,ExercicesStream.nbFemales(maleStream()));
}
@Test
void eldest() {
assertTrue(ExercicesStream.eldest(Stream.of()).isEmpty(), "Cas de la stream vide");
assertEquals(Optional.of(bravo),ExercicesStream.eldest(ALL.stream()));
}
@Test
void names() {
String allNames = ExercicesStream.names(ALL.stream()).trim();
assertEquals("Alfa Bravo Charlie Delta Echo Foxtrot Golf Hotel India Juliett",allNames);
assertEquals("",ExercicesStream.names(Stream.of()), "Cas de la liste vide");
}
@Test
void hasAsManyMalesAsFemales() {
assertTrue(ExercicesStream.hasAsManyMalesAsFemales(Stream.of()), "Cas de la liste vide");
assertFalse(ExercicesStream.hasAsManyMalesAsFemales(Stream.of(alfa)));
assertFalse(ExercicesStream.hasAsManyMalesAsFemales(Stream.of(bravo)));
assertFalse(ExercicesStream.hasAsManyMalesAsFemales(femaleStream()));
assertFalse(ExercicesStream.hasAsManyMalesAsFemales(maleStream()));
assertTrue(ExercicesStream.hasAsManyMalesAsFemales(ALL.stream()));
}
@Test
void averageAge() {
assertTrue(ExercicesStream.averageAge(Stream.of()).isEmpty(), "Cas de la liste vide");
OptionalDouble average = ExercicesStream.averageAge(ALL.stream());
assertTrue(average.isPresent());
double expected = 34.1;
assertTrue(Math.abs(average.getAsDouble() - expected) < 0.1, "La moyenne correcte est " + expected);
}
}
\ No newline at end of file
package fr.univamu.progav.td9;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
public class LibraryTest {
private Library library;
private Book book1;
private Book book2;
private Book book3;
@BeforeEach
void setUp() {
library = new Library();
book1 = new Book("123", "Livre 1");
book2 = new Book("456", "Livre 2");
book3 = new Book("789", "Livre 3");
library.addBook(book1);
library.addBook(book2);
library.addBook(book3);
}
@Test
void testFindBookThrowsException() {
assertThrows(BookNotFoundException.class, () -> {
library.findBook("999");
});
}
@Test
void testSingleCheckoutSuccess() throws BookException {
library.checkoutBook("123");
assertEquals(BookStatus.BORROWED, library.getBookStatus("123"));
}
@Test
void testBulkCheckoutPartialSuccess() throws BookException {
library.checkoutBook("123");
Book nonExistentBook = new Book("999", "Nonexistent");
List<String> booksToCheckout = List.of("123", "456", "999");
BulkCheckoutResult result = library.checkoutBooks(booksToCheckout);
assertFalse(result.isCompletelySuccessful());
assertEquals(1, result.successfulCheckouts().size());
assertEquals(2, result.failedCheckouts().size());
assertInstanceOf(BookUnavailableException.class, result.failedCheckouts().get(0));
assertInstanceOf(BookNotFoundException.class, result.failedCheckouts().get(1));
assertEquals(
"Livre 1 (123): book unavailable",
result.failedCheckouts().get(0).getMessage()
);
assertEquals(
"Nonexistent (999): book not found",
result.failedCheckouts().get(1).getMessage()
);
}
@Test
void testBulkCheckoutAllSuccess() {
List<String> booksToCheckout = List.of("123", "456");
BulkCheckoutResult result = library.checkoutBooks(booksToCheckout);
assertTrue(result.isCompletelySuccessful());
assertEquals(2, result.successfulCheckouts().size());
assertTrue(result.failedCheckouts().isEmpty());
}
}