import java.util.*; /** * Testausluokka TRA I tehtävään X3. */ public class TRAI_23_X3_testi { static Random rnd = new Random(); static TRAI_23_X3 testattava = new TRAI_23_X3_pohja(); /* <-- Oma tunnus tähän */ public static void main(String[] args) { // taulukoiden koko int N = 10; if (args.length > 0) N = Integer.parseInt(args[0]); // satunnaislukusiemen int siemen = 42; if (args.length > 1) siemen = Integer.parseInt(args[1]); // tulostusten määrä int print = 5; if (args.length > 2) print = Integer.parseInt(args[2]); rnd.setSeed(siemen); boolean ok = true; // satunnaisia ok &= testaaTulosX3(N, 0, N, false, N/2, print); ok &= testaaTulosX3(N, 0, N * 2, false, N/2, print); ok &= testaaTulosX3(N*2, 0, N * 4, false, N, print); // kaikki paitsi pienin siirretään ok &= testaaTulosX3(N, 0, N, true, 0, print); // vain suurin siirretään ok &= testaaTulosX3(N, 0, N, true, N-1, print); // kaikki siirretään ok &= testaaTulosX3(N, 0, N, true, -1, print); // ei yhtään siirretä ok &= testaaTulosX3(N, 0, N, true, N+1, print); ok &= testaaTulosX3(1, 1, 1, false, 0, print); ok &= testaaTulosX3(1, 1, 1, false, 1, print); ok &= testaaTulosX3(1, 1, 1, false, 2, print); ok &= testaaTulosX3(2, 1, 2, true, 0, print); ok &= testaaTulosX3(2, 1, 2, true, 1, print); ok &= testaaTulosX3(2, 1, 2, true, 2, print); ok &= testaaTulosX3(2, 1, 2, true, 3, print); System.out.println("\nTestataan merkkijonoilla "); ok &= testaaTulosX3mjono(5, 1, print); ok &= testaaTulosX3mjono(15, 1, print); ok &= testaaTulosX3mjono(15, 2, print); if (ok) System.out.println("\nAlun testit antoivat kaikki oikean tuloksen."); // asetetaan "satunnainen" satunnaislukusiemen rnd.setSeed(System.currentTimeMillis()); // testataan monta satunnaista syötettä int nTest = 1000; int k = 0; int virheet = 0; for (k = 0; k < nTest; k++) { if (! testaaTulosX3(N, 0, N, rnd.nextBoolean(), rnd.nextInt(N+3), 0)) virheet++; if (virheet > 30) break; } if (virheet > 0) ok = false; System.out.println("\n" + k + " testistä " + (k-virheet) + " oikein."); if (ok) System.out.println("\nKaikki tehdyt testit antoivat oikean tuloksen."); else System.out.println("\nJoissain testeissä virheitä."); } /** * Testaa jaottelua annetun kokoisella listalla * * @param n listan alkioiden määrä * @param min pienin luku listassa * @param max suurin luku listassa * @param varmistaRajat varmistetaanko min ja max kuhunkin listaan * @param raja jaotteluraja * @param print tulostuksen määrä * @return true jos testi meni oikein, muuten false */ static boolean testaaTulosX3(int n, int min, int max, boolean varmistaRajat, Integer raja, int print) { // generoidaan syöte LinkedList L = satunnainenLista(n, min, max, varmistaRajat); LinkedList cL = new LinkedList<>(L); // kopio syötteestä talteen if (print > 0) System.out.println("\nTESTI n="+n + "min="+min + " max="+max + " raja="+raja); // tulostetaan syötteet if (n < 20 && print > 2 || print > 5) { System.out.println("L=(" + n + "): " + L + " raja: " + raja); } // kutsutaan testattavaa metodia LinkedList tulos = testattava.siirraSuuremmat(L, raja); // tulostetaan tulos if (print > 0) { if (n < 20 && print > 2 || print > 5) { System.out.println("Jäljelle jäi: " + L); System.out.println("Siirrettiin : " + tulos); } System.out.println("Syöte " + n + " kpl -> L " + L.size() + " tulos " + tulos.size() + " yhteensä " + (L.size() + tulos.size()) + " kpl" ); } boolean ok = true; // tarkastetaan, että alkioiden yhteismäärä säilyi if (n != L.size() + tulos.size()) { ok = false; if (print > 0) System.out.println("Listojen alkiomäärät eivät täsmää!"); } // tarkastetaan, että jaottelu meni oikein ok &= eihanOleSuurempia(L, raja, print); ok &= ovathanSuurempia(tulos, raja, print); ok &= vertaaSisallot(cL, L, tulos); ok &= onkoSamaJarjestys(L, cL, print); ok &= onkoSamaJarjestys(tulos, cL, print); return ok; } /** * Testaa jaottelua merkkijonolla. * * @param n listan alkioiden määrä * @param len merkkijonojen pituus * @param print * @return */ static boolean testaaTulosX3mjono(int n, int len, int print) { // generoidaan syöte LinkedList L = satunnainenListaS(n, len); LinkedList cL = new LinkedList<>(L); // kopio syötteestä talteen String raja = randomString(rnd, len); if (print > 0) System.out.println("\nTESTI n="+n + " len="+len + " raja="+raja); // tulostetaan syötteet if (n < 20 && print > 2 || print > 5) { System.out.println("L=(" + n + "): " + L + " raja: " + raja); } // kutsutaan testattavaa metodia LinkedList tulos = testattava.siirraSuuremmat(L, raja); // tulostetaan tulos if (print > 0) { if (n < 20 && print > 2 || print > 5) { System.out.println("Jäljelle jäi: " + L); System.out.println("Siirrettiin : " + tulos); } System.out.println("Syöte " + n + " kpl -> L " + L.size() + " tulos " + tulos.size() + " yhteensä " + (L.size() + tulos.size()) + " kpl" ); } boolean ok = true; // tarkastetaan, että alkioiden yhteismäärä säilyi if (n != L.size() + tulos.size()) { ok = false; if (print > 0) System.out.println("Listojen alkiomäärät eivät täsmää!"); } // tarkastetaan, että jaottelu meni oikein ok &= eihanOleSuurempia(L, raja, print); ok &= ovathanSuurempia(tulos, raja, print); ok &= vertaaSisallot(cL, L, tulos); ok &= onkoSamaJarjestys(L, cL, print); ok &= onkoSamaJarjestys(tulos, cL, print); return ok; } /** * Generoi satunnaisen n kokoisen listan * * @param n alkioiden määrä * @param min pienin mahdollinen alkio * @param max suurin mahdollinen alkio * @param varmistaRajat jos tosi, niin min ja max ovat aina mukana (paitsi jos n<2) * @return uusi taulukko. */ static LinkedList satunnainenLista(int n, int min, int max, boolean varmistaRajat) { LinkedList tulos = new LinkedList<>(); int k = 0; if (max < 1) max = 1; if (n < 2) max = min; if (varmistaRajat) { if (n >= 1) { tulos.add(min); k++; } if (n >= 2) { tulos.add(rnd.nextInt(2), max); k++; } } for (int i = k; i < n; i++) { tulos.add(rnd.nextInt(max - min + 1) + min); } return tulos; } /** * Generoi satunnaisen n kokoisen merkkijonolistan * * @param n alkioiden määrä * @param len merkkijonojen pituus * @return uusi lista */ static LinkedList satunnainenListaS(int n, int len) { LinkedList tulos = new LinkedList<>(); int k = 0; for (int i = k; i < n; i++) { tulos.add(randomString(rnd, len)); } return tulos; } /** * Palauttaa satunnaisen len mittaisen merkkijonon. * * @param r satunnaislukugeneraattori * @param len merkkijonon pituus * @return uusi merkkijono */ public static String randomString(Random r, int len) { char[] C = new char[len]; for (int i = 0; i < len; i++) C[i] = (char) (r.nextInt(26) + 'a'); return new String(C); } /** * Tarkastaa ettei listassa ole suurempia alkioita kuin raja. * * @param alkiotyyppi * @param L tarkastettava lista * @param raja vertailtava raja-arvo * @param print tulostusten määrä * @return tosi, jos mikään ei ole suurempia tai yhtäsuuri kuin raja, muuten epätosi */ static public > boolean eihanOleSuurempia(LinkedList L, E raja, int print) { for (E a : L) { if (a == null) { if (print > 1) System.out.println("VIRHE: Listassa L null alkio!"); return false; } else if (a.compareTo(raja) > 0) { if (print > 1) System.out.println("VIRHE: Suurempi alkio jäljellä: " + a + " > " + raja); return false; } } return true; } /** * Tarkastaa että listan kaikki alkiot ovat suurempia kuin raja. * * @param alkiotyyppi * @param L tarkastettava lista * @param raja vertailtava raja-arvo * @param print tulostusten määrä * @return tosi, jos kaikki ovat suurempia, muuten epätosi */ static public > boolean ovathanSuurempia(LinkedList L, E raja, int print) { for (E a : L) { if (a == null) { if (print > 1) System.out.println("VIRHE: Listassa null alkio!"); return false; } else if (a.compareTo(raja) <= 0) { if (print > 1) System.out.println("VIRHE: Pienempi tai yhtäsuuri löytyi: " + a + " <= " + raja); return false; } } return true; } static public > boolean onkoSamaJarjestys(LinkedList L, LinkedList vrt, int print) { Iterator vrtIt = vrt.iterator(); E vrtElem = nextOrNull(vrtIt); for (E elem : L) { while (!elem.equals(vrtElem) && vrtElem != null) vrtElem = nextOrNull(vrtIt); if (vrtElem == null) { if (print > 4) System.out.println("VIRHE: alkio " + elem + " tuloksessa väärässä paikassa tai puuttuu syötteestä"); return false; } } return true; } static > E nextOrNull(Iterator i) { return i.hasNext() ? i.next() : null; } /** * Vertaa, että onhan listojen A ja B yhteissisältö sama kuin listan S. * @param S Kaikkien alkioiden lista * @param A Osa-alkioiden lista * @param B Osa-alkioiden lista * @param alkiotyyppi * @return tosi, jos sisällöt täsmäävät, muuten epätosi */ static boolean vertaaSisallot(LinkedList S, LinkedList A, LinkedList B) { Map MS = new HashMap<>(); Map MAB = new HashMap<>(); for (E x : S) MS.compute(x, (k, v) -> v == null ? 1 : v+1); for (E x : A) MAB.compute(x, (k, v) -> v == null ? 1 : v+1); for (E x : B) MAB.compute(x, (k, v) -> v == null ? 1 : v+1); // TODO: voisi tulostaa mahdollisia virheitä return MS.equals(MAB); } }