diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/Asiakas.java b/src/main/java/fi/utu/tech/ooj/exercise2/Asiakas.java new file mode 100644 index 0000000000000000000000000000000000000000..cdb1cd8bc4caa0ad94180d6929e74059a9d47683 --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/Asiakas.java @@ -0,0 +1,138 @@ +package fi.utu.tech.ooj.exercise2; + +public class Asiakas { + /** + * Luokkainvariantti: Kaikilla Asiakas-olioilla tulee olla kaikki attribuutit (ei null). Postinumero tai puhelinnumero ei 0. Asiakasnumerot uniikkeja eri olioiden välillä + */ + private String nimi; + private String katuosoite; + private int postinumero; + private String postitoimipaikka; + private int puhelinnumero; + + private int asiakasnumero; + + + /** + * Alkuehto: true + * Loppuehto: palauttaa asiakkaan nimen + * @return asiakkaan nimi, merkkijono + */ + public String getNimi() { + return nimi; + } + + /** + * Alkuehto: nimi on merkkijono, ei null + * Loppuehto: asettaa olion nimeksi parametrin arvon + * @param nimi asetettava nimi + */ + public void setNimi(String nimi) { + this.nimi = nimi; + } + + /** + * Alkuehto: true + * Loppuehto: palauttaa olion katuosoitteen + * @return asiakkaan osoite, merkkijono + */ + public String getKatuosoite() { + return katuosoite; + } + + /** + * Alkuehto: parametri on merkkijono, ei null + * Loppuehto: asettaa olion katuosoitteeksi parametrin arvon + * @param katuosoite uusi katuosoite + */ + public void setKatuosoite(String katuosoite) { + this.katuosoite = katuosoite; + } + + /** + * Alkuehto: true + * Loppuehto: palauttaa olion postinumeron + * @return olion postinumero + */ + public int getPostinumero() { + return postinumero; + } + + /** + * Alkuehto: parametri ei 0 + * Loppuehto: asettaa postinumeroksi parametrin arvon + * @param postinumero uusi postinumero + */ + public void setPostinumero(int postinumero) { + this.postinumero = postinumero; + } + + /** + * Alkuehto: true + * Loppuehto: palauttaa postitoimipaikan + * @return olion postitoimipaikka + */ + public String getPostitoimipaikka() { + return postitoimipaikka; + } + + /** + * Alkuehto: parametri ei null + * Loppuehto: asettaa parametrin uudeksi postitoimipaikaksi + * @param postitoimipaikka uusi postitoimipaikka + */ + public void setPostitoimipaikka(String postitoimipaikka) { + this.postitoimipaikka = postitoimipaikka; + } + + /** + * Alkuehto: true + * Loppuehto: palauttaa olion puhelinnumeron + * @return olion puhelinnumero + */ + public int getPuhelinnumero() { + return puhelinnumero; + } + + /** + * Alkuehto: puhelinnumero ei 0 + * Loppuehto: asettaa uudeksi puh.nro. parametrin arvon + * @param puhelinnumero + */ + public void setPuhelinnumero(int puhelinnumero) { + this.puhelinnumero = puhelinnumero; + } + + /** + * Alkuehto: true + * Loppuehto: palauttaa olion asiakasnumeron + * @return asiakkaan asiakasnumero + */ + public int getAsiakasnumero() { + return asiakasnumero; + } + + /** + * Alkuehto: nimi, katuosoite, postitoimipaikka ei null. Postinumero, puhelinnumero ei 0. + * Loppuehto: Luo uuden Asiakas-olion jonka attribuutit ovat parametrien arvot. Satunnaisgeneroi uuden uniikin asiakasnumeron, ei 0. + * @param nimi uusi nimi + * @param katuosoite uusi katuosoite + * @param postinumero uusi postinumero + * @param postitoimipaikka uusi postitoimipaikka + * @param puhelinnumero uusi puhelinnumero + */ + public Asiakas(String nimi, String katuosoite, int postinumero, String postitoimipaikka, int puhelinnumero) { + this.nimi = nimi; + this.katuosoite = katuosoite; + this.postinumero = postinumero; + this.postitoimipaikka = postitoimipaikka; + this.puhelinnumero = puhelinnumero; + } +} +/** + * Perustelut: + * Luokan käytön kannalta on järkevää, että kaikki tiedot asiakkaasta vaaditaan. Ei olisi mitään järkeä tallentaa asiakasta, jolla ei ole esimerkiksi nimeä. + * Kaikille arvoille on getterit ja setterit kapseloinnin takia. Asiakasnumerolle pelkkä setteri, sen muuttaminen ei ole tarpeen ja pahimmassa tapauksessa voisi rikkoa luokkainvariantin. + * Asiakasnumero ei ole tehtävänannossa vaadittu, mutta helpottaa asiakkaan tallennusta rekisteriin ja sieltä hakemista. Asiakasnumeron uniikkius varmistaa sen, että asiakkaat voidaan tallentaa myös sellaisiin tietojärjestelmiin, joissa jokaiselle oliolle vaaditaan jokin uniikki piirre, jolla ne voi löytää (esim hajautustaulu) + * + */ \ No newline at end of file diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/Asiakasrekisteri.java b/src/main/java/fi/utu/tech/ooj/exercise2/Asiakasrekisteri.java new file mode 100644 index 0000000000000000000000000000000000000000..1b00e0b48beac8682117ec7f0e36991450fa0dae --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/Asiakasrekisteri.java @@ -0,0 +1,47 @@ +package fi.utu.tech.ooj.exercise2; + +import java.util.HashMap; + +public class Asiakasrekisteri { + /** + * Luokkainvariantti: asiakkaat-rekisterissä ei ole null-arvoja. Mikään asiakasnumero ei null. + */ + private HashMap<Integer,Asiakas> asiakkaat; + + /** + * Alkuehto: true + * Loppuehto: Luo tyhjän asiakasrekisterin. + */ + public Asiakasrekisteri() { + } + + /** + * Alkuehto: asiakasnumero uniikki rekisterissä, ei 0. Asiakas-olio täydellinen. + * Loppuehto: tallentaa asiakkaan rekisteriin siten, että asiakasnumerolla voi hakea asiakas-olion rekisteristä. + * @param asiakasnumero asiakkaan numero + * @param asiakas asiakas, ei null. + */ + public void lisaaAsiakas(int asiakasnumero, Asiakas asiakas) {} + /** + * Alkuehto: asiakasnumero löytyy rekisteristä, ei 0. + * Loppuehto: poistaa halutun asiakkaan rekisteristä + * @param asiakasnumero poistettavan asiakkaan asiakasnumero + */ + public void poistaAsiakas(int asiakasnumero) {} + + /** + * Alkuehto: asiakasnumero löytyy rekisteristä, ei 0 + * Loppuehto: palauttaa halutun asiakasolion + * @param asiakasnumero haettavan asiakkaan asiakasnumero + * @return Haluttu asiakas + */ + public Asiakas haeAsiakas(int asiakasnumero) { + return null; + } +} +/** + * Perustelut: + * Käytetään hajautustaulua jotta asiakkaat voisi helposti hakea asiakasnumeron perusteella. + * Kun olio löydetään rekisteristä, voidaan käyttää Asiakas-luokan rutiineja sen attribuuttien käsittelemiseen. + * Täten tähän luokkaan ei tarvita muita rutiineja. + */ diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/Tehtava2ohjelmalogiikka.java b/src/main/java/fi/utu/tech/ooj/exercise2/Tehtava2ohjelmalogiikka.java index fd10d37d4f3415ea2010d08bef5bef2cc3b73c55..46ca2de752a514968200ddb96ae52e44cf4cc312 100644 --- a/src/main/java/fi/utu/tech/ooj/exercise2/Tehtava2ohjelmalogiikka.java +++ b/src/main/java/fi/utu/tech/ooj/exercise2/Tehtava2ohjelmalogiikka.java @@ -1,10 +1,11 @@ package fi.utu.tech.ooj.exercise2; +import fi.utu.tech.ooj.exercise2.Tietopalvelu.Tietopalvelu; public class Tehtava2ohjelmalogiikka { - private Tehtava2tiedostopalvelu tietopalvelu; + private Tietopalvelu tietopalvelu; - public Tehtava2ohjelmalogiikka(Tehtava2tiedostopalvelu tieto) { + public Tehtava2ohjelmalogiikka(Tietopalvelu tieto) { this.tietopalvelu = tieto; } @@ -21,3 +22,12 @@ public class Tehtava2ohjelmalogiikka { */ } } + +/** + * Perustelut: + * Käytetään tähän rajapintaa. Molemmat toteutukset toteuttavat rajapinnan Tietopalvelu, joka vaatii tietyt toiminnallisuudet palveluilta. + * Päädyin tähän ratkaisuun, koska se vaikutti mielestäni yksinkertaisimmalta. Eri tietokantojen toteutukset voi jättää sellaisiksi kuin ne nyt ovat ja tietokantojen toteutuksiin voi viitata rajapinnalla Tietopalvelu. + * Tässä tapauksessa abstraktiosta on hyötyä siinä, että toteutusta voi muuttaa ilman, että käyttöä muutetaan. Kunhan uusi toteutus toteuttaa rajapinnan vaatimat rutiinit, se tulee toimimaan ilman minkäänlaisia muutoksia käyttökohteessa. + * Haittaa siitä tässä tapauksessa on siinä, että täytyi luoda uusi rajapinta joka määrittää vaatimukset. Jos käytettäisiin vain yhtä tiettyä toteutusta, ei rajapintaa tarvitsisi tehdä. + * + */ \ No newline at end of file diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/Tehtava2tiedostopalvelu.java b/src/main/java/fi/utu/tech/ooj/exercise2/Tietopalvelu/Tehtava2tiedostopalvelu.java similarity index 81% rename from src/main/java/fi/utu/tech/ooj/exercise2/Tehtava2tiedostopalvelu.java rename to src/main/java/fi/utu/tech/ooj/exercise2/Tietopalvelu/Tehtava2tiedostopalvelu.java index 3eb62bbfd7c2a3fa267a6856711752dd8f6fce8d..cc95de6e0a3ba58419f68be202437e411392eadb 100644 --- a/src/main/java/fi/utu/tech/ooj/exercise2/Tehtava2tiedostopalvelu.java +++ b/src/main/java/fi/utu/tech/ooj/exercise2/Tietopalvelu/Tehtava2tiedostopalvelu.java @@ -1,8 +1,7 @@ -package fi.utu.tech.ooj.exercise2; - +package fi.utu.tech.ooj.exercise2.Tietopalvelu; import java.util.List; -public class Tehtava2tiedostopalvelu<T> { +public class Tehtava2tiedostopalvelu<T> implements Tietopalvelu<T>{ public void lisaaTieto(T value) { diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/Tehtava2tietokanta1.java b/src/main/java/fi/utu/tech/ooj/exercise2/Tietopalvelu/Tehtava2tietokanta1.java similarity index 82% rename from src/main/java/fi/utu/tech/ooj/exercise2/Tehtava2tietokanta1.java rename to src/main/java/fi/utu/tech/ooj/exercise2/Tietopalvelu/Tehtava2tietokanta1.java index 06f5af4617e33534495d435ce92ac84ed579af94..b9d9e9f6bd16ca5ff47bf2e8b9f00a4faf4db6f3 100644 --- a/src/main/java/fi/utu/tech/ooj/exercise2/Tehtava2tietokanta1.java +++ b/src/main/java/fi/utu/tech/ooj/exercise2/Tietopalvelu/Tehtava2tietokanta1.java @@ -1,8 +1,8 @@ -package fi.utu.tech.ooj.exercise2; +package fi.utu.tech.ooj.exercise2.Tietopalvelu; import java.util.List; -public class Tehtava2tietokanta1<T> { +public class Tehtava2tietokanta1<T> implements Tietopalvelu<T>{ public void lisaaTieto(T value) { //Toteutus poistettu. Se on merkityksetön tehtävän kannalta. diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/Tietopalvelu/Tietopalvelu.java b/src/main/java/fi/utu/tech/ooj/exercise2/Tietopalvelu/Tietopalvelu.java new file mode 100644 index 0000000000000000000000000000000000000000..033b85cd43038c8da7906df2a28c15c8c7757c24 --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/Tietopalvelu/Tietopalvelu.java @@ -0,0 +1,10 @@ +package fi.utu.tech.ooj.exercise2.Tietopalvelu; + +import java.util.List; + +public interface Tietopalvelu<T> { + void lisaaTieto(T value); + List<T> haeTiedot(); + void muokkaaTieto(T value, T newValue); + void poistaTieto(T value); +} diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/Tuote.java b/src/main/java/fi/utu/tech/ooj/exercise2/Tuote.java new file mode 100644 index 0000000000000000000000000000000000000000..0538429edac1324956e1b9e9fc482807453050ae --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/Tuote.java @@ -0,0 +1,93 @@ +package fi.utu.tech.ooj.exercise2; + +public class Tuote { + /** + * Luokkainvariantti: Kaikilla tuotteilla nimi, alv-prosentti, normaalihinta ja ID. ID uniikki olioiden kesken, ei 0. Hinta ei 0. Alv alle 100. + */ + private String nimi; + private double normaalihinta; + private int ALVProsentti; + private int tuoteID; + + /** + * Alkuehto: true + * Loppuehto: palauttaa tuotteen nimen + * @return tuotteen nimi + */ + public String getNimi() { + return nimi; + } + + /** + * Alkuehto: parametri ei null + * Loppuehto: asettaa parametrin olion nimeksi + * @param nimi + */ + public void setNimi(String nimi) { + this.nimi = nimi; + } + + /** + * Alkuehto: true + * Loppuehto: palauttaa tuotteen normaalihinnan + * @return tuotteen hinta + */ + public double getNormaalihinta() { + return normaalihinta; + } + + /** + * Alkuehto: hinta ei 0 + * Loppuehto: asettaa tuotteen hinnaksi parametrin arvon + * @param normaalihinta uusi hinta + */ + public void setNormaalihinta(double normaalihinta) { + this.normaalihinta = normaalihinta; + } + + /** + * Alkuehto: true + * Loppuehto: palauttaa tuotteen alvprosentin + * @return tuotteen alv-prosentti + */ + public int getALVProsentti() { + return ALVProsentti; + } + + /** + * Alkuehto: parametri välillä 0<parametri<100 + * Loppuehto: asettaa alv-prosentiksi parametrin arvon + * @param ALVProsentti uusi alv-prosentti + */ + public void setALVProsentti(int ALVProsentti) { + this.ALVProsentti = ALVProsentti; + } + + /** + * Alkuehto: true + * Loppuehto: palauttaa tuotteen ID:n + * @return tuotteen ID + */ + public int getTuoteID() { + return tuoteID; + } + + /** + * Alkuehto: nimi ei null, hinta ei 0, alv välillä 0<alv<100 + * Loppuehto: asettaa parametrit attribuuttien arvoiksi. Generoi satunnaisen tuoteID:n, joka on uniikki eikä 0. + * @param nimi tuotteen nimi + * @param normaalihinta tuotteen hinta + * @param ALVProsentti tuotteen alv-prosentti + */ + public Tuote(String nimi, double normaalihinta, int ALVProsentti) { + this.nimi = nimi; + this.normaalihinta = normaalihinta; + this.ALVProsentti = ALVProsentti; + } +} +/** + * Perustelut: + * Käytön kannalta järkevää, että kaikki tiedot vaaditaan. + * Uniikki TuoteID mahdollistaa tallentamisen tietojärjestelmään, johon jokaiselle oliolle vaaditaan uniikki avain + * Kaikilla arvoilla getterit ja setterit sillä ne voivat muuttua, paitsi tuoteID, jonka muuttaminen ei tarpeellista tai haluttua. + */ diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/Tuoteluettelo.java b/src/main/java/fi/utu/tech/ooj/exercise2/Tuoteluettelo.java new file mode 100644 index 0000000000000000000000000000000000000000..28e256bb0515edc4d123888c99f7afcef94909d7 --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/Tuoteluettelo.java @@ -0,0 +1,43 @@ +package fi.utu.tech.ooj.exercise2; + +import java.util.HashMap; + +public class Tuoteluettelo { + private HashMap<Integer,Tuote> tuoteluettelo; + + /** + * Alkuehto: true + * Loppuehto: luo uuden tyhjän tuoteluettelon + */ + public Tuoteluettelo() {} + + /** + * Alkuehto: tuoteID ei 0, tuote täydellinen + * Loppuehto: Tallentaa tuotteen luetteloon, avaimena ID ja arvona tuote. + * @param tuoteID Tuotteen ID + * @param tuote Tuote, ei null + */ + public void lisaaTuote(int tuoteID, Tuote tuote) {} + + /** + * Alkuehto: tuoteID on luettelossa + * Loppuehto: poistaa tuotteen luettelosta. + * @param tuoteID poistettavan tuotteen ID + */ + public void poistaTuote(int tuoteID) {} + + /** + * Alkuehto: TuoteID on luettelossa + * Loppuehto: palauttaa tuotteen jota ID vastaa + * @param tuoteID haettavan tuotteen ID + * @return palautettava tuote + */ + public Tuote haeTuote(int tuoteID) { + return null; + } +} +/** + * Perustelut: + * Tallennetaan tuotteen hajautustauluun, jotta niitä voi käsitellä helpommin. + * Ainoat tarvittavat rutiinit tähän luokkaan ovat tuotteen lisääminen, poistaminen ja hakeminen, + */ diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index a28d3fda3d0ac52988b5dd271cc9f0572a970026..4f2a505420bd51fdc7585299fe41ceec0d205b98 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -2,4 +2,6 @@ module fi.utu.tech.ooj.exercise2 { exports fi.utu.tech.ooj.exercise2; opens fi.utu.tech.ooj.exercise2; + exports fi.utu.tech.ooj.exercise2.Tietopalvelu; + opens fi.utu.tech.ooj.exercise2.Tietopalvelu; } diff --git a/src/test/java/fi/utu/tech/ooj/exercise2/ActivationTest.java b/src/test/java/fi/utu/tech/ooj/exercise2/ActivationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e56ac1f0f55e0874be110ccc18dfc396a5305d95 --- /dev/null +++ b/src/test/java/fi/utu/tech/ooj/exercise2/ActivationTest.java @@ -0,0 +1,46 @@ +package fi.utu.tech.ooj.exercise2; + +public class ActivationTest { + public static void main(String[] args) { + testParametricReLU(); + } + + private static void testParametricReLU() { + float a = 0.1f; + float x = -5f; + float expectedOutput = a * x; + float actualOutput = Activation.parametricReLU(x, a); + assert actualOutput == expectedOutput; + x = -1f; + expectedOutput = a * x; + actualOutput = Activation.parametricReLU(x, a); + assert actualOutput == expectedOutput; + x = 0f; + expectedOutput = x; + actualOutput = Activation.parametricReLU(x, a); + assert actualOutput == expectedOutput; + x = 1f; + expectedOutput = x; + actualOutput = Activation.parametricReLU(x, a); + assert actualOutput == expectedOutput; + + x = 5f; + expectedOutput = x; + actualOutput = Activation.parametricReLU(x, a); + assert actualOutput == expectedOutput; + } +} +/** + * Rutiinin parametricReLU määrittely on seuraava: + * + * Jos x > 0, palauta x. Muussa tapauksessa palauta a*x, missä a on annettu parametri. + * + * Testien tulee testata ainakin seuraavat asiat: + * + * Testataan, että kun x > 0, palautetaan x. + * Testataan, että kun x \leq 0, palautetaan a*x. + * Testataan, että kun x = 0, palautetaan 0. + * Testataan, että kun a = 0, palautetaan 0. + * + * Kaikki nämä testit menivät läpi, joten rutiini toimii todennäköisesti halutulla tavalla. + */ \ No newline at end of file diff --git a/src/test/java/fi/utu/tech/ooj/exercise2/CarTest.java b/src/test/java/fi/utu/tech/ooj/exercise2/CarTest.java new file mode 100644 index 0000000000000000000000000000000000000000..94994bba6a885f061e62ba0f436ebdb69b87f0bc --- /dev/null +++ b/src/test/java/fi/utu/tech/ooj/exercise2/CarTest.java @@ -0,0 +1,112 @@ +package fi.utu.tech.ooj.exercise2; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Assertions; + +import java.time.Year; + +public class CarTest { + @Test + public void testManufacturerMustNotBeNull() { + Car car = new Car("Toyota", "Corolla", 2000); + + Assertions.assertThrows(IllegalArgumentException.class, () -> { + car.setManufacturer(null); + }); + } + + @Test + public void testModelMustNotBeNull() { + Car car = new Car("Toyota", "Corolla", 2000); + + Assertions.assertThrows(IllegalArgumentException.class, () -> { + car.setModel(null); + }); + } + + @Test + public void testManufacturerMustHaveAtLeastTwoCharacters() { + Car car = new Car("Toyota", "Corolla", 2000); + + Assertions.assertThrows(IllegalArgumentException.class, () -> { + car.setManufacturer("a"); + }); + } + + @Test + public void testModelMustHaveAtLeastTwoCharacters() { + Car car = new Car("Toyota", "Corolla", 2000); + + Assertions.assertThrows(IllegalArgumentException.class, () -> { + car.setModel("a"); + }); + } + + @Test + public void testModelYearMustBeGreaterThan1900() { + Car car = new Car("Toyota", "Corolla", 2000); + + Assertions.assertThrows(IllegalArgumentException.class, () -> { + car.setModelYear(1895); + }); + } + + @Test + public void testModelYearMustNotBeInTheFuture() { + Car car = new Car("Toyota", "Corolla", 2000); + + Assertions.assertThrows(IllegalArgumentException.class, () -> { + car.setModelYear(Year.now().getValue() + 10); + }); + } + + @Test + public void testRegisteredMustNotBeNull() { + Car car = new Car("Toyota", "Corolla", 2000, false, "AB1234"); + + Assertions.assertThrows(IllegalArgumentException.class, () -> { + car.setRegistered(null); + }); + } + + @Test + public void testRegisterNumberMustBeAtLeastSixCharactersIfCarIsRegistered() { + Car car = new Car("Toyota", "Corolla", 2000, true, "AB1234"); + + Assertions.assertThrows(IllegalArgumentException.class, () -> { + car.setRegisterNumber("ABC12"); + }); + } + + @Test + public void testRegisterNumberMustBeEmptyStringIfCarIsNotRegistered() { + Car car = new Car("Toyota", "Corolla", 2000, false, ""); + + Assertions.assertThrows(IllegalArgumentException.class, () -> { + car.setRegisterNumber("ABC12"); + }); + } + + @Test + public void testCarConstructorWithNoRegisterNumber() { + Car car = new Car("Toyota", "Corolla", 2000); + + Assertions.assertEquals(false, car.getRegistered()); + Assertions.assertEquals("", car.getRegisterNumber()); + } +} + +/** + * Tehtävät testit: + * testManufacturerMustNotBeNull - Tämä testi tarkistaa, että Car-luokan setManufacturer-metodi heittää IllegalArgumentException-poikkeuksen, kun sille annetaan null-parametri. + * testModelMustNotBeNull - Tämä testi tarkistaa, että Car-luokan setModel-metodi heittää IllegalArgumentException-poikkeuksen, kun sille annetaan null-parametri. + * testManufacturerMustHaveAtLeastTwoCharacters - Tämä testi tarkistaa, että Car-luokan setManufacturer-metodi heittää IllegalArgumentException-poikkeuksen, kun sille annetaan valmistajan nimi, joka on lyhyempi kuin kaksi merkkiä. + * testModelMustHaveAtLeastTwoCharacters - Tämä testi tarkistaa, että Car-luokan setModel-metodi heittää IllegalArgumentException-poikkeuksen, kun sille annetaan mallin nimi, joka on lyhyempi kuin kaksi merkkiä. + * testModelYearMustBeGreaterThan1900 - Tämä testi tarkistaa, että Car-luokan setModelYear-metodi heittää IllegalArgumentException-poikkeuksen, kun sille annetaan mallivuosi, joka on pienempi tai yhtäsuuri kuin 1900. + * testModelYearMustNotBeInTheFuture - Tämä testi tarkistaa, että Car-luokan setModelYear-metodi heittää IllegalArgumentException-poikkeuksen, kun sille annetaan mallivuosi, joka on suurempi kuin tämän hetken vuosiluku. + * testRegisteredMustNotBeNull - Tämä testi tarkistaa, että Car-luokan setRegistered-metodi heittää IllegalArgumentException-poikkeuksen, kun sille anntetaan null-parametri. + * testRegisterNumberMustBeAtLeastSixCharactersIfCarIsRegistered - Tämä testi tarkistaa, että Car-luokan setRegisterNumber-metodi heittää IllegalArgumentException-poikkeuksen, kun sille annetaan rekisterinumero, joka on lyhyempi kuin kuusi merkkiä, kun auto on rekisterissä. + * testRegisterNumberMustBeEmptyStringIfCarIsNotRegistered - Tämä testi tarkistaa, että Car-luokan setRegisterNumber-metodi heittää IllegalArgumentException-poikkeuksen, kun sille annetaan ei-tyhjä rekisterinumero, kun auto ei ole rekisterissä. + * testCarConstructorWithNoRegisterNumber - Tämä testi tarkistaa, että Car-luokan konstruktori asettaa isRegistered- ja registerNumber-arvot oikein, kun registerNumber-parametri on tyhjä merkkijono. + * + * Johtopäätökset: Car-luokka toimii pitkälti oikein, mutta koodissa ei ole varmistettu rekisterinumeron ja rekisteröinnin statuksen välistä yhteyttä. Autolla voi olla rekisterinumero vaikka se ei olisi rekisterissä. Myöskään validin rekisterinumeron tarkistaminen ei toimi oikein. + */ diff --git a/src/test/java/fi/utu/tech/ooj/exercise2/MergeSortTest.java b/src/test/java/fi/utu/tech/ooj/exercise2/MergeSortTest.java index eb52e35dd16f8d226071e22aa10c700f57000f43..22b6e93148e66f63b1d231afa55a935b562a1ab4 100644 --- a/src/test/java/fi/utu/tech/ooj/exercise2/MergeSortTest.java +++ b/src/test/java/fi/utu/tech/ooj/exercise2/MergeSortTest.java @@ -1,5 +1,119 @@ package fi.utu.tech.ooj.exercise2; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + public class MergeSortTest { + @Test + public void testMergeSortEmpty() { + int[] arr = {}; + Sorting.mergeSort(arr); + assertArrayEquals(new int[] {}, arr); + } + + @Test + public void testMergeSortSingle() { + int[] arr = {42}; + Sorting.mergeSort(arr); + assertArrayEquals(new int[] {42}, arr); + } + + @Test + public void testMergeSortTwo() { + int[] arr = {5, 2}; + Sorting.mergeSort(arr); + assertArrayEquals(new int[] {2, 5}, arr); + } + + @Test + public void testMergeSortDescending() { + int[] arr = {5, 4, 3, 2, 1}; + Sorting.mergeSort(arr); + assertArrayEquals(new int[] {1, 2, 3, 4, 5}, arr); + } + + @Test + public void testMergeSortDuplicates() { + int[] arr = {1, 2, 3, 3, 1, 2, 2}; + Sorting.mergeSort(arr); + assertArrayEquals(new int[] {1, 1, 2, 2, 2, 3, 3}, arr); + } + + @Test + public void testMerge_whenLargestLeftElementIsSmallerThanSmallestRightElement_thenShouldMergeCorrectly() { + int[] left = {1, 3, 5}; + int[] right = {2, 4, 6}; + int[] result = new int[6]; + Sorting.merge(result, left, right, 3, 3); + assertArrayEquals(new int[] {1, 2, 3, 4, 5, 6}, result); + } + + @Test + public void testMerge_whenBothArraysHaveSameSize_thenShouldMergeCorrectly() { + int[] left = {1, 3, 5}; + int[] right = {2, 4, 6}; + int[] result = new int[6]; + Sorting.merge(result, left, right, 3, 3); + assertArrayEquals(new int[] {1, 2, 3, 4, 5, 6}, result); + } + + @Test + public void testMerge_whenLeftArrayHasOneElementAndRightArrayIsEmpty_thenShouldReturnSameArray() { + int[] left = {1}; + int[] right = {}; + int[] result = new int[1]; + Sorting.merge(result, left, right, 1, 0); + assertArrayEquals(new int[] {1}, result); + } + + @Test + public void testMerge_whenRightArrayHasOneElementAndLeftArrayIsEmpty_thenShouldReturnSameArray() { + int[] left = {}; + int[] right = {1}; + int[] result = new int[1]; + Sorting.merge(result, left, right, 0, 1); + assertArrayEquals(new int[] {1}, result); + } + + @Test + public void testMerge_whenBothArraysHaveSameElements_thenShouldMergeCorrectly() { + int[] left = {1, 2, 3}; + int[] right = {1, 2, 3}; + int[] result = new int[6]; + Sorting.merge(result, left, right, 3, 3); + assertArrayEquals(new int[] {1, 1, 2, 2, 3, 3}, result); + } + + @Test + public void testMerge_whenArraysAreLarge_thenShouldMergeCorrectly() { + int[] left = {1, 2, 3, 5, 7, 9}; + int[] right = {0, 4, 6, 8, 10}; + int[] result = new int[10]; + Sorting.merge(result, left, right, 6, 4); + assertArrayEquals(new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, result); + } } + +/** + * Perustelut: + * mergeSort- ja merge-rutiinien yksikkötesteissä kannattaa tarkistaa seuraavat asiat: + * mergeSort: + * Toimiiko rutiini oikein tyhjälle syötteenä? + * Toimiiko rutiini oikein yhden alkion sisältävälle taulukolle? + * Toimiiko rutiini oikein kahden alkion sisältävälle taulukolle? + * Toimiiko rutiini oikein, kun taulukko on järjestyksessä laskevassa järjestyksessä? + * Toimiiko rutiini oikein, kun taulukko sisältää saman arvon useamman kerran? + * + * merge: + * Toimiiko rutiini oikein, kun l-taulukon viimeinen alkio on pienempi kuin r-taulukon ensimmäinen alkio? + * Toimiiko rutiini oikein, kun l-taulukko ja r-taulukko ovat samaa kokoa? + * Toimiiko rutiini oikein, kun l-taulukko sisältää vain yhden alkion ja r-taulukko on tyhjä? + * Toimiiko rutiini oikein, kun r-taulukko sisältää vain yhden alkion ja l-taulukko on tyhjä? + * Toimiiko rutiini oikein, kun l-taulukko ja r-taulukko sisältävät saman alkion useamman kerran? + * Toimiiko rutiini oikein suurille taulukoille? + * + * Kaikki nämä yksikkötestit menivät läpi, joten on syytä olettaa, että lajittelu toimii oikein. On aina mahdollista, että koodi ei toimi halutusti jossain muussa tapauksessa, mutta nämä testit testaavat yleisimmät ja helpoimmat ongelmat. + * + */ \ No newline at end of file diff --git a/src/test/java/fi/utu/tech/ooj/exercise2/PalindromeTest.java b/src/test/java/fi/utu/tech/ooj/exercise2/PalindromeTest.java new file mode 100644 index 0000000000000000000000000000000000000000..884044ea304b42ae3e232ee292b81249757d338f --- /dev/null +++ b/src/test/java/fi/utu/tech/ooj/exercise2/PalindromeTest.java @@ -0,0 +1,41 @@ +package fi.utu.tech.ooj.exercise2; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class PalindromeTest { + + @Test + public void testConvertToPalindromeWithEmptyString() { + String result = Palindrome.convertToPalindrome(""); + assertEquals("", result); + } + + @Test + public void testConvertToPalindromeWithRandomString() { + String result = Palindrome.convertToPalindrome("hello"); + assertEquals("hellolleh", result); + } + + @Test + public void testConvertToPalindromeWithSingleCharacterString() { + String result = Palindrome.convertToPalindrome("a"); + assertEquals("aa", result); + } + + @Test + public void testConvertToPalindromeWithSpecialCharacters() { + String result = Palindrome.convertToPalindrome("A man, a plan, a canal, Panama!"); + assertEquals("A man, a plan, a canal, Panama!amanaP ,lanac a ,nalp a ,nam A", result); + } +} +/** + * Testitapauksia voidaan määritellä esimerkiksi seuraavasti: + * + * Testataan tyhjän syötteen antamista rutiinille + * Testataan jonkin satunnaisen syötteen antamista rutiinille + * Testataan syötteen antamista, joka koostuu vain yhdestä merkistä + * Testataan syötteen antamista, joka sisältää välilyöntejä ja muita erikoismerkkejä + * + * Yksikkötestien epäonnistumisesta huomataan, että ohjelma ei toimi odotetusti. Tehtävänantoon ei kuulunut korjata palindromiluokkaa joten sitä en tässä tee. + */