Add oving 5
This commit is contained in:
45
oppgavetekster/oving5/BinaryComputingIterator.md
Normal file
45
oppgavetekster/oving5/BinaryComputingIterator.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Interface - BinaryComputingIterator
|
||||
|
||||
Denne oppgaven handler om en meta-iterator som kombinerer par av verdier fra to iteratorer til en ny iterator-sekvens ved hjelp av en gitt binær operasjon.
|
||||
|
||||
Meta-iteratorer er iteratorer som bruker andre iteratorer som datakilder.
|
||||
|
||||
Du skal lage en ny klasse `BinaryComputingIterator`, som er en *implementasjon* av det innebygde `Iterator<Double>`-grensesnittet. Konstruktøren til `BinaryComputingIterator` skal ta inn to iteratorer og en binær operator, samt to valgfrie standardverdier. Når `next()`-metoden til `BinaryComputingIterator` blir kalt, skal en verdi hentes fra hver av de to iteratorene, den binære operasjonen utføres på disse to verdiene og resultatet returneres. Den binære operasjonen skal spesifiseres ved hjelp av det innebygde `BinaryOperator<Double>`-grensesnittet, som har en `apply`-metode som lar en beregne resultatet av den binære operasjonen. Hvordan en kan opprette funksjonelle grensesnitt kan du lese mer om på [wikisiden om dette](https://www.ntnu.no/wiki/display/tdt4100/Lambda-uttrykk+og+funksjonelle+grensesnitt+i+Java+8).
|
||||
|
||||
## BinaryComputingIterator
|
||||
|
||||
Klassen skal ha to konstruktører, en med og en uten standardverdier:
|
||||
|
||||
- `BinaryComputingIterator(Iterator<Double> iterator1, Iterator<Double> iterator2, BinaryOperator<Double> operator)`. Ingen av argumentene kan være `null`.
|
||||
- `BinaryComputingIterator(Iterator<Double> iterator1, Iterator<Double> iterator2, Double default1, Double default2, BinaryOperator<Double> operator)`.
|
||||
|
||||
Her er `iterator1` og `iterator2` iteratorene som blir kombinert av `BinaryComputingIterator`, og `default1` og `default2` er standardverdier for de respektive iteratorene. Klassen må ha følgende metoder, begge spesifisert av `Iterator<Double>`-grensesnittet: Hvordan en lager en `BinaryOperator` klasse kan du se mer om lenger ned i oppgaveteksten.
|
||||
|
||||
- `boolean hasNext()` - returnerer true dersom det kan beregnes flere verdier, altså hvis begge iteratorene enten har flere verdier eller har en tilhørende standardverdi. Men merk at `hasNext()` returnerer uansett `false` hvis begge iteratorene er tomme.
|
||||
- `Double next()` - returnerer resultatet av å bruke binæroperasjonen operator på de neste verdiene fra sub-iteratorene, og bruker standardverdier dersom en av iteratorene ikke har flere verdier.
|
||||
|
||||
Husk at ved hjelp av Java 8-syntaks kan en implementasjon av BinaryOperator skrives som `(num1, num2) -> <uttrykk>`, der `<uttrykk>` er et Java-uttrykk som brukes `num1` og `num2`. Hvis BinaryComputerIterator henter verdier fra to iteratorer med hhv. verdiene `1`, `2`, `3` og `3`, `4`, `5` og den binære operatoren er `(num1, num2) -> num1 + num2`, så skal sekvensen en får ut være `4`, `6`, `8`.
|
||||
|
||||
For å håndtere tilfellet hvor den ene iteratoren gir ut flere verdier enn den andre, så skal det være mulig å gi standardverdier hhv. `default1` og `default2` for `iterator1` og `iterator2`, som vil bli brukt for å fylle inn manglende verdier. Hvis `BinaryComputerIterator` henter verdier fra to iteratorer med hhv. verdiene `6`, `3`, `0` og `3`, `4` og den binære operatoren er `(num1, num2) -> num1 - num2` og `default2` er `2`, så skal sekvensen en får ut være `3`, `-1`, `-2`.
|
||||
|
||||
### Eksempel
|
||||
|
||||
`BinaryOperator`-implementasjoner kan lett skrive ved hjelp av Java 8 sin funksjonsnotasjon. Dersom man for eksempel vil bruke en addisjonsoperator kan det se slik ut:
|
||||
|
||||
```java
|
||||
Iterator<Double> iterator1 = List.of(2.0, 3.0).iterator();
|
||||
Iterator<Double> iterator2 = List.of(5.0).iterator();
|
||||
|
||||
BinaryOperator<Double> addition = (a, b) -> a + b;
|
||||
|
||||
// Opprett en ny BinaryComputingIterator som tar inn iterator1 og iterator2 og utfører addisjon
|
||||
// på verdiene.
|
||||
BinaryComputingIterator binaryIterator = new BinaryComputingIterator(iterator1, iterator2, null, 10.0, addition);
|
||||
|
||||
binaryIterator.next(); // 7.0
|
||||
binaryIterator.hasNext(); // true
|
||||
binaryIterator.next(); // 13.0
|
||||
binaryIterator.hasNext(); // false
|
||||
```
|
||||
|
||||
Testkode for BinaryComputingIterator er her: [oving5/BinaryComputingIteratorTest.java](../../src/test/java/oving5/BinaryComputingIteratorTest.java).
|
||||
38
oppgavetekster/oving5/CardComparison.md
Normal file
38
oppgavetekster/oving5/CardComparison.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Interface - CardComparison-oppgave
|
||||
|
||||
Denne oppgaven hander om to måter å håndtere sortering av `Card`-objekter, med grensesnittene `Comparable` og `Comparator`, som er innebygd i Java (`java.util.Comparable`, `java.util.Comparator`).
|
||||
|
||||
Vi tar i denne oppgaven utgangspunkt i `Card`-klassen fra [Innkapsling - Card-oppgave](../oving3/Card.md). Et `Card`-objekt har en kortfarge (av typen `char`) og verdi (`int`), og sortering gjøres på disse verdiene, ved at en først sorterer på kortfarge og så på verdi. Siden Java har sorteringsmetoder innebygd trenger vi ikke bry oss om selve sorteringsalgoritmen. Vi fokuserer her på logikken for *sammenligning* av `Card`-objekter, altså hvilke `Card` som skal komme før/etter andre.
|
||||
|
||||
Dersom du ikke har gjort `Card`-oppgaven allerede, bør du gjøre denne først. Hvis du ikke har gjort det, kan du kopiere koden fra [løsningsforslaget](https://git.ntnu.no/tdt4100/tdt4100-lf-25/blob/main/src/main/java/oving3/card/Card.java), som kommer til å være tilgjengelig etter siste demonstrasjonsfrist for øving 3.
|
||||
|
||||
Filen i denne oppgaven skal ligge i [`oving5/card`](../../src/main/java/oving5/card).
|
||||
|
||||
## Del 1
|
||||
|
||||
La `Card`-klassen implementere `Comparable` med følgende sammenligningslogikk
|
||||
|
||||
- `compareTo`-metoden skal sammenligne et kort med et annet, slik at:
|
||||
- Spar kommer etter hjerter.
|
||||
- Hjerter kommer etter ruter.
|
||||
- Ruter kommer etter kløver.
|
||||
- Ved lik kortfarge skal verdien brukes i stigende rekkefølge, altså $1$ (ess) kommer før $2$, kommer før $3$ osv. til og med $11$ (knekt), $12$ (dame) og $13$ (konge).
|
||||
|
||||
Skriv testkode som sorterer kort i en liste vha. `Collections.sort` og `Comparable`-logikken, og verifiser at sammenligningslogikken er riktig implementert.
|
||||
|
||||
*Hint:* Returner `-1` for å sette kortet `this` før kortet som blir gitt inn, `0` dersom de er like, og `1` dersom `this` skal komme etter det gitte kortet.
|
||||
|
||||
## Del 2
|
||||
|
||||
For å kunne sortere `Card`-objekter med annen logikk, så kan en bruke grensesnittet `Comparator`, som er et objekt som kan sammenligne objekter parvise. Implementer en `Comparator` (dvs. lag en klasse som *implements* `Comparator`) kalt `CardComparator`, som kan konfigureres (stilles inn) til å sortere med ess som høyeste kort og med en bestemt kortfarge som trumf, altså en kortfarge som regnes som høyere enn de andre.
|
||||
|
||||
- `CardComparator` må ha en konstruktør som tar inn en `boolean` og en `char`. Det første argumentet sier om ess skal regnes som størst (`true`) eller minst (`false`), mens det andre argumentet angir hvilke kortfarge som er trumf. F.eks. skal et `CardComparator`-objekt laget med `new CardComparator(true, ' ')` rangere ess høyere enn konge og bruke standard rangering av kortfarger (siden trumf-argumentet ikke er en av kortfargene), og et `CardComparator`-objekt laget med `new CardComparator(false, 'C')` rangerer ess lavest og kløver (`'C'` = clubs) høyest av kortfargene (de andre kortfargene har standard rangering med spar over hjerter over ruter).
|
||||
|
||||
Skriv testkode som sorterer kort i en liste vha. `Collections.sort` og `Comparator-logikken`, og verifiser at sammenligningslogikken er riktig implementert.
|
||||
|
||||
Testkode for del 1 og del 2 finner du her: [oving5/card/CardComparatorTest.java](../../src/test/java/oving5/card/CardComparatorTest.java).
|
||||
|
||||
## Valgfri Ekstraoppgave
|
||||
|
||||
Utvid `CardComparator` slik at den kan konfigureres med en annen rangering av kortfargene, f.eks. slik at kløver er høyere enn ruter.
|
||||
Merk at denne fortsatt skal overstyres av evt. trumf. Nytten er altså at en kan endre rangeringsrekkefølgen på alle på én gang.
|
||||
30
oppgavetekster/oving5/CardContainer.md
Normal file
30
oppgavetekster/oving5/CardContainer.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# Interface - CardContainer-oppgave
|
||||
|
||||
Denne oppgaven handler om å lage et felles grensesnitt for `CardDeck`- og `CardHand`-klassene, laget i oppgavene [Innkapsling - Card-oppgave](../oving3/Card.md) og [Objektstrukturer - Card-oppgave del 2](../oving4/Card.md). Her skal du lage og implementere et grensenitt kalt `CardContainer`, som spesifiserer metoder for lesing av samlinger av Card-objekter.
|
||||
|
||||
Dersom du ikke har gjort `Card`-oppgaven allerede, bør du gjøre denne først. Hvis du ikke har gjort det, kan du kopiere koden fra [løsningsforslaget](https://git.ntnu.no/tdt4100/tdt4100-lf-25/blob/main/src/main/java/oving4/card), som kommer til å være tilgjengelig etter siste demonstrasjonsfrist for øving 4.
|
||||
|
||||
Filene i denne oppgaven skal ligge i [`oving5/card`](../../src/main/java/oving5/card).
|
||||
|
||||
## Del 1 - CardContainer interface
|
||||
|
||||
Definer et `CardContainer`-grensesnitt, med metodene som er felles for `CardHand` og `CardDeck`:
|
||||
|
||||
- `int getCardCount()` - returnerer antall kort som dette objektet inneholder.
|
||||
- `Card getCard(int n)` - returnerer kort nr. `n` i dette objektet.
|
||||
|
||||
Gjør nødvendig endringer i `CardHand`- og `CardDeck`-klassene for å implementere `CardContainer`-grensesnittet.
|
||||
|
||||
## Del 2 - Iterator for CardContainer
|
||||
|
||||
Lag en klasse kalt `CardContainerIterator`, som er en [`Iterator`](https://www.ntnu.no/wiki/display/tdt4100/Iterasjon+med+Iterator+og+Iterable) for alle klasser som implementerer `CardContainer`-grensesnittet. `CardContainerIterator` må ha en konstruktør som tar inn en instans av (en klasse som implementerer) `CardContainer`. Du kan gjøre dette ved å ta inn et argument av typen `CardContainer`, altså `CardContainerIterator(CardContainer cardContainer) { ... }`.
|
||||
|
||||
*Hint*: Merk at `CardContainerIterator` ikke vet om `CardContainer`-objektet er et `CardDeck`-objekt, et `CardHand`-objekt eller et annet objekt som implementerer `CardContainer`. Den har derfor ikke tilgang til de interne listene i `CardHand` og `CardDeck`. Hvilke metoder må alle klasser som implementerer `CardContainer` ha, og hvordan kan disse metodene brukes for å lage en [`Iterator`](https://www.ntnu.no/wiki/display/tdt4100/Iterasjon+med+Iterator+og+Iterable)?
|
||||
|
||||
Testkode for oppgaven finner du her: [oving5/card/CardContainerIteratorTest.java](../../src/test/java/oving5/card/CardContainerIteratorTest.java).
|
||||
|
||||
## Del 3 - Iterable
|
||||
|
||||
La `CardContainer`-grensesnittet utvide (`extends`) `Iterable<Card>` og la `iterator()`-metoden som dermed kreves, returnere en korrekt konfigurert instans av `CardContainerIterator`.
|
||||
|
||||
Testkode for oppgaven finner du her: [oving5/card/CardDeckTest.java](../../src/test/java/oving5/card/CardDeckTest.java) og [oving5/card/CardHandTest.java](../../src/test/java/oving5/card/CardHandTest.java).
|
||||
19
oppgavetekster/oving5/CardPredicate.md
Normal file
19
oppgavetekster/oving5/CardPredicate.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Interface - CardPredicate-oppgave
|
||||
|
||||
Denne oppgaven handler om hvordan en kan bruke det funksjonelle `Predicate<T>`-grensesnittet, sammen med `CardDeck`-klassen. Vi tar i denne oppgaven utgangspunkt i `CardDeck`-klassen fra [Innkapsling - Card-oppgave](../oving3/Card.md). Et `CardDeck`-objekt har en liste med `Card`-objekter. `Card` har en kortfarge (av typen `char`) og verdi (`int`), og vi ønsker å lage metoder i `CardDeck` som søker opp `Card`-objekter som tilfredsstiller visse kriterier, f.eks. sjekker om spar dame finnes, teller antall hjerter eller henter ut alle ess. For å representere selve kriteriet brukes [`Predicate<T>`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/function/Predicate.html)-grensesnittet, som handler om å teste/sjekke om et objekt tilfredsstiller visse kriterium.
|
||||
|
||||
Dersom du ikke har gjort `Card`-oppgaven allerede, bør du gjøre denne først. Hvis du ikke har gjort det, kan du kopiere koden fra [løsningsforslaget](https://git.ntnu.no/tdt4100/tdt4100-lf-25/blob/main/src/main/java/oving3/card/Card.java), som kommer til å være tilgjengelig etter siste demonstrasjonsfrist for øving 3.
|
||||
|
||||
Filen i denne oppgaven skal ligge i [`oving5/card`](../../src/main/java/oving5/card).
|
||||
|
||||
**Implementer** følgende metoder i `CardDeck`-klassen:
|
||||
|
||||
- `List<Card> getCards(Predicate<Card> predicate)` - Skal returnere en liste med de kortene som tilfredsstiller `predicate`. Argumentet kan ikke være `null` for noen av metodene.
|
||||
- `int getCardCount(Predicate<Card> predicate)` - Skal returnere hvor mange kort som tilfredsstiller `predicate`.
|
||||
- `boolean hasCard(Predicate<Card> predicate)` - Skal returnere `true` dersom det finnes et kort som tilfredsstiller `predicate`, `false` ellers.
|
||||
|
||||
Lag også din egen `main()`-metode hvor du prøver hver av de tre metodene over. Du skal altså sjekke om spar dame finnes, telle antall hjerter og hente ut alle ess.
|
||||
|
||||
Testkode for oppgaven finner du her: [oving5/card/CardPredicateTest.java](../../src/test/java/oving5/card/CardPredicateTest.java).
|
||||
|
||||
Hvordan en kan opprette funksjonelle grensesnitt kan du se på [wikisiden](https://www.ntnu.no/wiki/display/tdt4100/Lambda-uttrykk+og+funksjonelle+grensesnitt+i+Java+8) om dette.
|
||||
38
oppgavetekster/oving5/Named.md
Normal file
38
oppgavetekster/oving5/Named.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Interface - Named-oppgave
|
||||
|
||||
Denne oppgaven handler om et grensnitt (interface) for person-navn og hvordan slike implementeres og sorteres med grensesnittet `Comparator`.
|
||||
|
||||
I denne oppgaven tar vi utgangspunkt i at en person har et navn (`String`) bestående av fornavn ("given name") og etternavn ("family name") som sammen gir personens fulle navn ("full name").
|
||||
|
||||
Filene i denne oppgaven skal ligge i [`oving5/named`](../../src/main/java/oving5/named).
|
||||
|
||||
## Del 1
|
||||
|
||||
Definer et grensesnitt `Named` med følgende metoder:
|
||||
|
||||
- `void setGivenName(String)` og `String getGivenName()` for å sette og hente fornavn.
|
||||
- `void setFamilyName(String)` og `String getFamilyName()` for å sette og hente etternavn.
|
||||
- `void setFullName(String)` og `String getFullName()` for å sette og hente personens hele navn. Argumentet til set-metoden skal være fornavn og etternavn skilt med mellomrom. Tilsvarende skal get-metoden returnere fornavn og etternavn skilt med mellomrom.
|
||||
|
||||
## Del 2
|
||||
|
||||
Lag klassene `Person1` og `Person2` som begge implementerer grensesnittet `Named`. `Person1`-klassen skal ha felter for for- og etternavn (altså `givenName` og `familyName`) og en konstruktør som tar inn to tilsvarende argumenter. `Person2` skal ha ett felt for fullt navn (`fullName`) og en konstruktør som tar inn det fulle navnet. Begge skal imidlertid implementere samme logikk, dvs. ha get- og set-metoder for fornavn, etternavn og fullt navn. Man kan anta at brukeren oppretter `Person1` og `Person2`-objekter med gyldige navn, altså trenger man ikke å implementere valideringsmetoder.
|
||||
|
||||
## Del 3
|
||||
|
||||
For å kunne sammenligne `Named`-objekter, f.eks. for å sortere en kontaktliste, kan du lage en klasse kalt `NamedComparator`, som implementerer grensesnittet [`Comparator`](https://www.ntnu.no/wiki/display/tdt4100/Sortering+med+Comparable+og+Comparator). `NamedComparator`-objektet skal brukes for å sammenligne navn parvis: Først på etternavn og deretter på fornavn om etternavnene er like. Dette kan gjøres ved å la `NamedComparator`-klassen implementere metoden `int compare(Named named1, Named named2)` med følgende logikk:
|
||||
|
||||
- Dersom etternavnene er ulike skal metoden:
|
||||
- returnere et negativt heltall om det første etternavnet er alfabetisk ordnet før det andre,
|
||||
- eller et positivt heltall i motsatt tilfelle.
|
||||
- Dersom etternavnene er like skal metoden gjøre det samme på fornavnene. Dersom også fornavnene er like skal metoden returnere 0.
|
||||
|
||||
Skriv testkode som bruker `Collections.sort`-metoden på en `ArrayList<Named>`, for å teste om `NamedComparator`-klassen har implementert [`Comparator`](https://www.ntnu.no/wiki/display/tdt4100/Sortering+med+Comparable+og+Comparator) riktig.
|
||||
|
||||
[Hint om sammenligning av strenger](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html#compareTo(java.lang.String)).
|
||||
|
||||
Testkode for oppgavene finner du her:
|
||||
|
||||
- [oving5/named/NamedComparatorTest.java](../../src/test/java/oving5/named/NamedComparatorTest.java),
|
||||
- [oving5/named/Person1Test.java](../../src/test/java/oving5/named/Person1Test.java),
|
||||
- [oving5/named/Person2Test.java](../../src/test/java/oving5/named/Person2Test.java).
|
||||
49
oppgavetekster/oving5/README.md
Normal file
49
oppgavetekster/oving5/README.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Øving 5: Grensesnitt
|
||||
|
||||
## Øvingsmål
|
||||
|
||||
- Lære hva grensesnitt er og hvordan disse defineres
|
||||
- Lære hvordan man implementerer et grensesnitt
|
||||
- Kjenne til grunnleggende funksjonelle grensesnitt
|
||||
|
||||
## Øvingskrav
|
||||
|
||||
- Kunne lage grensesnitt og implementere disse med andre klasser
|
||||
- Kunne bruke grensesnittene `Comparable<T>` og `Comparator<T>`
|
||||
- Kunne bruke grensesnittene `Iterable<T>` og `Iterator<T>`
|
||||
|
||||
## Dette må du gjøre
|
||||
|
||||
### Del 1: Programmering
|
||||
|
||||
Gjør **minst to** av oppgavene under, for å få 2 poeng må det gjøres **minst fire** av oppgavene under, og minst en av dem må være markert som vanskelig. Oppgavene skal lagres i [`src/main/java/oving5`](../../src/main/java/oving5).
|
||||
|
||||
- [TicketControl](./TicketControl.md) (Lett)
|
||||
- [CardContainer](./CardContainer.md) (Lett)
|
||||
- [CardPredicate](./CardPredicate.md) (Lett)
|
||||
- [CardComparison](./CardComparison.md) (Medium)
|
||||
- [Twitter](./Twitter.md) (Medium)
|
||||
- [Named](./Named.md) (Medium)
|
||||
- [BinaryComputingIterator](./BinaryComputingIterator.md) (Vanskelig)
|
||||
- [StringGrid](./StringGrid.md) (Vanskelig)
|
||||
- [RPNKalkulator med funksjonelle grensesnitt](./RPNCalc.md) (Vanskelig)
|
||||
|
||||
Alle oppgavene er høyst eksamensrelevante. Vi har imidlertid valgt å trappe ned kravene for `Iterator`, så spesielt `StringGrid` går dypere i temaet enn dere kan forvente å se på eksamen.
|
||||
|
||||
### Del 2: Debugging
|
||||
|
||||
Gjør følgende oppgave om debugging og vis frem løsningen til studass på sal:
|
||||
|
||||
- [StringMergingIterator](./StringMergingIterator.md)
|
||||
|
||||
### Del 3: Sekvensdiagram
|
||||
|
||||
Lag et [sekvensdiagram](https://www.ntnu.no/wiki/display/tdt4100/Sekvensdiagrammer) som viser samhandlingen mellom et `StringMergingIterator`-objekt og dens argumenter. Dvs. lag et [sekvensdiagram](https://www.ntnu.no/wiki/display/tdt4100/Sekvensdiagrammer) som viser hvordan `StringMergingIterator` gjennom metodekall fletter verdiene fra de to gitte iteratorene (som blir tatt inn som argumentene til `StringMergingIterator`-objektet). Du trenger ikke å levere inn diagrammet på Blackboard.
|
||||
|
||||
### Hjelp / mistanke om bugs
|
||||
|
||||
Ved spørsmål eller behov for hjelp konsulter studassen din i saltiden hans / hennes. Du kan også oppsøke andre studasser på sal eller legge ut et innlegg på [Piazza](https://piazza.com/ntnu.no/spring2025/tdt4100).
|
||||
|
||||
### Godkjenning
|
||||
|
||||
Last opp kildekode på Blackboard innen den angitte innleveringsfristen. Innlevert kode skal demonstreres for en læringsassistent innen én uke etter innleveringsfrist. Se for øvrig Blackboard-sidene for informasjon rundt organisering av øvingsopplegget og det tilhørende øvingsreglementet.
|
||||
25
oppgavetekster/oving5/RPNCalc.md
Normal file
25
oppgavetekster/oving5/RPNCalc.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Interface - RPNKalkulator med funksjonelle grensesnitt
|
||||
|
||||
Denne oppgaven handler om å gjøre det enklere å utvide en kalkulator ved å bruke det innebygde funksjonelle grensesnittet `BinaryOperator<T>`, sammen med `RPNCalc`-klassen.
|
||||
|
||||
Vi tar i denne oppgaven utgangspunkt i `RPNCalc`-klassen fra [Øving 3 - RPN-kalkulator](../oving3/RPNCalc.md)-oppgave, men det er ikke strengt nødvendig å ha gjort denne på forhånd. Et `RPNCalc`-objekt består av en stack med tall, metoder for å håndtere stacken, og `performOperation(char)` metoden, som utfører en operasjon gitt av parameteret. For eksempel vil kallet `performOperation('*')` fjerne de to øverste tallene fra stacken, multiplisere dem, og pushe resultatet på toppen av stacken. Om operasjonene hardkodes i metoden, vil det være vanskelig å endre hva kalkulatoren kan gjøre under kjøring. Denne oppgaven går derfor ut på å gjøre det mulig å legge til og fjerne operasjoner fra kalkulatoren. Operasjoner på en og to flyttall kan representeres ved bruk av henholdsvis `UnaryOperator<Double>`- og `BinaryOperator<Double>`-grensesnittene, og operasjoner uten operander (f.eks. pi) kan representeres ved bruk av `Supplier<Double>`.
|
||||
|
||||
Implementer følgende metoder i `RPNCalc`-klassen:
|
||||
|
||||
- `boolean addOperator(char, BinaryOperator<Double>)` - legger til en operator som virker på to tall (f.eks `+`) hvis operatoren ikke allerede er lagt til. Returner `true` hvis den nye operatoren blir lagt til. Operatoren kan ikke være `null`.
|
||||
- `void removeOperator(char operator)` - fjerner operatoren med tegn `operator`.
|
||||
|
||||
Du må også oppdatere `performOperation(char)` til å bruke operatorene som legges til via metodene over. Om man prøver å kalle `performOperation` med en operator som ikke er lagt til skal det utløses et `UnsupportedOperationException`-unntak.
|
||||
|
||||
## Valgfri Ekstraoppgave
|
||||
|
||||
Utvid programmet til å kunne ta inn operatorer som tar inn et parameter (`UnaryOperator<Double>`, f.eks. `|` (absoluttverdi)) og ingen parametre (`Supplier<Double>`, f.eks. `p` (pi)). Husk at du må håndtere forsøk på å legge til samme operator i flere kategorier (f.eks. om man prøver å legge til `+` som både `UnaryOperator` og `BinaryOperator` må det håndteres på en god måte).
|
||||
|
||||
Dette vil innebære å legge til metodene:
|
||||
|
||||
- `boolean addOperator(char, UnaryOperator<Double>)`
|
||||
- `boolean addOperator(char, Supplier<Double>)`
|
||||
|
||||
som fungerer på samme måte som `addOperator(char, BinaryOperator<Double>)`, samt å oppdatere resten av koden til å fungere med de forskjellige operatortypene.
|
||||
|
||||
Testkode finner du her: [oving5/RPNCalcTest.java](../../src/test/java/oving5/RPNCalcTest.java).
|
||||
73
oppgavetekster/oving5/StringGrid.md
Normal file
73
oppgavetekster/oving5/StringGrid.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# Interface - StringGrid-oppgave
|
||||
|
||||
Denne oppgaven handler om et grensnitt (interface) for rutenett som holder strenger (StringGrid), hvordan slike implementeres og hvordan en kan iterere gjennom et slikt rutenett ved hjelp av en [`Iterator`](https://www.ntnu.no/wiki/display/tdt4100/Iterasjon+med+Iterator+og+Iterable).
|
||||
|
||||
I denne oppgaven tar vi utgangspunkt i et `StringGrid`-grensesnitt som definerer metodene til et rutenett som holder strenger. Et rutenett er firkantet og består av et antall rader og kolonner. Det skal være mulig å spørre rutenettet hvilken streng som er på angitt rad og kolonne i tillegg til å endre strengen på angitt rad og kolonne. Denne oppførselen er oppsummert i det definerte `StringGrid`-grensesnittet under:
|
||||
|
||||
Filene i denne oppgaven skal ligge i [`oving5/stringgrid`](../../src/main/java/oving5/stringgrid).
|
||||
|
||||
```java
|
||||
package oving5.stringgrid;
|
||||
|
||||
/**
|
||||
* An interface with methods for managing the content of a String grid. The grid has a number of
|
||||
* rows (the grid's height) and columns (the grid's width). In each cell in the grid there is a
|
||||
* String that can be set with the setElement method and read with the getElement method.
|
||||
*/
|
||||
public interface StringGrid {
|
||||
|
||||
// Returns the number of rows in this StringGrid
|
||||
int getRowCount();
|
||||
|
||||
// Returns the number of columns in this StringGrid
|
||||
int getColumnCount();
|
||||
|
||||
// Returns the String at the given row and column. Throws an IllegalArgumentException if the
|
||||
// row or column is out of range
|
||||
String getElement(int row, int column);
|
||||
|
||||
// Sets the String at the given row and column. Throws an IllegalArgumentException if the row
|
||||
// or column is out of range
|
||||
void setElement(int row, int column, String element);
|
||||
}
|
||||
```
|
||||
|
||||
Alle klasser som implementerer **StringGrid**-grensesnittet må støtte de fire definerte metodene.
|
||||
|
||||
## Del 1 - StringGrid-grensesnitt og implementerende StringGridImpl-klasse
|
||||
|
||||
Lag en `StringGridImpl`-klasse som implementerer `StringGrid`-grensesnittet definert over. Merk at grensesnitt ikke kan brukes til å spesifisere konstruktører, så du må selv definere en eller flere egnede konstruktører. Det er imidlertid nødvendig å implementere en konstruktør som tilsvarer den JUnit-testen forventer:
|
||||
|
||||
- `StringGridImpl(int rows, int columnCount)` - konstruktør som tar inn antall rader som `rows` og antall kolonner som `columnCount`.
|
||||
|
||||
Du står fritt til å velge hvordan metodene definert av grensesnittet skal implementeres så lenge de tilfredsstiller den definerte oppførselen.
|
||||
|
||||
**Hint:** Bruk en enkel `ArrayList<String>` eller en dobbel `ArrayList<ArrayList<String>>` (se wiki-siden om [todimensjonale matriser](https://www.ntnu.no/wiki/display/tdt4100/Todimensjonale+matriser)). Du kan også bruke en enkel `String[]` eller en todimensjonal `String[][]` for å lagre strengene. Implementasjonen er helt opp til deg, så lenge den oppfører seg som beskrevet i grensesnittet.
|
||||
|
||||
## Del 2 - StringGridIterator-klasse
|
||||
|
||||
Det er hensiktmessig å kunne iterere over alle elementene i et rutenett som implementerer grensesnittet `StringGrid`, f.eks. når en bygger en streng i en `toString()`-metode eller skal sjekke om et spill har blitt avsluttet/vunnet. I denne deloppgaven skal du lage en slik [`Iterator`](https://www.ntnu.no/wiki/display/tdt4100/Iterasjon+med+Iterator+og+Iterable)-implementasjon, kalt `StringGridIterator`. Denne klassen må implementere grensesnittet `Iterator<String>`, siden `StringGrid` inneholder `String`-objekter. I tillegg til metodene som er definert i `Iterator`-grensesnittet, må `StringGridIterator` ha en konstruktør som tar imot hvilken `StringGrid` det skal itereres over og i hvilken rekkefølge elementene skal returneres i. Disse verdiene må huskes, så koden i `Iterator`-metodene kan brukes dem til å styre iterasjonen. `StringGridIterator`-klassen må altså støtte følgende konstruktør/metoder:
|
||||
|
||||
- `StringGridIterator(StringGrid, boolean rowMajor)` - konstruktør som tar inn `StringGrid`-objektet som `StringGridIterator`-klassen skal iterere over i tillegg til en logisk verdi som angir om iterasjonen skal være bortover først (`rowMajor` er `true`) eller nedover først (`rowMajor` er `false`).
|
||||
- `boolean hasNext()` - returnerer `true` så lenge det er flere `String`-objekter igjen i `StringGrid`-objektet som ikke ennå er blitt iterert over (med andre ord, sjekk om du har kommet til siste rute i rutenettet).
|
||||
- `String next()` - returnerer det neste `String`-objektet i rutenettet. Hvilken `String` som er den neste, avhenger av hvordan rutenettet skal itereres (med andre ord, hvorvidt om `rowMajor` er `true` eller `false`).
|
||||
- `void remove()` - denne metoden skal bare utløse et unntak av typen `UnsupportedOperationException` siden det ikke skal være mulig å fjerne `String`-objekter fra rutenettet.
|
||||
|
||||
## Del 3 - Iterable-grensesnittet
|
||||
|
||||
Endre `StringGrid`-grensesnittet slik at det utvider (med `extends`) [`Iterable<String>`](https://www.ntnu.no/wiki/display/tdt4100/Iterasjon+med+Iterator+og+Iterable). Dette skal gjøre det mulig å skrive for-setningen under, for å gå gjennom alle elementene i rutenettet.
|
||||
|
||||
```java
|
||||
StringGrid stringGrid = ... // her initialiseres stringGrid
|
||||
|
||||
// gå gjennom alle elementene i stringGrid
|
||||
for (String s : stringGrid) {
|
||||
// gjør noe med s her
|
||||
}
|
||||
```
|
||||
|
||||
Rekkefølgen som en slik `for`-løkke går gjennom elementene på, skal være hele første rad, så hele andre rad osv. til og med siste rad.
|
||||
|
||||
Hva slags følger får det for `StringGridImpl`? Gjør nødvendige endringer i den også, og test at det virker!
|
||||
|
||||
Testkode for del 1 og del 2 finner du her: [oving5/stringgrid/StringGridTest.java](../../src/test/java/oving5/stringgrid/StringGridTest.java).
|
||||
22
oppgavetekster/oving5/StringMergingIterator.md
Normal file
22
oppgavetekster/oving5/StringMergingIterator.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Debugging - StringMergingIterator-oppgave
|
||||
|
||||
Oppgaven handler om feilsøking ("debugging") av en Iterator-implementasjon ved bruk av [**debuggeren**](https://www.ntnu.no/wiki/pages/viewpage.action?pageId=235996724) i VS Code.
|
||||
|
||||
Les først denne artikkelen om bruk av debugger i VS Code om du ikke er kjent med dette: [Kjøring av kode og debugging i VS Code](https://www.ntnu.no/wiki/pages/viewpage.action?pageId=235996724)
|
||||
|
||||
Klassen `StringMergingIterator` implementerer grensesnittet [`Iterator<String>`](https://www.ntnu.no/wiki/display/tdt4100/Iterasjon+med+Iterator+og+Iterable), og leverer annenhver verdi fra to andre iteratorer av typen `Iterator<String>`. Denne iteratoren fletter altså verdiene fra to andre gitte iteratorer, og er altså en meta-iterator. Meta-iteratorer er iteratorer som bruker andre iteratorer som datakilder.
|
||||
|
||||
`StringMergingIterator` har følgende konstruktør:
|
||||
|
||||
- `StringMergingIterator(Iterator<String> first, Iterator<String> second)`
|
||||
|
||||
Siden klassen implementerer `Iterator<String>` har den også følgende metoder:
|
||||
|
||||
- `boolean hasNext()` - returnerer `true` dersom iteratoren har flere verdier, `false` dersom det ikke er flere verdier.
|
||||
- `String next()` - returnerer den neste verdien fra iteratoren, eller utløser et `NoSuchElementException` dersom iteratoren er tom.
|
||||
|
||||
I denne oppgaven blir en implementasjon av `StringMergingIterator` sammen med et testprogram utdelt, men i implementasjonen av klassen har vi plantet en eller flere feil. Målet for oppgaven er å finne feilene i implementasjonen ved hjelp av [debuggeren](https://www.ntnu.no/wiki/pages/viewpage.action?pageId=235996724) i VS Code. Kjør programklassen `StringMergingIteratorProgram` i debug-modus, og bruk dette til å finne ut hvor `StringMergeIterator` gjør feil. Dersom programklassen lykkes med å få en flettet strøm med verdier har du funnet alle feilene.
|
||||
|
||||
Merk at du *ikke* skal gjøre noen endringer `StringMergingIteratorProgram`, men bruke dette programmet til å teste logikken i `StringMergingIterator`.
|
||||
|
||||
Programmet du skal feilsøke er `StringMergingIteratorProgram`, og du finner koden for denne i [oving5/debugging/StringMergingIteratorProgram.java](../../src/main/java/oving5/debugging/StringMergingIteratorProgram.java). Koden for `StringMergingIterator` finner du i [oving5/debugging/StringMergingIterator.java](../../src/main/java/oving5/debugging/StringMergingIterator.java).
|
||||
27
oppgavetekster/oving5/TicketControl.md
Normal file
27
oppgavetekster/oving5/TicketControl.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Interface - TicketControl-oppgave
|
||||
|
||||
Denne oppgaven handler om å lage en representasjon av billetter. Du skal lage et grensesnitt for billetter, og to klasser som implementer dette; en som representerer en enkeltbillett og en som representerer en periodebillett.
|
||||
|
||||
Filene i denne oppgaven skal ligge i [`oving5/ticket`](../../src/main/java/oving5/ticket).
|
||||
|
||||
## Del 1 - Ticket-grensesnitt
|
||||
|
||||
Lag et grensesnitt kalt `Ticket`, med følgende metoder:
|
||||
|
||||
- `boolean scan()` - Denne metoden kalles hver gang billetten scannes. Dersom billetten er gyldig, skal metoden returnere `true`, ellers `false`. Legg merke til at du **ikke** skal implementere metoden her, du skal bare definere grensesnittet.
|
||||
|
||||
Tanken her er at vi kan senere lage en kontrollørklasse som kan bruke `scan()`-metoden for å sjekke om en billett er gyldig.
|
||||
|
||||
## Del 2 - SingleTicket-klasse
|
||||
|
||||
Lag en klasse kalt `SingleTicket` som implementerer `Ticket`-grensesnittet. `SingleTicket` skal implementere `scan()`-metoden slik at den kun returnerer `true` den første gangen metoden blir kalt.
|
||||
|
||||
**Hint:** Du kan bruke en `boolean`-variabel for å holde styr på om billetten er gyldig eller ikke.
|
||||
|
||||
Testkode for oppgaven finner du her: [oving5/ticket/SingleTicketTest.java](../../src/test/java/oving5/ticket/SingleTicketTest.java).
|
||||
|
||||
## Del 3 - PeriodTicket-klasse
|
||||
|
||||
Lag en klasse kalt `PeriodTicket` som implementerer `Ticket`-grensesnittet. `PeriodTicket` skal implementere `scan()`-metoden slik at den returnerer `true` dersom det nåværende tidspunktet er mellom to gitte tidspunkter. `PeriodTicket` skal ha en konstruktør som tar inn to `LocalDateTime`-objekter som representerer start- og sluttidspunktet for gyldigheten til billetten. Legg til validering der det gir mening.
|
||||
|
||||
Testkode for oppgaven finner du her: [oving5/ticket/PeriodTicketTest.java](../../src/test/java/oving5/ticket/PeriodTicketTest.java).
|
||||
55
oppgavetekster/oving5/Twitter.md
Normal file
55
oppgavetekster/oving5/Twitter.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Interface - Sortering av TwitterAccount-objekter ved bruk av Comparator
|
||||
|
||||
Denne oppgaven handler om sortering av `TwitterAccount`-objekter, ved bruk av grensesnittet `Comparator`. Oppgaven illustrerer hvordan man kan sortere objekter av samme klasse på ulike måter, ved hjelp av ulike implementasjoner av `Comparator`.
|
||||
|
||||
Vi tar i denne oppgaven utgangspunkt i `TwitterAccount`- og `Tweet`-klassen fra [Øving 4 - Twitter-oppgave](../oving4/Twitter.md). Et `TwitterAccount`-objekt har et brukernavn, en liste over andre brukere som følges, en liste over brukere som følger denne brukeren (dette `TwitterAccount`-objektet), og en liste med tweets. Vi ønsker å kunne sortere `TwitterAccount`-objekter på tre ulike parametre:
|
||||
|
||||
1. Brukernavn
|
||||
2. Antall følgere
|
||||
3. Antall tweet
|
||||
|
||||
Dersom du ikke har gjort `Twitter`-oppgaven allerede, bør du gjøre denne først. Løsningsforslaget kommer til å være tilgjengelig [her](https://git.ntnu.no/tdt4100/tdt4100-lf-25/blob/main/src/main/java/oving4/twitter) etter siste demonstrasjonsfrist for øving 4.
|
||||
|
||||
Filene i denne oppgaven skal ligge i [`oving5/twitter`](../../src/main/java/oving5/twitter).
|
||||
|
||||
## Del 1
|
||||
|
||||
I denne delen av oppgaven skal du lage tre ulike implementasjoner av `Comparator`-grensesnittet. `Comparator`-grensesnittet inneholder én metode: `int compare(Object o1, Object o2)`. Implementasjonen av denne metoden skal returnere:
|
||||
|
||||
- Et negativt tall dersom objektet o1 skal komme før objektet o2 i en sortert rekkefølge.
|
||||
- Et positivt tall dersom objektet o1 skal komme etter objektet o2 i en sortert rekkefølge.
|
||||
- $0$ om det er likegyldig hvilken rekkefølge objektene har (dvs. de er like hverandre for den parameteren/de paremetrene de sorteres på).
|
||||
|
||||
De tre klassene du skal lage er som følger:
|
||||
|
||||
- `UserNameComparator`: Sammenligner `TwitterAccount`-objektene på brukernavn, slik at brukeren “Apekatten” vil komme før “Bjørnen” som igjen vil komme før “Cameleonen” (dvs. leksikalsk rekkefølge - tenk rekkefølgene brukernavnene ville stått i et leksikon eller en ordbok).
|
||||
- `FollowersCountComparator`: Sammenligner `TwitterAccount`-objektene på antall følgere, slik at brukeren med flest følgere havner først.
|
||||
- `TweetsCountComparator`: Sammenligner `TwitterAccount`-objektene på antall tweets, slik at brukeren med flest tweets havner først.
|
||||
|
||||
Alle klassene skal implementere `Comparator<TwitterAccount>`.
|
||||
|
||||
[Hint om sammenligning av strenger](<https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html#compareTo(java.lang.String)>).
|
||||
|
||||
[Hint om sammenligning av tall](<https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Integer.html#compareTo(java.lang.Integer)>).
|
||||
|
||||
## Del 2
|
||||
|
||||
I denne delen av oppgaven skal du legge til en funksjon i `TwitterAccount`-klassen som lar deg hente ut en sortert versjon av følgerene til dette (`this`) `TwitterAccount`-objektet. Funksjonen du skal implementere er som følger:
|
||||
|
||||
- `List<TwitterAccount> getFollowers(Comparator<TwitterAccount>)` - skal returnere en sortert kopi av følgere-listen til dette `TwitterAccount`-objektet. Objektene skal sorteres ved å bruke det `Comparator`-objektet som tas inn som parameter. Dersom parameteren er `null` skal du returnere den orginale (usorterte) versjonen av følgere-listen. Du skal ikke skrive din egen sorteringsalgoritme, men bruke `Collections.sort`-funksjonen fra `java.utils`-biblioteket. Merk at den opprinnelige følgere-listen skal være uforandret etter at denne funksjonen har blitt kjørt.
|
||||
|
||||
Testkode for oppgaven finner du her:
|
||||
|
||||
- [oving5/twitter/TwitterAccountTest.java](../../src/test/java/oving5/twitter/TwitterAccountTest.java)
|
||||
- [oving5/twitter/FollowersCountComparatorTest.java](../../src/test/java/oving5/twitter/FollowersCountComparatorTest.java)
|
||||
- [oving5/twitter/TweetsCountComparatorTest.java](../../src/test/java/oving5/twitter/TweetsCountComparatorTest.java)
|
||||
- [oving5/twitter/UserNameComparatorTest.java](../../src/test/java/oving5/twitter/UserNameComparatorTest.java)
|
||||
|
||||
## Valgfri Ekstraoppgave
|
||||
|
||||
Lag en klasse `TwitterAccountComparator` som implementerer `Comparator<TwitterAccount>` og sammenligner `TwitterAccount`-objekter på
|
||||
følgende måte:
|
||||
|
||||
- `TwitterAccount`-objektet med flest følgere skal komme først.
|
||||
- Dersom to `TwitterAccount`-objekter har like mange følgere skal det `TwitterAccount`-objektet med flest tweets komme først.
|
||||
- Dersom to `TwitterAccount`-objekter har like mange følgere og tweets skal `TwitterAccount`-objektene sammenlignes på brukernavn.
|
||||
0
src/main/java/oving5/card/.gitkeep
Normal file
0
src/main/java/oving5/card/.gitkeep
Normal file
0
src/main/java/oving5/named/.gitkeep
Normal file
0
src/main/java/oving5/named/.gitkeep
Normal file
0
src/main/java/oving5/stringgrid/.gitkeep
Normal file
0
src/main/java/oving5/stringgrid/.gitkeep
Normal file
0
src/main/java/oving5/ticket/.gitkeep
Normal file
0
src/main/java/oving5/ticket/.gitkeep
Normal file
0
src/main/java/oving5/twitter/.gitkeep
Normal file
0
src/main/java/oving5/twitter/.gitkeep
Normal file
100
src/test/java/oving5/BinaryComputingIteratorTest.java
Normal file
100
src/test/java/oving5/BinaryComputingIteratorTest.java
Normal file
@@ -0,0 +1,100 @@
|
||||
package oving5;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class BinaryComputingIteratorTest {
|
||||
|
||||
private Iterator<Double> iterator1;
|
||||
private Iterator<Double> iterator2;
|
||||
private Iterator<Double> iteratorShort;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
iterator1 = List.of(0.5, -2.0).iterator();
|
||||
iterator2 = List.of(5.0, 3.0).iterator();
|
||||
iteratorShort = List.of(5.0).iterator();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that the constructor sets up the iterator correctly")
|
||||
public void testConstructor() {
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new BinaryComputingIterator(null, iterator2, (a, b) -> a * b);
|
||||
}, "Iterator1 cannot be null");
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new BinaryComputingIterator(iterator1, null, (a, b) -> a * b);
|
||||
}, "Iterator2 cannot be null");
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new BinaryComputingIterator(iterator1, iterator2, null);
|
||||
}, "Operator cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check BinaryComputingIterator with multiplication")
|
||||
public void testMultiplication() {
|
||||
BinaryComputingIterator binaryIt =
|
||||
new BinaryComputingIterator(iterator1, iterator2, (a, b) -> a * b);
|
||||
assertEquals(2.5, binaryIt.next(), "The first number was incorrect");
|
||||
assertTrue(binaryIt.hasNext());
|
||||
assertEquals(-6.0, binaryIt.next(), "The second number was incorrect");
|
||||
assertFalse(binaryIt.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check BinaryComputingIterator with addition")
|
||||
public void testAddition() {
|
||||
BinaryComputingIterator binaryIt =
|
||||
new BinaryComputingIterator(iterator1, iterator2, (a, b) -> a + b);
|
||||
assertEquals(5.5, binaryIt.next(), "The first number was incorrect");
|
||||
assertTrue(binaryIt.hasNext());
|
||||
assertEquals(1.0, binaryIt.next(), "The second number was incorrect");
|
||||
assertFalse(binaryIt.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Test multiplication with only one number")
|
||||
public void testShortIterator() {
|
||||
BinaryComputingIterator binaryIt =
|
||||
new BinaryComputingIterator(iterator1, iteratorShort, (a, b) -> a * b);
|
||||
assertEquals(2.5, binaryIt.next(), "The first number was incorrect");
|
||||
assertFalse(binaryIt.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Test with default value, both a number and null")
|
||||
public void testShortIteratorAndDefault() {
|
||||
BinaryComputingIterator binaryIt =
|
||||
new BinaryComputingIterator(iterator1, iteratorShort, null, 2.0, (a, b) -> a * b);
|
||||
assertEquals(2.5, binaryIt.next(), "The first number was incorrect");
|
||||
assertTrue(binaryIt.hasNext());
|
||||
assertEquals(-4.0, binaryIt.next(), "The second number was incorrect");
|
||||
assertFalse(binaryIt.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Test with an empty iterator")
|
||||
public void testEmptyIterator() {
|
||||
BinaryComputingIterator binaryIt = new BinaryComputingIterator(Collections.emptyIterator(),
|
||||
Collections.emptyIterator(), (a, b) -> a * b);
|
||||
assertFalse(binaryIt.hasNext(), "An empty iterator should not have next");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Test an empty iterator with default value")
|
||||
public void testEmptyIteratorAndDefault() {
|
||||
BinaryComputingIterator binaryIt = new BinaryComputingIterator(Collections.emptyIterator(),
|
||||
Collections.emptyIterator(), 1.0, 2.0, (a, b) -> a * b);
|
||||
assertFalse(binaryIt.hasNext(), "An empty iterator should not have next");
|
||||
}
|
||||
}
|
||||
71
src/test/java/oving5/RPNCalcTest.java
Normal file
71
src/test/java/oving5/RPNCalcTest.java
Normal file
@@ -0,0 +1,71 @@
|
||||
package oving5;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import java.util.function.BinaryOperator;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class RPNCalcTest {
|
||||
|
||||
private RPNCalc calc;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
calc = new RPNCalc();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Test operation without operands")
|
||||
public void testPerformOperationWithoutOperation() {
|
||||
assertThrows(UnsupportedOperationException.class, () -> {
|
||||
calc.performOperation('+');
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Test execution of a simple operation")
|
||||
public void testPerformOperation() {
|
||||
calc.addOperator('+', (a, b) -> a * b); // Use "incorrect" definition to filter out cheating
|
||||
calc.addOperator('l', (a, b) -> a * (a + b));
|
||||
|
||||
calc.push(4);
|
||||
calc.push(3);
|
||||
calc.performOperation('+');
|
||||
assertEquals(12.0, calc.pop(), "The result of the calculation was incorrect");
|
||||
assertEquals(Double.NaN, calc.pop());
|
||||
|
||||
calc.push(4);
|
||||
calc.push(3);
|
||||
calc.performOperation('l');
|
||||
assertEquals(28.0, calc.pop(), "The result of the calculation was incorrect");
|
||||
assertEquals(Double.NaN, calc.pop());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Test adding operators")
|
||||
public void testAddOperator() {
|
||||
assertTrue(calc.addOperator('+', (a, b) -> a + b), "You should be able to add operators");
|
||||
assertTrue(calc.addOperator('-', (a, b) -> a - b), "You should be able to add operators");
|
||||
assertFalse(calc.addOperator('+', (a, b) -> a + b),
|
||||
"You should not be able to add the same operator twice");
|
||||
assertFalse(calc.addOperator('-', (a, b) -> a * b),
|
||||
"You should not be able to add the same operator twice");
|
||||
assertFalse(calc.addOperator('.', (BinaryOperator<Double>) null),
|
||||
"You should not be able to add a null operator");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that you can remove operators")
|
||||
public void testRemoveOperator() {
|
||||
calc.addOperator('+', (a, b) -> a + b);
|
||||
calc.removeOperator('+');
|
||||
|
||||
assertThrows(UnsupportedOperationException.class, () -> {
|
||||
calc.performOperation('+');
|
||||
}, "The operator should have been removed");
|
||||
}
|
||||
}
|
||||
78
src/test/java/oving5/card/CardComparatorTest.java
Normal file
78
src/test/java/oving5/card/CardComparatorTest.java
Normal file
@@ -0,0 +1,78 @@
|
||||
package oving5.card;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class CardComparatorTest {
|
||||
|
||||
private Card s1;
|
||||
private Card h1;
|
||||
private Card d1;
|
||||
private Card c1;
|
||||
private Card s13;
|
||||
private Card h13;
|
||||
private Card d13;
|
||||
private Card c13;
|
||||
private Collection<Card> expected;
|
||||
private List<Card> cards;
|
||||
|
||||
private static void testCards(Collection<Card> actualCards, Collection<Card> expectedCards) {
|
||||
Iterator<Card> actual = actualCards.iterator();
|
||||
Iterator<Card> expected = expectedCards.iterator();
|
||||
|
||||
while (expected.hasNext()) {
|
||||
assertTrue(actual.hasNext());
|
||||
|
||||
Card actualCard = actual.next();
|
||||
Card expectedCard = expected.next();
|
||||
assertEquals(expectedCard.getSuit(), actualCard.getSuit(), String.format(
|
||||
"The card deck should have been %s, but was %s", expectedCards, actualCards));
|
||||
assertEquals(expectedCard.getFace(), actualCard.getFace(), String.format(
|
||||
"The card deck should have been %s, but was %s", expectedCards, actualCards));
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
s1 = new Card('S', 1);
|
||||
h1 = new Card('H', 1);
|
||||
d1 = new Card('D', 1);
|
||||
c1 = new Card('C', 1);
|
||||
s13 = new Card('S', 13);
|
||||
h13 = new Card('H', 13);
|
||||
d13 = new Card('D', 13);
|
||||
c13 = new Card('C', 13);
|
||||
cards = new ArrayList<>(List.of(s1, s13, h1, h13, d1, d13, c1, c13));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that the deck is sorted with aces as the lowest")
|
||||
public void testNormal() {
|
||||
expected = List.of(c1, c13, d1, d13, h1, h13, s1, s13);
|
||||
cards.sort(new CardComparator(false, ' '));
|
||||
CardComparatorTest.testCards(cards, expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that the deck is sorted with aces as the highest")
|
||||
public void testAceIsHighest() {
|
||||
expected = List.of(c13, c1, d13, d1, h13, h1, s13, s1);
|
||||
cards.sort(new CardComparator(true, ' '));
|
||||
CardComparatorTest.testCards(cards, expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that the deck is sorted correctly with diamonds as trump")
|
||||
public void testDiamondIsTrump() {
|
||||
expected = List.of(c1, c13, h1, h13, s1, s13, d1, d13);
|
||||
cards.sort(new CardComparator(false, 'D'));
|
||||
CardComparatorTest.testCards(cards, expected);
|
||||
}
|
||||
}
|
||||
69
src/test/java/oving5/card/CardContainerIteratorTest.java
Normal file
69
src/test/java/oving5/card/CardContainerIteratorTest.java
Normal file
@@ -0,0 +1,69 @@
|
||||
package oving5.card;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class CardContainerIteratorTest {
|
||||
|
||||
private Card c1;
|
||||
private Card c2;
|
||||
private Card d1;
|
||||
private Card d2;
|
||||
private Card h1;
|
||||
private Card h2;
|
||||
private Card s1;
|
||||
private Card s2;
|
||||
private CardContainerIterator iterator;
|
||||
|
||||
private static void testCards(Iterator<Card> actual, Iterator<Card> expected) {
|
||||
while (expected.hasNext()) {
|
||||
assertTrue(actual.hasNext());
|
||||
|
||||
Card actualCard = actual.next();
|
||||
Card expectedCard = expected.next();
|
||||
assertEquals(expectedCard.getSuit(), actualCard.getSuit(), String
|
||||
.format("The card should have been %s, but was %s", expectedCard, actualCard));
|
||||
assertEquals(expectedCard.getFace(), actualCard.getFace(), String
|
||||
.format("The card should have been %s, but was %s", expectedCard, actualCard));
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
iterator = new CardContainerIterator(new CardDeck(2));
|
||||
s1 = new Card('S', 1);
|
||||
s2 = new Card('S', 2);
|
||||
h1 = new Card('H', 1);
|
||||
h2 = new Card('H', 2);
|
||||
d1 = new Card('D', 1);
|
||||
d2 = new Card('D', 2);
|
||||
c1 = new Card('C', 1);
|
||||
c2 = new Card('C', 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that the iterator for a new deck of cards outputs [S1, S2, H1, H2, D1, D2, C1, C2]")
|
||||
public void testConstructor() {
|
||||
CardContainerIteratorTest.testCards(iterator,
|
||||
List.of(s1, s2, h1, h2, d1, d2, c1, c2).iterator());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that the first card in the iterator is correct")
|
||||
public void testNext() {
|
||||
Card nextCard = iterator.next();
|
||||
assertEquals(s1.toString(), nextCard.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that the deck contains at least one card")
|
||||
public void testHasNext() {
|
||||
boolean hasNext = iterator.hasNext();
|
||||
assertTrue(hasNext);
|
||||
}
|
||||
}
|
||||
86
src/test/java/oving5/card/CardDeckTest.java
Normal file
86
src/test/java/oving5/card/CardDeckTest.java
Normal file
@@ -0,0 +1,86 @@
|
||||
package oving5.card;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class CardDeckTest {
|
||||
|
||||
private Card s1;
|
||||
private Card h1;
|
||||
private Card d1;
|
||||
private Card c1;
|
||||
private Card s2;
|
||||
private Card h2;
|
||||
private Card d2;
|
||||
private Card c2;
|
||||
private CardDeck deck;
|
||||
private Collection<Card> expected;
|
||||
|
||||
private static void testCards(Iterable<Card> actual, Iterator<Card> expected) {
|
||||
Iterator<Card> actualIt = actual.iterator();
|
||||
|
||||
while (expected.hasNext()) {
|
||||
assertTrue(actualIt.hasNext());
|
||||
|
||||
Card expectedCard = expected.next();
|
||||
Card actualCard = actualIt.next();
|
||||
assertEquals(expectedCard.getSuit(), actualCard.getSuit(), String
|
||||
.format("The card should have been %s, but was %s", expectedCard, actualCard));
|
||||
assertEquals(expectedCard.getFace(), actualCard.getFace(), String
|
||||
.format("The card should have been %s, but was %s", expectedCard, actualCard));
|
||||
}
|
||||
}
|
||||
|
||||
private static void testCards(CardContainer it, Collection<Card> expected) {
|
||||
assertEquals(expected.size(), it.getCardCount());
|
||||
|
||||
Iterator<Card> expectedIt = expected.iterator();
|
||||
int i = 0;
|
||||
|
||||
while (expectedIt.hasNext()) {
|
||||
Card expectedCard = expectedIt.next();
|
||||
Card actualCard = it.getCard(i);
|
||||
assertEquals(expectedCard.getSuit(), actualCard.getSuit(),
|
||||
String.format("Card number %d should have been %s, but was %s", i + 1,
|
||||
expectedCard, actualCard));
|
||||
assertEquals(expectedCard.getFace(), actualCard.getFace(),
|
||||
String.format("Card number %d should have been %s, but was %s", i + 1,
|
||||
expectedCard, actualCard));
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
deck = new CardDeck(2);
|
||||
s1 = new Card('S', 1);
|
||||
s2 = new Card('S', 2);
|
||||
h1 = new Card('H', 1);
|
||||
h2 = new Card('H', 2);
|
||||
d1 = new Card('D', 1);
|
||||
d2 = new Card('D', 2);
|
||||
c1 = new Card('C', 1);
|
||||
c2 = new Card('C', 2);
|
||||
expected = new ArrayList<>(List.of(s1, s2, h1, h2, d1, d2, c1, c2));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Checks that CardContainer works with CardDeck")
|
||||
public void testCardContainer() {
|
||||
CardDeckTest.testCards(deck, expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Checks that the iterator works with CardDeck")
|
||||
public void testDeckIterator() {
|
||||
CardDeckTest.testCards(deck, expected.iterator());
|
||||
}
|
||||
}
|
||||
78
src/test/java/oving5/card/CardHandTest.java
Normal file
78
src/test/java/oving5/card/CardHandTest.java
Normal file
@@ -0,0 +1,78 @@
|
||||
package oving5.card;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class CardHandTest {
|
||||
|
||||
private Card s1;
|
||||
private Card c2;
|
||||
private CardHand hand;
|
||||
private Collection<Card> expected;
|
||||
|
||||
private static void testCards(CardContainer it, Collection<Card> expected) {
|
||||
assertEquals(expected.size(), it.getCardCount());
|
||||
|
||||
Iterator<Card> expectedIt = expected.iterator();
|
||||
int i = 0;
|
||||
|
||||
while (expectedIt.hasNext()) {
|
||||
Card expectedCard = expectedIt.next();
|
||||
Card actualCard = it.getCard(i);
|
||||
assertEquals(expectedCard.getSuit(), actualCard.getSuit(),
|
||||
String.format("Card number %d should have been %s, but was %s", i + 1,
|
||||
expectedCard, actualCard));
|
||||
assertEquals(expectedCard.getFace(), actualCard.getFace(),
|
||||
String.format("Card number %d should have been %s, but was %s", i + 1,
|
||||
expectedCard, actualCard));
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private static void testCards(Iterable<Card> actual, Iterator<Card> expected) {
|
||||
Iterator<Card> actualIt = actual.iterator();
|
||||
|
||||
while (expected.hasNext()) {
|
||||
assertTrue(actualIt.hasNext());
|
||||
|
||||
Card expectedCard = expected.next();
|
||||
Card actualCard = actualIt.next();
|
||||
assertEquals(expectedCard.getSuit(), actualCard.getSuit(), String
|
||||
.format("The card should have been %s, but was %s", expectedCard, actualCard));
|
||||
assertEquals(expectedCard.getFace(), actualCard.getFace(), String
|
||||
.format("The card should have been %s, but was %s", expectedCard, actualCard));
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
s1 = new Card('S', 1);
|
||||
c2 = new Card('C', 2);
|
||||
hand = new CardHand();
|
||||
expected = new ArrayList<>(List.of(s1, c2));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Checks that CardContainer works with CardHand")
|
||||
public void testCardContainer() {
|
||||
hand.addCard(s1);
|
||||
hand.addCard(c2);
|
||||
CardHandTest.testCards(hand, expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Checks that the iterator works with CardHand")
|
||||
public void testDeckIterator() {
|
||||
hand.addCard(s1);
|
||||
hand.addCard(c2);
|
||||
CardHandTest.testCards(hand, expected.iterator());
|
||||
}
|
||||
}
|
||||
63
src/test/java/oving5/card/CardPredicateTest.java
Normal file
63
src/test/java/oving5/card/CardPredicateTest.java
Normal file
@@ -0,0 +1,63 @@
|
||||
package oving5.card;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class CardPredicateTest {
|
||||
|
||||
private CardDeck deck;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
deck = new CardDeck(10);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that hasCard() works as expected")
|
||||
public void testHasCard() {
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
deck.hasCard(null);
|
||||
}, "Predicate cannot be null");
|
||||
|
||||
assertTrue(deck.hasCard(c -> c.getSuit() == 'S'));
|
||||
assertFalse(deck.hasCard(c -> c.getFace() == 13));
|
||||
assertTrue(deck.hasCard(c -> c.getSuit() == 'S' && c.getFace() == 8));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that getCardCount() works as expected")
|
||||
public void testGetCardCount() {
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
deck.getCardCount(null);
|
||||
}, "Predicate cannot be null");
|
||||
|
||||
assertEquals(10, deck.getCardCount(c -> c.getSuit() == 'S'));
|
||||
assertEquals(4, deck.getCardCount(c -> c.getFace() == 4));
|
||||
assertEquals(1, deck.getCardCount(c -> c.getFace() == 4 && c.getSuit() == 'H'));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that getCards() works as expected")
|
||||
public void testGetCards() {
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
deck.getCards(null);
|
||||
}, "Predicate cannot be null");
|
||||
|
||||
Card card = new Card('S', 4);
|
||||
Card card2 = new Card('S', 5);
|
||||
List<Card> matching = List.of(card, card2);
|
||||
assertEquals(matching.size(),
|
||||
deck.getCards(c -> (c.getFace() == 4 || c.getFace() == 5) && c.getSuit() == 'S')
|
||||
.size(),
|
||||
"getCards should have returned two cards that were spades and had the numbers 4 "
|
||||
+ "or 5");
|
||||
assertEquals(10, deck.getCards(c -> c.getSuit() == 'S').size(),
|
||||
"getCards should have returned 10 cards of the spades suit");
|
||||
}
|
||||
}
|
||||
50
src/test/java/oving5/named/NamedComparatorTest.java
Normal file
50
src/test/java/oving5/named/NamedComparatorTest.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package oving5.named;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class NamedComparatorTest {
|
||||
|
||||
private NamedComparator comparator;
|
||||
private Person1 p1;
|
||||
private Person2 p2;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
comparator = new NamedComparator();
|
||||
p1 = new Person1("Aleksander", "Vestlund");
|
||||
p2 = new Person2("Dan Vestlund");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that people with the same name are equivalent")
|
||||
public void testSameFullName() {
|
||||
assertEquals(0, comparator.compare(p1, p1));
|
||||
assertEquals(0, comparator.compare(p2, p2));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that given names are compared when the family names are the same")
|
||||
public void testSameFamilyName() {
|
||||
// Return negative since first givenName is before second
|
||||
assertTrue(comparator.compare(p1, p2) < 0, "Aleksander should come before Dan");
|
||||
|
||||
// Return positive since first givenName is after second
|
||||
assertTrue(comparator.compare(p2, p1) > 0, "Dan should come after Aleksander");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that family names are compared correctly")
|
||||
public void testDifferentFamilyName() {
|
||||
p2.setFamilyName("Bertelsen");
|
||||
|
||||
// Return negative since first familyName is before second
|
||||
assertTrue(comparator.compare(p2, p1) < 0, "Bertelsen should come before Vestlund");
|
||||
|
||||
// Return positive since first familyName is after second
|
||||
assertTrue(comparator.compare(p1, p2) > 0, "Vestlund should come after Bertelsen");
|
||||
}
|
||||
}
|
||||
58
src/test/java/oving5/named/Person1Test.java
Normal file
58
src/test/java/oving5/named/Person1Test.java
Normal file
@@ -0,0 +1,58 @@
|
||||
package oving5.named;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class Person1Test {
|
||||
|
||||
private Person1 person;
|
||||
private String given;
|
||||
private String family;
|
||||
|
||||
private static void testName(Person1 person, String givenName, String familyName) {
|
||||
assertEquals(givenName, person.getGivenName());
|
||||
assertEquals(familyName, person.getFamilyName());
|
||||
assertEquals(String.format("%s %s", givenName, familyName), person.getFullName());
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
given = "Hallvard";
|
||||
family = "Trætteberg";
|
||||
person = new Person1(given, family);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that the constructor assigns the correct name to the person")
|
||||
public void testConstructor() {
|
||||
Person1Test.testName(person, given, family);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that setGivenName() assigns the correct name")
|
||||
public void testSetGivenName() {
|
||||
String newGiven = "Jens";
|
||||
person.setGivenName(newGiven);
|
||||
Person1Test.testName(person, newGiven, family);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that setFamilyName() assigns the correct name")
|
||||
public void testSetFamilyName() {
|
||||
String newFamily = "Olsen";
|
||||
person.setFamilyName(newFamily);
|
||||
Person1Test.testName(person, given, newFamily);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that setFullName() assigns the correct name")
|
||||
public void testSetFullName() {
|
||||
String newGiven = "Lisa";
|
||||
String newFamily = "Eriksen";
|
||||
String newFull = String.format("%s %s", newGiven, newFamily);
|
||||
person.setFullName(newFull);
|
||||
Person1Test.testName(person, newGiven, newFamily);
|
||||
}
|
||||
}
|
||||
58
src/test/java/oving5/named/Person2Test.java
Normal file
58
src/test/java/oving5/named/Person2Test.java
Normal file
@@ -0,0 +1,58 @@
|
||||
package oving5.named;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class Person2Test {
|
||||
|
||||
private Person2 person;
|
||||
private String given;
|
||||
private String family;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
given = "Hallvard";
|
||||
family = "Trætteberg";
|
||||
person = new Person2(String.format("%s %s", given, family));
|
||||
}
|
||||
|
||||
private static void testName(Person2 person, String givenName, String familyName) {
|
||||
assertEquals(givenName, person.getGivenName());
|
||||
assertEquals(familyName, person.getFamilyName());
|
||||
assertEquals(String.format("%s %s", givenName, familyName), person.getFullName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that the constructor assigns the correct name to the person")
|
||||
public void testConstructor() {
|
||||
Person2Test.testName(person, given, family);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that setGivenName() assigns the correct name")
|
||||
public void testSetGivenName() {
|
||||
String newGiven = "Jens";
|
||||
person.setGivenName(newGiven);
|
||||
Person2Test.testName(person, newGiven, family);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that setFamilyName() assigns the correct name")
|
||||
public void testSetFamilyName() {
|
||||
String newFamily = "Olsen";
|
||||
person.setFamilyName(newFamily);
|
||||
Person2Test.testName(person, given, newFamily);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that setFullName() assigns the correct name")
|
||||
public void testSetFullName() {
|
||||
String newGiven = "Lisa";
|
||||
String newFamily = "Eriksen";
|
||||
String newFull = String.format("%s %s", newGiven, newFamily);
|
||||
person.setFullName(newFull);
|
||||
Person2Test.testName(person, newGiven, newFamily);
|
||||
}
|
||||
}
|
||||
111
src/test/java/oving5/stringgrid/StringGridTest.java
Normal file
111
src/test/java/oving5/stringgrid/StringGridTest.java
Normal file
@@ -0,0 +1,111 @@
|
||||
package oving5.stringgrid;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class StringGridTest {
|
||||
|
||||
private StringGrid grid;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
grid = new StringGridImpl(2, 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Test the size of the grid")
|
||||
public void testSize() {
|
||||
assertEquals(2, grid.getRowCount(), "The number of rows was incorrect");
|
||||
assertEquals(3, grid.getColumnCount(), "The number of columns was incorrect");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Test that setElement sets the correct grid element")
|
||||
public void testGrid() {
|
||||
grid.setElement(0, 0, "0, 0");
|
||||
grid.setElement(0, 1, "0, 1");
|
||||
grid.setElement(0, 2, "0, 2");
|
||||
grid.setElement(1, 0, "1, 0");
|
||||
grid.setElement(1, 1, "1, 1");
|
||||
grid.setElement(1, 2, "1, 2");
|
||||
|
||||
assertEquals("0, 0", grid.getElement(0, 0));
|
||||
assertEquals("0, 1", grid.getElement(0, 1));
|
||||
assertEquals("0, 2", grid.getElement(0, 2));
|
||||
assertEquals("1, 0", grid.getElement(1, 0));
|
||||
assertEquals("1, 1", grid.getElement(1, 1));
|
||||
assertEquals("1, 2", grid.getElement(1, 2));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check the elements in the grid with row-first order")
|
||||
public void testGridIteratorRowMajor() {
|
||||
StringGridIterator iterator = new StringGridIterator(grid, true);
|
||||
|
||||
grid.setElement(0, 0, "0, 0");
|
||||
grid.setElement(0, 1, "0, 1");
|
||||
grid.setElement(0, 2, "0, 2");
|
||||
grid.setElement(1, 0, "1, 0");
|
||||
grid.setElement(1, 1, "1, 1");
|
||||
grid.setElement(1, 2, "1, 2");
|
||||
|
||||
assertTrue(iterator.hasNext());
|
||||
|
||||
assertEquals("0, 0", iterator.next());
|
||||
assertTrue(iterator.hasNext());
|
||||
|
||||
assertEquals("0, 1", iterator.next());
|
||||
assertTrue(iterator.hasNext());
|
||||
|
||||
assertEquals("0, 2", iterator.next());
|
||||
assertTrue(iterator.hasNext());
|
||||
|
||||
assertEquals("1, 0", iterator.next());
|
||||
assertTrue(iterator.hasNext());
|
||||
|
||||
assertEquals("1, 1", iterator.next());
|
||||
assertTrue(iterator.hasNext());
|
||||
|
||||
// False after going through the last one
|
||||
assertEquals("1, 2", iterator.next());
|
||||
assertFalse(iterator.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check the elements in the grid with column-first order")
|
||||
public void testGridIteratorColumnMajor() {
|
||||
StringGridIterator iterator = new StringGridIterator(grid, false);
|
||||
|
||||
grid.setElement(0, 0, "0, 0");
|
||||
grid.setElement(0, 1, "0, 1");
|
||||
grid.setElement(0, 2, "0, 2");
|
||||
grid.setElement(1, 0, "1, 0");
|
||||
grid.setElement(1, 1, "1, 1");
|
||||
grid.setElement(1, 2, "1, 2");
|
||||
|
||||
assertTrue(iterator.hasNext());
|
||||
|
||||
assertEquals("0, 0", iterator.next(), "A cell was incorrect");
|
||||
assertTrue(iterator.hasNext(), "Incorrect number of cells in the grid");
|
||||
|
||||
assertEquals("1, 0", iterator.next(), "A cell was incorrect");
|
||||
assertTrue(iterator.hasNext(), "Incorrect number of cells in the grid");
|
||||
|
||||
assertEquals("0, 1", iterator.next(), "A cell was incorrect");
|
||||
assertTrue(iterator.hasNext(), "Incorrect number of cells in the grid");
|
||||
|
||||
assertEquals("1, 1", iterator.next(), "A cell was incorrect");
|
||||
assertTrue(iterator.hasNext(), "Incorrect number of cells in the grid");
|
||||
|
||||
assertEquals("0, 2", iterator.next(), "A cell was incorrect");
|
||||
assertTrue(iterator.hasNext(), "Incorrect number of cells in the grid");
|
||||
|
||||
// False after going through the last one
|
||||
assertEquals("1, 2", iterator.next());
|
||||
assertFalse(iterator.hasNext(), "Incorrect number of cells in the grid");
|
||||
}
|
||||
}
|
||||
51
src/test/java/oving5/ticket/PeriodTicketTest.java
Normal file
51
src/test/java/oving5/ticket/PeriodTicketTest.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package oving5.ticket;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import java.time.LocalDateTime;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class PeriodTicketTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that the ticket is valid within the period")
|
||||
public void testIsValidWhenWithinPeriod() {
|
||||
LocalDateTime start = LocalDateTime.now().minusDays(1);
|
||||
LocalDateTime end = LocalDateTime.now().plusDays(1);
|
||||
PeriodTicket ticket = new PeriodTicket(start, end);
|
||||
assertTrue(ticket.scan(), "The ticket should be valid within the period");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that the ticket is not valid before the period")
|
||||
public void testIsNotValidWhenBeforePeriod() {
|
||||
LocalDateTime start = LocalDateTime.now().plusDays(1);
|
||||
LocalDateTime end = LocalDateTime.now().plusDays(2);
|
||||
PeriodTicket ticket = new PeriodTicket(start, end);
|
||||
assertFalse(ticket.scan(), "The ticket should not be valid before the period");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that the ticket is not valid after the period")
|
||||
public void testIsNotValidWhenAfterPeriod() {
|
||||
LocalDateTime start = LocalDateTime.now().minusDays(2);
|
||||
LocalDateTime end = LocalDateTime.now().minusDays(1);
|
||||
PeriodTicket ticket = new PeriodTicket(start, end);
|
||||
assertFalse(ticket.scan(), "The ticket should not be valid after the period");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that the ticket throws IllegalArgumentException when the start date is "
|
||||
+ "after the end date")
|
||||
public void testThrowsExceptionWhenStartIsAfterEnd() {
|
||||
LocalDateTime start = LocalDateTime.now().plusDays(1);
|
||||
LocalDateTime end = LocalDateTime.now().minusDays(1);
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new PeriodTicket(start, end);
|
||||
}, "The ticket should throw IllegalArgumentException when the start date is after the "
|
||||
+ "end date");
|
||||
}
|
||||
}
|
||||
41
src/test/java/oving5/ticket/SingleTicketTest.java
Normal file
41
src/test/java/oving5/ticket/SingleTicketTest.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package oving5.ticket;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class SingleTicketTest {
|
||||
|
||||
private Ticket ticket;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
ticket = new SingleTicket();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that the ticket returns true when scanned for the first time")
|
||||
public void testReturnsTrueWhenScanned() {
|
||||
assertTrue(this.ticket.scan(),
|
||||
"The ticket should return true when scanned for the first time");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that the ticket returns false when scanned for the second time")
|
||||
public void testReturnsFalseWhenScannedTwice() {
|
||||
ticket.scan();
|
||||
assertFalse(ticket.scan(),
|
||||
"The ticket should return false when scanned for the second time");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that the ticket returns true when scanned for the first time after reset")
|
||||
public void testReturnsFalseWhenScannedTwiceAfterReset() {
|
||||
ticket.scan();
|
||||
ticket = new SingleTicket();
|
||||
assertTrue(ticket.scan(),
|
||||
"The ticket should return true when scanned for the first time after reset");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package oving5.twitter;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class FollowersCountComparatorTest {
|
||||
|
||||
private TwitterAccount aaron;
|
||||
private TwitterAccount ben;
|
||||
private TwitterAccount charlie;
|
||||
private FollowersCountComparator comparator;
|
||||
|
||||
@BeforeEach
|
||||
public void SetUp() {
|
||||
aaron = new TwitterAccount("Aaron");
|
||||
ben = new TwitterAccount("Ben");
|
||||
charlie = new TwitterAccount("Charlie");
|
||||
comparator = new FollowersCountComparator();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that the comparison is based on followers")
|
||||
public void testCompare() {
|
||||
aaron.follow(ben);
|
||||
ben.follow(aaron);
|
||||
assertEquals(0, comparator.compare(aaron, ben), "Aaron and Ben should be equal");
|
||||
|
||||
charlie.follow(ben);
|
||||
assertTrue(comparator.compare(aaron, ben) > 0, "Aaron should come after Ben");
|
||||
assertTrue(comparator.compare(ben, aaron) < 0, "Ben should come before Aaron");
|
||||
}
|
||||
}
|
||||
38
src/test/java/oving5/twitter/TweetsCountComparatorTest.java
Normal file
38
src/test/java/oving5/twitter/TweetsCountComparatorTest.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package oving5.twitter;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class TweetsCountComparatorTest {
|
||||
|
||||
private TwitterAccount mostTweet;
|
||||
private TwitterAccount lessTweet1;
|
||||
private TwitterAccount lessTweet2;
|
||||
private TweetsCountComparator comparator;
|
||||
|
||||
@BeforeEach
|
||||
public void SetUp() {
|
||||
mostTweet = new TwitterAccount("Aaron");
|
||||
lessTweet1 = new TwitterAccount("Ben");
|
||||
lessTweet2 = new TwitterAccount("Charlie");
|
||||
comparator = new TweetsCountComparator();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check comparison based on tweets")
|
||||
public void testCompare() {
|
||||
mostTweet.tweet("Tweet");
|
||||
mostTweet.tweet("Tweet");
|
||||
lessTweet1.tweet("Tweet");
|
||||
lessTweet2.tweet("Tweet");
|
||||
assertTrue(comparator.compare(mostTweet, lessTweet1) < 0,
|
||||
"The account with the most tweets should come first");
|
||||
assertTrue(comparator.compare(lessTweet1, mostTweet) > 0,
|
||||
"The account with the fewest tweets should come last");
|
||||
assertEquals(0, comparator.compare(lessTweet1, lessTweet2),
|
||||
"Two accounts with the same number of tweets should be equal");
|
||||
}
|
||||
}
|
||||
146
src/test/java/oving5/twitter/TwitterAccountTest.java
Normal file
146
src/test/java/oving5/twitter/TwitterAccountTest.java
Normal file
@@ -0,0 +1,146 @@
|
||||
package oving5.twitter;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
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.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class TwitterAccountTest {
|
||||
|
||||
private TwitterAccount nils;
|
||||
private TwitterAccount ole;
|
||||
|
||||
private static void checkFollow(TwitterAccount accountA, TwitterAccount accountB,
|
||||
boolean AfollowsB, boolean BfollowsA) {
|
||||
if (AfollowsB) {
|
||||
assertTrue(accountA.isFollowing(accountB), String.format("%s should be following %s",
|
||||
accountA.getUserName(), accountB.getUserName()));
|
||||
assertTrue(accountB.isFollowedBy(accountA), String.format("%s should be followed by %s",
|
||||
accountB.getUserName(), accountA.getUserName()));
|
||||
} else {
|
||||
assertFalse(accountA.isFollowing(accountB),
|
||||
String.format("%s should not be following %s", accountA.getUserName(),
|
||||
accountB.getUserName()));
|
||||
assertFalse(accountB.isFollowedBy(accountA),
|
||||
String.format("%s should not be followed by %s", accountB.getUserName(),
|
||||
accountA.getUserName()));
|
||||
}
|
||||
|
||||
if (BfollowsA) {
|
||||
assertTrue(accountB.isFollowing(accountA), String.format("%s should be following %s",
|
||||
accountB.getUserName(), accountA.getUserName()));
|
||||
assertTrue(accountA.isFollowedBy(accountB), String.format("%s should be followed by %s",
|
||||
accountA.getUserName(), accountB.getUserName()));
|
||||
} else {
|
||||
assertFalse(accountB.isFollowing(accountA),
|
||||
String.format("%s should not be following %s", accountB.getUserName(),
|
||||
accountA.getUserName()));
|
||||
assertFalse(accountA.isFollowedBy(accountB),
|
||||
String.format("%s should not be followed by %s", accountA.getUserName(),
|
||||
accountB.getUserName()));
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
nils = new TwitterAccount("Nils");
|
||||
ole = new TwitterAccount("Ole");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that the constructor sets up the account correctly")
|
||||
public void testConstructor() {
|
||||
assertEquals("Nils", nils.getUserName());
|
||||
assertEquals(0, nils.getTweetCount());
|
||||
assertEquals("Ole", ole.getUserName());
|
||||
assertEquals(0, ole.getTweetCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Follow")
|
||||
public void testFollow() {
|
||||
nils.follow(ole);
|
||||
TwitterAccountTest.checkFollow(nils, ole, true, false);
|
||||
|
||||
ole.follow(nils);
|
||||
TwitterAccountTest.checkFollow(nils, ole, true, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Unfollow")
|
||||
public void testUnfollow() {
|
||||
TwitterAccountTest.checkFollow(nils, ole, false, false);
|
||||
|
||||
nils.follow(ole);
|
||||
TwitterAccountTest.checkFollow(nils, ole, true, false);
|
||||
|
||||
nils.unfollow(ole);
|
||||
TwitterAccountTest.checkFollow(nils, ole, false, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Tests that a new tweet is correct")
|
||||
public void testNewTweet() {
|
||||
nils.tweet("Kvitre!");
|
||||
assertEquals(1, nils.getTweetCount(), "Nils' tweet count should be 1");
|
||||
assertEquals("Kvitre!", nils.getTweet(1).getText(), "The text should be 'Tweet'");
|
||||
|
||||
nils.tweet("Kvitre igjen!");
|
||||
assertEquals(2, nils.getTweetCount());
|
||||
assertEquals("Kvitre igjen!", nils.getTweet(1).getText());
|
||||
assertEquals("Kvitre!", nils.getTweet(2).getText());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Tests exceptions for illegal tweets")
|
||||
public void testIllegalTweet() {
|
||||
assertThrows(RuntimeException.class, () -> {
|
||||
nils.getTweet(1);
|
||||
}, "Should not be able to retrieve a tweet that does not exist");
|
||||
|
||||
assertThrows(RuntimeException.class, () -> {
|
||||
nils.getTweet(-1);
|
||||
}, "Should not be able to retrieve a tweet that does not exist");
|
||||
|
||||
nils.tweet("Tweet!");
|
||||
|
||||
assertThrows(RuntimeException.class, () -> {
|
||||
nils.getTweet(2);
|
||||
}, "Should not be able to retrieve a tweet that does not exist");
|
||||
|
||||
assertThrows(RuntimeException.class, () -> {
|
||||
nils.getTweet(-1);
|
||||
}, "Should not be able to retrieve a tweet that does not exist");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check that retweet works, including retweeting a retweet")
|
||||
public void testRetweet() {
|
||||
TwitterAccount kari = new TwitterAccount("Kari");
|
||||
|
||||
nils.tweet("Kvitre!");
|
||||
assertEquals(1, nils.getTweetCount());
|
||||
assertEquals("Kvitre!", nils.getTweet(1).getText());
|
||||
|
||||
ole.retweet(nils.getTweet(1));
|
||||
assertEquals(1, nils.getTweetCount());
|
||||
assertEquals(1, nils.getRetweetCount());
|
||||
assertEquals(1, ole.getTweetCount());
|
||||
assertEquals(0, ole.getRetweetCount());
|
||||
assertEquals("Kvitre!", ole.getTweet(1).getText());
|
||||
assertEquals(nils.getTweet(1), ole.getTweet(1).getOriginalTweet());
|
||||
|
||||
kari.retweet(ole.getTweet(1));
|
||||
assertEquals(1, nils.getTweetCount());
|
||||
assertEquals(2, nils.getRetweetCount());
|
||||
assertEquals(1, ole.getTweetCount());
|
||||
assertEquals(0, ole.getRetweetCount());
|
||||
assertEquals(1, kari.getTweetCount());
|
||||
assertEquals(0, kari.getRetweetCount());
|
||||
assertEquals("Kvitre!", kari.getTweet(1).getText());
|
||||
assertEquals(nils.getTweet(1), kari.getTweet(1).getOriginalTweet());
|
||||
}
|
||||
}
|
||||
32
src/test/java/oving5/twitter/UserNameComparatorTest.java
Normal file
32
src/test/java/oving5/twitter/UserNameComparatorTest.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package oving5.twitter;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class UserNameComparatorTest {
|
||||
|
||||
private TwitterAccount aaron1;
|
||||
private TwitterAccount aaron2;
|
||||
private TwitterAccount ben;
|
||||
private UserNameComparator comparator;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
aaron1 = new TwitterAccount("Aaron");
|
||||
aaron2 = new TwitterAccount("Aaron");
|
||||
ben = new TwitterAccount("Ben");
|
||||
comparator = new UserNameComparator();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Check comparison based on username")
|
||||
public void testCompare() {
|
||||
assertTrue(comparator.compare(aaron1, ben) < 0, "Aaron should be sorted before Ben");
|
||||
assertTrue(comparator.compare(ben, aaron1) > 0, "Ben should be sorted after Aaron");
|
||||
assertEquals(comparator.compare(aaron1, aaron2), 0,
|
||||
"Two people with the same name should be equal");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user