From 09e85e9945dc39705daba2af992283d0ceb59146 Mon Sep 17 00:00:00 2001 From: schneefux Date: Sat, 29 Sep 2018 21:30:09 +0200 Subject: test --- pom.xml | 19 + src/de/ostfalia/algo/ws18/base/Gender.java | 11 + src/de/ostfalia/algo/ws18/base/IManagement.java | 81 ++++ src/de/ostfalia/algo/ws18/base/IMember.java | 53 +++ src/de/ostfalia/algo/ws18/base/KindOfSport.java | 19 + src/de/ostfalia/algo/ws18/base/Member.java | 210 ++++++++++ src/de/ostfalia/algo/ws18/s1/LinkedListNode.java | 63 +++ src/de/ostfalia/algo/ws18/s1/Main.java | 24 ++ src/de/ostfalia/algo/ws18/s1/Management.java | 275 +++++++++++++ src/de/ostfalia/algo/ws18/s1/test/LageTestS1.java | 365 ++++++++++++++++++ .../algo/ws18/s1/test/ManagementTestS1.java | 397 +++++++++++++++++++ src/de/ostfalia/algo/ws18/s1/test/MemberTest.java | 260 +++++++++++++ src/de/ostfalia/algo/ws18/s2/Management.java | 84 ++++ src/de/ostfalia/algo/ws18/s2/test/LageTestS2.java | 366 ++++++++++++++++++ .../algo/ws18/s2/test/ManagementTestS2.java | 424 +++++++++++++++++++++ src/de/ostfalia/algo/ws18/s2/test/MemberTest.java | 260 +++++++++++++ 16 files changed, 2911 insertions(+) create mode 100644 pom.xml create mode 100644 src/de/ostfalia/algo/ws18/base/Gender.java create mode 100644 src/de/ostfalia/algo/ws18/base/IManagement.java create mode 100644 src/de/ostfalia/algo/ws18/base/IMember.java create mode 100644 src/de/ostfalia/algo/ws18/base/KindOfSport.java create mode 100644 src/de/ostfalia/algo/ws18/base/Member.java create mode 100644 src/de/ostfalia/algo/ws18/s1/LinkedListNode.java create mode 100644 src/de/ostfalia/algo/ws18/s1/Main.java create mode 100644 src/de/ostfalia/algo/ws18/s1/Management.java create mode 100644 src/de/ostfalia/algo/ws18/s1/test/LageTestS1.java create mode 100644 src/de/ostfalia/algo/ws18/s1/test/ManagementTestS1.java create mode 100644 src/de/ostfalia/algo/ws18/s1/test/MemberTest.java create mode 100644 src/de/ostfalia/algo/ws18/s2/Management.java create mode 100644 src/de/ostfalia/algo/ws18/s2/test/LageTestS2.java create mode 100644 src/de/ostfalia/algo/ws18/s2/test/ManagementTestS2.java create mode 100644 src/de/ostfalia/algo/ws18/s2/test/MemberTest.java diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..98564b8 --- /dev/null +++ b/pom.xml @@ -0,0 +1,19 @@ + + 4.0.0 + AlgoAufgabe1 + AlgoAufgabe1 + 0.0.1-SNAPSHOT + + src + + + maven-compiler-plugin + 3.8.0 + + 1.8 + 1.8 + + + + + \ No newline at end of file diff --git a/src/de/ostfalia/algo/ws18/base/Gender.java b/src/de/ostfalia/algo/ws18/base/Gender.java new file mode 100644 index 0000000..fe5b4de --- /dev/null +++ b/src/de/ostfalia/algo/ws18/base/Gender.java @@ -0,0 +1,11 @@ +package de.ostfalia.algo.ws18.base; + +/** + * @author M. Gruendel + */ +public enum Gender { + + M, + F + +} diff --git a/src/de/ostfalia/algo/ws18/base/IManagement.java b/src/de/ostfalia/algo/ws18/base/IManagement.java new file mode 100644 index 0000000..11091c2 --- /dev/null +++ b/src/de/ostfalia/algo/ws18/base/IManagement.java @@ -0,0 +1,81 @@ +package de.ostfalia.algo.ws18.base; + +/** + * @author M. Gruendel + */ +public interface IManagement { + + /** + * Liefert die Anzahl der Datensaetze. + * @return Anzahl der Datensaetze: int. + */ + public int size(); + + + /** + * Fuegt ein Mitglied dem Datensatz hinzu. + * @param member - hinzuzufuegendes Mitglied: IMember. + * @return true, wenn das Mitglied hinzugefuegt werden konnte, sonst + * false. + */ + public boolean insert(IMember member); + + + /** + * Sucht nach einem Datensatz mit dem angegebenen Schluessel. + * @param key - Schluesselwert: long + * @return - den gefundenen Datensatz, oder null, wenn der Schluesselwert + * nicht gefunden werden konnte: IMember. + */ + public IMember search(long key); + + + /** + * Sucht nach dem ersten Datensatz mit dem angegebenen Namen und Vornamen. + * @param name - Nachname des Mitglieds: String. + * @param firstName - Vorname des Mitglieds: String. + * @return - den gefundenen Datensatz, oder null, wenn der Schluesselwert + * nicht gefunden werden konnte: IMember. + */ + public IMember search(String name, String firstName); + + + /** + * Liefert die Anzahl der Datensaetze mit der angegebenen Sportart zurueck. + * @param kindOfSport die gesuchte Sportart: KindOfSport. + * @return - Anzahl der Datensaetze mit der angegebenen Sportart: int. + */ + public int size(KindOfSport kindOfSport); + + + /** + * Liefert die Datensaetze mit der angegebenen Sportart zurueck. + * @param kindOfSport die gesuchte Sportart: KindOfSport. + * @return - die Datensaetze mit der angegebenen Sportart: IMember[]. + */ + public IMember[] discipline(KindOfSport kindOfSport); + + /** + * Liefert alle Datensaetze als Array von IMember zurueck. + * @return - alle Datensaetze als Array: IMember[]. + */ + public IMember[] toArray(); + + /** + * Liefert die Anzahl grundlegenden Operationen bei der zuvor aufgerufenen + * Zugriffsmethode zurueck. + * @return - Anzahl grundlegenden Operationen bei der zuvor aufgerufenen + * Zugriffsmethode: int. + */ + public int numberOfOperations(); + + + /** + * Nur fuer Aufgabe 3: liefert die Hoehe des binaeren Suchbaums zurueck. + * @return - die Hoehe des binaeren Suchbaums: int. + */ + public default int height() { + return 0; + }; + +} diff --git a/src/de/ostfalia/algo/ws18/base/IMember.java b/src/de/ostfalia/algo/ws18/base/IMember.java new file mode 100644 index 0000000..e579ad7 --- /dev/null +++ b/src/de/ostfalia/algo/ws18/base/IMember.java @@ -0,0 +1,53 @@ +package de.ostfalia.algo.ws18.base; + +import java.time.LocalDate; + +/** + * @author M. Gruendel + */ +public interface IMember extends Comparable { + + /** + * Liefert den Schluesselwert zurueck. + * @return - den Schluesselwert: int. + */ + public long getKey(); + + /** + * Liefert den Nachnamen des Mitglieds zurueck. + * @return - den Nachnamen des Mitglieds: String. + */ + public String getName(); + + /** + * Liefert den Vornamen des Mitglieds zurueck. + * @return - den Vornamen des Mitglieds: String. + */ + public String getFirstName(); + + /** + * Liefert das Geschlecht des Mitglieds zurueck. + * @return Geschlecht des Mitglieds: Gender. + */ + public Gender getGender(); + + /** + * Liefert das Geburtsdatum des Mitglieds zurueck. + * @return Geburtsdatum des Mitglieds: LocalDate. + */ + public LocalDate getDate(); + + /** + * liefert die Sportart zurueck. + * @return - die Sportart: KindOfSport; + */ + public KindOfSport getKindOfSport(); + + /** + * Liefert den Datensatz inklusive Schluesselwert als String zurueck.

+ * Beispiel: "82115101922, Hueber, Uta, 1922-10-15, F, HANDBALL" + * @return Datensatz inklusive Schluesselwert: String. + */ + public String toString(); + +} diff --git a/src/de/ostfalia/algo/ws18/base/KindOfSport.java b/src/de/ostfalia/algo/ws18/base/KindOfSport.java new file mode 100644 index 0000000..f6e43d0 --- /dev/null +++ b/src/de/ostfalia/algo/ws18/base/KindOfSport.java @@ -0,0 +1,19 @@ +package de.ostfalia.algo.ws18.base; + +/** + * @author M. Gruendel + */ +public enum KindOfSport { + + FUSSBALL, + HANDBALL, + SCHWIMMEN, + LEICHTATHLETIK, + REITEN, + FECHTEN, + TURNEN, + RADSPORT, + TANZEN, + RUDERN + +} diff --git a/src/de/ostfalia/algo/ws18/base/Member.java b/src/de/ostfalia/algo/ws18/base/Member.java new file mode 100644 index 0000000..5e24b81 --- /dev/null +++ b/src/de/ostfalia/algo/ws18/base/Member.java @@ -0,0 +1,210 @@ +package de.ostfalia.algo.ws18.base; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +public class Member implements IMember { + /** + * Schlüssel kodiert als: + * Anfangsbuchstabe des Namens, codiert in + * zwei Dezimalziffern a -> 01, b -> 02, …, z -> 26. + * Diese Zuordnung gilt für Groß- und Kleinbuchstaben, + * Umlaute werden als ae, oe, ue dargestellt. + * Anfangsbuchstabe des Vornamens, codiert in + * zwei Dezimalziffern, siehe Name + * Geburtsdatum, ttmmjjjj + * + * Sie können davon ausgehen, dass doppelte Schlüssel nicht vorkommen. + */ + private long key; + + /** + * Name. + */ + private String name; + + /** + * Firstname. + */ + private String firstname; + + /** + * Date. + */ + private LocalDate date; + + /** + * Gender. + */ + private Gender gender; + + /** + * Associated kind of sport. + */ + private KindOfSport kindOfSport; + + /** + * Parse a CSV to a Member. + * + * @param csv A CSV String separated by ', ', + * with the row signature 'name, firstname, date, gender, kind of sport' + * @return A Member. + */ + public Member(String csv) { + final String DELIMITER = ", "; + String[] columns = csv.split(DELIMITER); + + if (columns.length != 5) { + throw new IllegalArgumentException( + "Row '" + csv + "' is not a valid format!"); + } + + this.name = columns[0]; + this.firstname = columns[1]; + this.date = LocalDate.parse(columns[2], + DateTimeFormatter.ISO_DATE); + this.gender = Gender.valueOf(columns[3]); + this.kindOfSport = KindOfSport.valueOf(columns[4]); + this.key = encode(this); + } + + /** + * Member constructor. + * + * @param name The name. + * @param firstname The firstname. + * @param date The date. + * @param gender The gender. + * @param kindOfSport The associated kind of sport. + */ + public Member(String name, + String firstname, + LocalDate date, + Gender gender, + KindOfSport kindOfSport) { + this.name = name; + this.firstname = firstname; + this.date = date; + this.gender = gender; + this.kindOfSport = kindOfSport; + this.key = encode(this); + } + + /** + * Generate a unique key from a member's attributes. + * + * @param member A member. + * @return A key. + */ + private static Long encode(Member member) { + String nameKeyPart = encodeLetters(member.name.substring(0, 1)); + String surnameKeyPart = encodeLetters(member.firstname.substring(0, 1)); + String dateKeyPart = encodeDate(member.date); + String key = nameKeyPart + surnameKeyPart + dateKeyPart; + return Long.valueOf(key); + } + + /** + * Format the given date as part of a key. + * + * @param date A LocalDate. + * @return A String ttmmjjjj. + */ + private static String encodeDate(LocalDate date) { + return String.format("%02d%02d%02d", // 2 digits, left pad + date.getDayOfMonth(), + date.getMonthValue(), + date.getYear()); + } + + /** + * Map each letter in the given string to a value + * between '01' and '26'. + * + * @param string A string containing only letters. + * @return A string of zero padded digits. + */ + private static String encodeLetters(String string) { + String encodedString = ""; + + for (char letter : sanitizeLetters(string).toCharArray()) { + int letterIndex = letter - 'a' + 1; + + if (letterIndex < 1 || letterIndex > 26) { + throw new IllegalArgumentException( + letter + " cannot be encoded!"); + } + + encodedString += String.format("%02d", letterIndex); + } + + return encodedString; + } + + /** + * Replace ä, ö, ü and lowercase the string. + * + * @param string A string. + * @return A lowercase string without umlauts. + */ + private static String sanitizeLetters(String string) { + return string + .toLowerCase() + .replace("ä", "ae") + .replace("ö", "oe") + .replace("ü", "ue"); + } + + /** + * Return this member as string. + */ + @Override + public String toString() { + return this.key + ", " + + this.name + ", " + + this.firstname + ", " + + this.date + ", " + + this.gender + ", " + + this.kindOfSport; + } + + /** + * Implement the Comparable interface by comparing the keys. + * + * @return @see Comparable + */ + @Override + public int compareTo(IMember member) { + return Long.compare(this.key, member.getKey()); + } + + @Override + public String getName() { + return this.name; + } + + @Override + public Gender getGender() { + return this.gender; + } + + @Override + public LocalDate getDate() { + return this.date; + } + + @Override + public String getFirstName() { + return this.firstname; + } + + @Override + public long getKey() { + return this.key; + } + + @Override + public KindOfSport getKindOfSport() { + return this.kindOfSport; + } +} diff --git a/src/de/ostfalia/algo/ws18/s1/LinkedListNode.java b/src/de/ostfalia/algo/ws18/s1/LinkedListNode.java new file mode 100644 index 0000000..a7cf4f1 --- /dev/null +++ b/src/de/ostfalia/algo/ws18/s1/LinkedListNode.java @@ -0,0 +1,63 @@ +package de.ostfalia.algo.ws18.s1; + +/** + * A generic linked list node. + * + * @param The type of the value this node contains. + */ +public class LinkedListNode { + /** + * This node's value. + */ + private E value; + /** + * The next linked node. + */ + private LinkedListNode next; + + /** + * Create a node with the given value and no next node. + * + * @param value This node's value. + */ + public LinkedListNode(E value) { + this.value = value; + this.next = null; + } + + /** + * Get this node's value. + * + * @return This node's value. + */ + public E getValue() { + return this.value; + } + + /** + * Set this node's value. + * + * @param value The new value. + */ + public void setValue(E value) { + this.value = value; + } + + /** + * Get the next linked node. + * + * @return The next linked node. + */ + public LinkedListNode getNext() { + return this.next; + } + + /** + * Set the next linked node. + * + * @param next + */ + public void setNext(LinkedListNode next) { + this.next = next; + } +} diff --git a/src/de/ostfalia/algo/ws18/s1/Main.java b/src/de/ostfalia/algo/ws18/s1/Main.java new file mode 100644 index 0000000..b55dff5 --- /dev/null +++ b/src/de/ostfalia/algo/ws18/s1/Main.java @@ -0,0 +1,24 @@ +package de.ostfalia.algo.ws18.s1; + +import java.time.LocalDate; + +import de.ostfalia.algo.ws18.base.Gender; +import de.ostfalia.algo.ws18.base.KindOfSport; +import de.ostfalia.algo.ws18.base.Member; + +public class Main { + public static void main(String ...args) { + Management management = new Management(); + management.checkpoint(); + management.insert(new Member("Blümchen", "Benjamin", LocalDate.now(), Gender.M, KindOfSport.TANZEN)); + System.out.println(management.checkpoint()/1000 + " ms für das erste insert"); + management.insert(new Member("Kolumna", "Carla", LocalDate.now(), Gender.F, KindOfSport.RADSPORT)); + System.out.println(management.checkpoint()/1000 + " ms für das zweite insert"); + System.out.println("management hat " + management.size() + " Elemente, eingefügt in " + management.numberOfOperations()); + management.checkpoint(); + System.out.println("Suche Claudia Wexler: " + + management.search("Wexler", "Claudia") + + ", gefunden nach " + management.numberOfOperations() + + " Operationen und " + management.checkpoint()/1000 + " ms"); + } +} diff --git a/src/de/ostfalia/algo/ws18/s1/Management.java b/src/de/ostfalia/algo/ws18/s1/Management.java new file mode 100644 index 0000000..940a0ad --- /dev/null +++ b/src/de/ostfalia/algo/ws18/s1/Management.java @@ -0,0 +1,275 @@ +package de.ostfalia.algo.ws18.s1; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.function.Predicate; + +import de.ostfalia.algo.ws18.base.IManagement; +import de.ostfalia.algo.ws18.base.IMember; +import de.ostfalia.algo.ws18.base.KindOfSport; +import de.ostfalia.algo.ws18.base.Member; + +public class Management implements IManagement { + /** + * Track the number of operations. + */ + protected int numberOfOperations; + + /** + * Track the execution time. + */ + private long lastCheckpointNs; + + /** + * Current head node. + */ + protected LinkedListNode head; + /** + * Length of the list. + */ + protected int size = 0; + /** + * Whether the list is reversed, i. e. the head is the tail. + */ + private boolean reversed = false; + + /** + * Empty constructor. + */ + public Management() { + } + + /** + * Insert from an array of strings. + * + * @param membersCsv Array of CSV rows. + */ + public Management(String[] membersCsv) { + for (String memberCsv : membersCsv) { + this.insert(new Member(memberCsv)); + } + } + + /** + * Read from the CSV file and insert. + * + * @param filename Path to the CSV file. + */ + public Management(String filename) { + this.importFromFile(filename); + } + + /** + * Read from the CSV file and insert. + * + * @param filename Path to the CSV file. + */ + public void importFromFile(String filename) { + File file = new File(filename); + + try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) { + bufferedReader.lines().forEach(line -> insert(new Member(line))); + } catch (IOException exception) { + throw new IllegalArgumentException(exception); + } + } + + /** + * Create a filtered version of this list. + * + * @param criteria Criteria to filter for. + * @param breakAfterFirstMatch If true, return after the first match. + * @return A new list where all elements meet the given criteria. + */ + protected Management filter(Predicate criteria, boolean breakAfterFirstMatch) { + Management result = new Management(); + if (this.size == 0) { + return result; + } + + // searches from head, inserts at head -> result is reversed + result.reverse(); + + LinkedListNode currentNode = this.head; + do { + IMember currentValue = currentNode.getValue(); + this.numberOfOperations++; + if (criteria.test(currentValue)) { + result.insert(currentValue); + if (breakAfterFirstMatch) { + break; + } + } + } while ((currentNode = currentNode.getNext()) != null); + + return result; + } + + /** + * Find the first element that matches the given criteria. + * + * @param criteria Criteria to search for. + * @return The first element that matches the given criteria or null. + */ + protected LinkedListNode search(Predicate criteria) { + Management filteredList = this.filter(criteria, true); + if (filteredList.size() == 0) { + return null; + } else { + return filteredList.head; + } + } + + /** + * Count the number of elements that match the given criteria. + * + * @param criteria Criteria to filter for. + * @return The number of elements that match the given criteria. + */ + private long size(Predicate criteria) { + return this.filter(criteria, false).size; + } + + /** + * Reverse the order of the list. + */ + public void reverse() { + this.reversed = !this.reversed; + } + + /** + * @return The length of this list. + */ + @Override + public int size() { + return this.size; + } + + /** + * Add an element at the start of the list. + * Replace the current head with a new node and link this node to the old head. + * + * @return TODO? + */ + @Override + public boolean insert(IMember value) { + LinkedListNode newHead = new LinkedListNode(value); + this.numberOfOperations++; + if (this.head != null) { + newHead.setNext(this.head); + } + this.head = newHead; + + this.size++; + return true; // TODO? + } + + /** + * Find the first member with the given key. + * + * @param key The key to search for. + * @return The member or null. + */ + @Override + public IMember search(long key) { + LinkedListNode result = this.search(member -> member.getKey() == key); + if (result != null) { + return result.getValue(); + } else { + return null; + } + } + + /** + * Find the first member with the given name. + * + * @param name The name of the member. + * @param firstName first name of the member. + * @return The member or null. + */ + @Override + public IMember search(String name, String firstName) { + LinkedListNode result = this.search(member -> member.getName().equals(name) + && member.getFirstName().equals(firstName)); + if (result != null) { + return result.getValue(); + } else { + return null; + } + } + + /** + * Count the number of members which have an association to the given kindOfSport. + * + * @param kindOfSport The kindOfSport of the members. + * @return The number of members with the given kindOfSport. + */ + @Override + public int size(KindOfSport kindOfSport) { + this.numberOfOperations = 0; + return (int) this.size(member -> member.getKindOfSport().equals(kindOfSport)); + } + + /** + * Return the members which have an association to the given kindOfSport. + * + * @param kindOfSport The kindOfSport of the members. + * @return An array of the members with the given kindOfSport. + */ + @Override + public IMember[] discipline(KindOfSport kindOfSport) { + return this.filter(member -> member.getKindOfSport().equals(kindOfSport), false) + .toArray(); + } + + /** + * Convert the list to an array. + * + * @return The elements of this list as array. + */ + @Override + public IMember[] toArray() { + IMember[] array = new IMember[this.size]; + if (this.size() == 0) { + return array; + } + + LinkedListNode currentNode = this.head; + + for (int index = 0; index < this.size; index++) { + if (reversed) { + array[this.size - index - 1] = currentNode.getValue(); + } else { + array[index] = currentNode.getValue(); + } + currentNode = currentNode.getNext(); + } + + return array; + } + + /** + * TODO + * + * @return The number of operations recorded since the last call. + */ + @Override + public int numberOfOperations() { + int numberOfOperations = this.numberOfOperations; + this.numberOfOperations = 0; + return numberOfOperations; + } + + /** + * Reset the timer and get the time difference in ns. + * + * @return Nanoseconds since the last call. + */ + public long checkpoint() { + long nanoseconds = this.lastCheckpointNs; + this.lastCheckpointNs = System.nanoTime(); + return this.lastCheckpointNs - nanoseconds; + } +} diff --git a/src/de/ostfalia/algo/ws18/s1/test/LageTestS1.java b/src/de/ostfalia/algo/ws18/s1/test/LageTestS1.java new file mode 100644 index 0000000..63078cc --- /dev/null +++ b/src/de/ostfalia/algo/ws18/s1/test/LageTestS1.java @@ -0,0 +1,365 @@ +package de.ostfalia.algo.ws18.s1.test; + +import static org.junit.Assert.assertFalse; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.RuleChain; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; + +import de.ostfalia.algo.ws18.base.IManagement; +import de.ostfalia.algo.ws18.base.IMember; +import de.ostfalia.algo.ws18.base.KindOfSport; +import de.ostfalia.algo.ws18.base.Member; +import de.ostfalia.algo.ws18.s1.Management; +import de.ostfalia.junit.annotations.AfterMethod; +import de.ostfalia.junit.annotations.TestDescription; +import de.ostfalia.junit.base.IMessengerRules; +import de.ostfalia.junit.base.ITraceRules; +import de.ostfalia.junit.conditional.Natural; +import de.ostfalia.junit.conditional.PassTrace; +import de.ostfalia.junit.rules.MessengerRule; +import de.ostfalia.junit.rules.RuleControl; +import de.ostfalia.junit.rules.TraceRule; +import de.ostfalia.junit.runner.TopologicalSortRunner; + +@RunWith(TopologicalSortRunner.class) +public class LageTestS1 { + + public boolean evalOperations = true; + public RuleControl opt = RuleControl.NONE; + public IMessengerRules messenger = MessengerRule.newInstance(opt); + public ITraceRules trace = TraceRule.newInstance(opt); + + + @Rule + public TestRule chain = RuleChain + .outerRule(trace) + .around(messenger); + + private int fileLength = 10000; + /** + * Datei mit 10000 Datensaetze fuer die JUnit-Tests. + */ + public String fileName = "Materialien/Mitglieder10000.txt"; + + private FileReader fileReader; + private BufferedReader bufferedReader; + + @Before + public void setUp() throws Exception { + fileReader = new FileReader(new File(fileName)); + bufferedReader = new BufferedReader(fileReader); + } + + @After + public void after() throws Exception { + if (bufferedReader != null) bufferedReader.close(); + if (fileReader != null) fileReader.close(); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String) und anschliessendes + * Ueberpruefen der Anzahl der gespeicherten Eintraege in der + * Mitgliederverwaltung. + * Die verwendete Datensatzdatei enthaelt 10000 Eintraege.
  • + *
  • Erwartet: + *
      + *
    • Anzahl Eintraege in der Mitgliederverwaltung: 10000.
    • + *
    • toArray() liefert ein Array der Groesse 10000.
    • + *
    • Anzahl Operationen: 10000 ± 1000.
    • + *
    + *
  • + *
+ * @throws IOException + * wird ausgeloest, wenn ein E/A-Fehler auftritt, also das Lesen aus + * der Datensatzdatei fehlschlaegt. + */ + @Test + @TestDescription("Testen des Kontruktors(String).") + public void testKonstruktorString() throws IOException { + trace.add("Konstruktoraufruf Management(\"%s\")", fileName); + IManagement mgnt = new Management(fileName); + int count = mgnt.numberOfOperations(); + trace.add("Aufruf der Methode toArray()."); + IMember[] members = mgnt.toArray(); + + evaluate(members, mgnt.size(), fileLength); + evaluate(members, fileLength); + evaluate(count, 10000, 1000); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management() und anschliessendes Einfuegen + * von 10000 Datensaetze in die Mitgliederverwaltung. + * Die 10000 Datensaetze werden durch Aufruf der Methode insert(IMember) + * einzeln in die Mitgliederverwaltung eingefuegt.
  • + *
  • Erwartet: + *
      + *
    • Anzahl Eintraege in der Mitgliederverwaltung: 10000.
    • + *
    • toArray() liefert ein Array der Groesse 10000.
    • + *
    • Anzahl Operationen: 10000 ± 1000.
    • + *
    + *
  • + *
+ * @throws IOException + * wird ausgeloest, wenn ein E/A-Fehler auftritt, also das Lesen aus + * der Datensatzdatei fehlschlaegt. + */ + @Test + @AfterMethod ("testKonstruktorString") + @TestDescription("Testen der Insert-Methode.") + public void testEinfuegen() throws IOException { + trace.add("Konstruktoraufruf Management()"); + IManagement mgnt = new Management(); + trace.add("Aufruf der Methode toArray()."); + IMember[] members = mgnt.toArray(); + + evaluate(members, mgnt.size(), 0); + + trace.add("Einfuegen der Datensaetze in die Mitgliederverwaltung."); + String line; + int count = 0; + while ((line = bufferedReader.readLine()) != null) { + trace.addInfo(PassTrace.ifTrue("Einfuegen von Datensatz \"%s\".", + mgnt.insert(new Member(line)), line)); + count += mgnt.numberOfOperations(); + } + assertFalse("Datensatz/-saetze konnten nicht eingefügt werden.", + trace.hasOccurrences()); + trace.add("Aufruf der Methode toArray() nach dem Einfuegen."); + members = mgnt.toArray(); + + evaluate(members, mgnt.size(), fileLength); + evaluate(members, fileLength); + evaluate(count, 10000, 1000); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String) und anschliessendes + * Suchen nach allen Schluesselwerten in der Mitgliederverwaltung. + * Die Datensatzdatei enthaelt 10000 Eintraege.
  • + *
  • Erwartet: + *
      + *
    • Anzahl Eintraege in der Mitgliederverwaltung: 10000.
    • + *
    • Alle Schluesselwerte muessen in der Mitgliederverwaltung + * gefunden werden.
    • + *
    • Gesamtanzahl Operationen beim Suchen aller 10000 Eintraege: + * 50005000 ± 10000.
    • + *
    + *
  • + *
+ * @throws IOException + * wird ausgeloest, wenn ein E/A-Fehler auftritt, also das Lesen aus + * der Datensatzdatei fehlschlaegt. + */ + @Test + @AfterMethod("testKonstruktorString") + @TestDescription("Testen der search(long)-Methode.") + public void testSuchen() throws IOException { + trace.add("Konstruktoraufruf Management(%s)", fileName); + IManagement mgnt = new Management(fileName); + trace.add("Aufruf der Methode toArray()."); + IMember[] members = mgnt.toArray(); + + evaluate(members, mgnt.size(), fileLength); + + trace.add("Suchen nach Datensaetze in die Mitgliederverwaltung."); + String line; + int count = 0; + while ((line = bufferedReader.readLine()) != null) { + IMember exp = new Member(line); + IMember got = mgnt.search(exp.getKey()); + trace.addInfo(PassTrace.ifEquals("Suchen nach Schluessel \"%d\".", + exp, got, exp.getKey())); + count += mgnt.numberOfOperations(); + } + assertFalse("Fehlerhafte / fehlende Datensaetze in der Mitgliederverwaltung.", + trace.hasOccurrences()); + evaluate(count, 50005000, fileLength); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String) und anschliessendes + * Ueberpruefen der Anzahl der Eintraege der Sportarten in der + * Mitgliederverwaltung. + * Die Datensatzdatei enthaelt 10000 Eintraege.
  • + *
  • Erwartete:
    + * Methode size(KindOfSport) muss folgende Werte liefern: + *
      + *
    • FUSSBALL: 985.
    • + *
    • HANDBALL: 989.
    • + *
    • SCHWIMMEN: 1037.
    • + *
    • LEICHTATHLETIK: 973.
    • + *
    • REITEN: 1000.
    • + *
    • FECHTEN: 985.
    • + *
    • TURNEN: 1033.
    • + *
    • RADSPORT: 996.
    • + *
    • TANZEN: 992.
    • + *
    • RUDERN: 1010.
    • + *
    + *
  • + *
  • Erwartete Gesamtanzahl Operationen beim Suchen aller 10000 Eintraege: + * 100000 ± 10000. + *
  • + *
+ * @throws IOException + * wird ausgeloest, wenn ein E/A-Fehler auftritt, also das Lesen aus + * der Datensatzdatei fehlschlaegt. + */ + @Test + @AfterMethod("testKonstruktorString") + @TestDescription("Testen der size(KindOfSport)-Methode.") + public void testTraversieren() throws IOException { + final int[] exp = {985, 989, 1037, 973, 1000, 985, 1033, 996, 992, 1010}; + + trace.add("Konstruktoraufruf Management(%s)", fileName); + IManagement mgnt = new Management(fileName); + + String msg = "Falsche Anzahl der Mitglieder fuer die Sportarten %s erhalten."; + int index = 0, count = 0; + for (KindOfSport sport : KindOfSport.values()) { + trace.add("Aufruf von size(%s).", sport); + trace.addInfo(PassTrace.ifEquals(msg, exp[index++], mgnt.size(sport), sport)); + count += mgnt.numberOfOperations(); + } + assertFalse("Methode size(KindOfSport) liefert falsches Ergebnis.", + trace.hasOccurrences()); + evaluate(count, 10 * 10000, 10000); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String) und anschliessendes + * Ueberpruefen der Eintraege der 10 Sportarten in der Mitgliederverwaltung. + * Mit Hilfe einer Pruefsumme wird festgestellt, ob die Eintraege + * korrekt sind. Die Datensatzdatei enthaelt 10000 Eintraege.
  • + *
  • Erwartete:
    + * Methode discipline(KindOfSport) muss folgende Werte liefern: + *
      + *
    • FUSSBALL: 985 Eintraege (Pruefsumme: 225236503928).
    • + *
    • HANDBALL: 989 Eintraege (Pruefsumme: 173758233713).
    • + *
    • SCHWIMMEN: 1037 Eintraege (Pruefsumme: 183013252630).
    • + *
    • LEICHTATHLETIK: 973 Eintraege (Pruefsumme: 161145468810).
    • + *
    • REITEN: 1000 Eintraege (Pruefsumme: 152686351492).
    • + *
    • FECHTEN: 985 Eintraege (Pruefsumme: 257673959686).
    • + *
    • TURNEN: 1033 Eintraege (Pruefsumme: 90525160369).
    • + *
    • RADSPORT: 996 Eintraege (Pruefsumme: 266557207632).
    • + *
    • TANZEN: 992 Eintraege (Pruefsumme: 74094229376).
    • + *
    • RUDERN: 1010 Eintraege (Pruefsumme: 58704317911).
    • + *
    + *
  • + *
+ * @throws IOException + * wird ausgeloest, wenn ein E/A-Fehler auftritt, also das Lesen aus + * der Datensatzdatei fehlschlaegt. + */ + @Test + @AfterMethod("testKonstruktorString") + @TestDescription("Testen der discipline(KindOfSport)-Methode.") + public void testTraversieren2() throws IOException { + final int[] exp = {985, 989, 1037, 973, 1000, 985, 1033, 996, 992, 1010}; + final long[] chk = {225236503928L, 173758233713L, 183013252630L, 161145468810L, + 152686351492L, 257673959686L, 90525160369L, 266557207632L, + 74094229376L, 58704317911L}; + + trace.add("Konstruktoraufruf Management(%s)", fileName); + IManagement mgnt = new Management(fileName); + + String msg = "Anzahl der Mitglieder fuer die Sportarten %s."; + int index = 0; + for (KindOfSport sport : KindOfSport.values()) { + trace.add("Aufruf von discipline(%s).", sport); + IMember[] got = mgnt.discipline(sport); + trace.addInfo(PassTrace.ifEquals(msg, exp[index], got.length, sport)); + trace.add("Alle Eintraege muessen der Sportart %s entprechen.", sport); + int idx = 0; + long chkSum = 0; + for (IMember member : got) { + trace.addInfo(PassTrace.ifEquals("[%d] Unerwartete Sportart %s.", + sport, member.getKindOfSport(), idx++, sport)); + chkSum ^= member.getKey(); + } + trace.add("Pruefsumme fuer die Sportart %s.", sport); + trace.addInfo(PassTrace.ifEquals("Unerwartete Pruefsumme.", chk[index], chkSum)); + index++; + } + assertFalse("Methode discipline(KindOfSport) liefert falsches Ergebnis.", + trace.hasOccurrences()); + } + + //----------------------------------------------------------------- + + /** + * Ueberpruefung der Anzahl Mitglieder in der Mitgliederverwaltung. + * @param members - Mitglieder in der Mitgliederverwaltung: IMember[]. + * @param size - erhaltene Anzahl der Mitglieder: int. + * @param exp - erwartete Anzahl der Mitglieder: int. + */ + private void evaluate(IMember[] members, int size, int exp) { + trace.add(PassTrace + .ifEquals("Anzahl der Datensaetze muss %d betragen.", exp, size, exp)); + trace.add(PassTrace + .ifEquals("toArray().length muss %d liefern.", exp, members.length, exp)); + assertFalse("Fehlerhafte Anzahl von Datensaetze in der Mitgliederverwaltung.", + trace.hasOccurrences()); + } + + /** + * Ueberpueft die Datensaetze in der Mitgliederverwaltung mit den Datensaetzen + * in der eingelesenen Datei. + * @param members - Mitglieder in der Mitgliederverwaltung: IMember[]. + * @param lines - Anzahl Zeilen (Datensaetze) in der eingelesenen Datei: int. + * @throws IOException + */ + private void evaluate(IMember[] members, int lines) throws IOException { + int index = lines; + String line; + FileReader fr = new FileReader(new File(fileName)); + BufferedReader br = new BufferedReader(fr); + while ((line = bufferedReader.readLine()) != null) { + IMember member = new Member(line); + trace.addInfo(PassTrace.ifEquals("Ungueltiger Datensatz [%d], Dateizeile %d", + member, members[--index], index, lines - index)); + } + fr.close(); + br.close(); + int errors = trace.getOccurrences(); + assertFalse(errors + " fehlerhafte Datensaetze in der Mitgliederverwaltung.", + trace.hasOccurrences()); + } + + /** + * Ueberpruefung der Anzahl der Operationen. + * @param count - erhaltene Anzahl der Operationen: int. + * @param exp - erwartete Anzahl der Operationen: int. + * @param range - gueltiger Bereich um den erwarteten Wert: int. + */ + private void evaluate(int count, int exp, int range) { + if (evalOperations) { + int min = exp - range; + int max = exp + range; + Natural got = Natural.format(count); + trace.add(PassTrace.ifTrue( + "Anzahl Operationen muss im Bereich %d..%d liegen. Erhalten %d.", + got.rangeOf(min, max), min, max, count) + ); + assertFalse("Fehlerhafte Anzahl Operationen.", trace.hasOccurrences()); + } else { + System.err.println("Evaluate Operations disabled!"); + } + } + +} diff --git a/src/de/ostfalia/algo/ws18/s1/test/ManagementTestS1.java b/src/de/ostfalia/algo/ws18/s1/test/ManagementTestS1.java new file mode 100644 index 0000000..e9eb46e --- /dev/null +++ b/src/de/ostfalia/algo/ws18/s1/test/ManagementTestS1.java @@ -0,0 +1,397 @@ +package de.ostfalia.algo.ws18.s1.test; + +import static org.junit.Assert.assertFalse; + +import java.util.Arrays; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.RuleChain; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; + +import de.ostfalia.algo.ws18.base.IManagement; +import de.ostfalia.algo.ws18.base.IMember; +import de.ostfalia.algo.ws18.base.KindOfSport; +import de.ostfalia.algo.ws18.base.Member; +import de.ostfalia.algo.ws18.s1.Management; +import de.ostfalia.junit.annotations.AfterMethod; +import de.ostfalia.junit.annotations.TestDescription; +import de.ostfalia.junit.base.IMessengerRules; +import de.ostfalia.junit.base.ITraceRules; +import de.ostfalia.junit.conditional.PassTrace; +import de.ostfalia.junit.rules.MessengerRule; +import de.ostfalia.junit.rules.RuleControl; +import de.ostfalia.junit.rules.TraceRule; +import de.ostfalia.junit.runner.TopologicalSortRunner; + +@RunWith(TopologicalSortRunner.class) +public class ManagementTestS1 { + + public RuleControl opt = RuleControl.NONE; + public IMessengerRules messenger = MessengerRule.newInstance(opt); + public ITraceRules trace = TraceRule.newInstance(opt); + + + @Rule + public TestRule chain = RuleChain + .outerRule(trace) + .around(messenger); + + /** + * Datensatz mit 10 Eintraegen als Testdaten fuer die JUnit-Tests. + */ + public String[] data10 = {"Hueber, Uta, 1922-10-15, F, HANDBALL", //[0] + "Muller, Ursula, 1964-01-28, F, HANDBALL", //[1] + "Fried, Heike, 1997-12-14, F, RUDERN", //[2] + "Meyer, Tanja, 1946-04-16, F, HANDBALL", //[3] + "Brauer, Mandy, 1933-07-21, F, FUSSBALL", //[4] + "Weiss, Ulrich, 1987-06-09, M, FUSSBALL", //[5] + "Bohm, Stephanie, 1931-10-22, F, HANDBALL", //[6] + "Huber, Annett, 1936-11-19, F, RUDERN", //[7] + "Hertz, Thomas, 1946-10-01, M, HANDBALL", //[8] + "Scholz, Anja, 1933-01-12, F, RUDERN"}; //[9] + + /** + * Schluesselwerte fuer den Datensatz data (10 Eintraege). + */ + public long[] keys10 = {82115101922L, 132128011964L, 60814121997L, 132016041946L, + 21321071933L, 232109061987L, 21922101931L, 80119111936L, + 82001101946L, 190112011933L}; + + int[] all = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; + int[] ofs = {-1, +1}; + + @Before + public void setUp() throws Exception { + } + + /** + *
    + *
  • Testfall: Standard-Konstruktoraufruf Management().
    + * Nach Aufruf des Standard-Konstruktors duerfen sich keine Datensaetze + * in der Mitgliederverwaltung befinden.
  • + *
  • Erwartet: Anzahl der Datensaetze = 0.
  • + *
+ */ + @Test (timeout = 1000) + @TestDescription("Testen des Kontruktors().") + public void testKonstruktorOhneParameter() { + trace.add("Konstruktoraufruf Management()"); + IManagement mgnt = new Management(); + evaluate(mgnt); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String[]) mit einem Datensatz.
    + * Nach Aufruf Konstruktors muss sich genau ein Datensatz (data10[0]) + * in der Mitgliederverwaltung befinden.
  • + *
  • Erwartet: data10[0] in der Mitgliederverwaltung.
  • + *
+ */ + @Test (timeout = 1000) + @AfterMethod("testKonstruktorOhneParameter") + @TestDescription("Testen des Kontruktors(String[]) mit einem Datensatz.") + public void testKonstruktorEinDatensatz() { + trace.add("Konstruktoraufruf Management(String[])"); + IManagement mgnt = new Management(Arrays.copyOf(data10, 1)); + evaluate(mgnt, 0); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String[]) mit 10 Datensaetzen.
    + * Nach Aufruf Konstruktors mussen sich alle 10 Datensaetze in der + * Mitgliederverwaltung befinden.
  • + *
  • Erwartet: data10[0] bis data10[9] in der Mitgliederverwaltung.
  • + *
+ */ + @Test (timeout = 1000) + @AfterMethod("testKonstruktorEinDatensatz") + @TestDescription("Testen des Kontruktors(String[]) mit 10 Datensaetzen.") + public void testKonstruktorZehnDatensaetze() { + trace.add("Konstruktoraufruf Management(String[])"); + IManagement mgnt = new Management(data10); + evaluate(mgnt, all); + } + + /** + *
    + *
  • Testfall: Standard-Konstruktoraufruf Management() und anschliessendes + * Einfuegen von 10 Datensaetzen.
    + * Alle Datensaetze muessen in die Mitgliederverwaltung eingefuegt + * werden koennen.
  • + *
  • Erwartet: data10[0] bis data10[9] in der Mitgliederverwaltung.
  • + *
+ */ + @Test (timeout = 1000) + @AfterMethod("testKonstruktorZehnDatensaetze") + @TestDescription("Testen der insert(IMember)-Methode mit 10 Datensaetzen.") + public void testInsert() { + trace.add("Konstruktoraufruf Management()"); + IManagement mgnt = new Management(); + evaluate(mgnt); + + String msg = "Falscher Rueckgabe beim Einfuegen errhalten."; + for (int i = 0; i < data10.length; i++) { + trace.add("Datensatz \"%s\" hinzufuegen.", data10[i]); + IMember member = new Member(data10[i]); + trace.addInfo("Aufruf von insert(%s).", member); + trace.addInfo(PassTrace.ifTrue(msg, mgnt.insert(member))); + } + evaluate(mgnt, all); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String[]) mit 10 Datensaetzen + * und anschliessendes Suchen nach den Schuesselwerten in der + * Mitgliederverwaltung.
  • + *
  • Erwartet: Alle Schuesselwerten muessen in der Mitgliederverwaltung + * gefunden werden. Die Methode search(long) muss den zugehoerigen + * Datensatz zurueckliefern.
  • + *
+ */ + @Test (timeout = 1000) + @AfterMethod("testKonstruktorZehnDatensaetze") + @TestDescription("Testen der search(long)-Methode mit 10 Datensaetzen.") + public void testSearchLong() { + trace.add("Konstruktoraufruf Management(String[])"); + IManagement mgnt = new Management(data10); + evaluate(mgnt, all); + + String msg = "Falscher Datensatz bei der Suche nach %d geliefert."; + for (int i = 0; i < data10.length; i++) { + trace.add("Aufruf von search(%d)", keys10[i]); + String exp = concat(i); + IMember got = mgnt.search(keys10[i]); + trace.addInfo(PassTrace.ifEquals(msg, exp, got, keys10[i])); + } + assertFalse("Methode search(long) liefert falschen Datensatz.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String[]) mit 10 Datensaetzen + * und anschliessendes Suchen nach Schuesselwerten, die nicht in der + * Mitgliederverwaltung existieren.
  • + *
  • Erwartet: Kein Schuesselwert darf in der Mitgliederverwaltung + * gefunden werden. Methode search(long) muss null liefern.
  • + *
+ */ + @Test (timeout = 1000) + @AfterMethod("testKonstruktorZehnDatensaetze") + @TestDescription("Methode search(long) muss bei nicht vorhandenen Schluesseln null liefern.") + public void testSearchNotExist() { + trace.add("Konstruktoraufruf Management(String[])"); + IManagement mgnt = new Management(data10); + evaluate(mgnt, all); + + String msg = "Nicht vorhandener Schluessel %d geliefert ungueltigen Datensatz."; + for (int i = 0; i < data10.length; i++) { + for (int j = 0; j < ofs.length; j++) { + long key = keys10[i] + ofs[j]; + trace.add("Aufruf von search(%d)", key); + IMember got = mgnt.search(key); + trace.addInfo(PassTrace.ifEquals(msg, null, got, key)); + } + } + assertFalse("Methode search(long) liefert falschen Datensatz.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String[]) mit 10 Datensaetzen + * und anschliessendes Suchen nach dem Nach- und Vornamen in der + * Mitgliederverwaltung.
  • + *
  • Erwartet: Alle Namen muessen in der Mitgliederverwaltung + * gefunden. Die Methode search(String, String) muss den zugehoerigen + * Datensatz zurueckliefern.
  • + *
+ */ + @Test (timeout = 1000) + @AfterMethod("testKonstruktorZehnDatensaetze") + @TestDescription("Testen der search(String, String)-Methode mit 10 Datensaetzen.") + public void testSearchName() { + trace.add("Konstruktoraufruf Management(String[])"); + IManagement mgnt = new Management(data10); + evaluate(mgnt, all); + + String msg = "Falscher Datensatz bei der Suche nach \"%s, %s\" geliefert."; + for (int i = 0; i < data10.length; i++) { + String[] parts = data10[i].split(","); + trace.add("Aufruf von search(\"%s, %s\")", parts[0], parts[1]); + String exp = concat(i); + IMember got = mgnt.search(parts[0].trim(), parts[1].trim()); + trace.addInfo(PassTrace.ifEquals(msg, exp, got, parts[0], parts[1])); + } + assertFalse("Methode search(String, String) liefert falschen Datensatz.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String[]) mit 10 Datensaetzen + * und anschliessendes Suchen nach dem Nach- und Vornamen in der + * Mitgliederverwaltung, wobei der Nachname nicht exsistiert.
  • + *
  • Erwartet: Kein Namen darf in der Mitgliederverwaltung + * gefunden werden. Die Methode search(String, String) muss null liefern.
  • + *
+ */ + @Test (timeout = 1000) + @AfterMethod("testKonstruktorZehnDatensaetze") + @TestDescription("Methode search(String, String) nuss bei unbekannen Namen null liefern.") + public void testSearchUnknown() { + trace.add("Konstruktoraufruf Management(String[])"); + IManagement mgnt = new Management(data10); + evaluate(mgnt, all); + + String msg = "Ungueltiger Datensatz bei der Suche nach \"%s, %s\" geliefert."; + for (int i = 0; i < data10.length; i++) { + String[] parts = data10[i].split(","); + String unknown = parts[0] + "s"; + trace.add("Aufruf von search(\"%s, %s\")", unknown, parts[1]); + IMember got = mgnt.search(unknown.trim(), parts[1].trim()); + trace.addInfo(PassTrace.ifEquals(msg, null, got, unknown, parts[1])); + } + assertFalse("Methode search(String, String) liefert falschen Datensatz.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String[]) mit 10 Datensaetzen + * und anschliessendes Ermitteln der Anzahl der Eintraege fuer die + * Sportarten HANDBALL, RUDERN, FUSSBALL und REITEN in der + * Mitgliederverwaltung.
  • + *
  • Erwartet: Die Methode size(KindOfSport) muss folgende Werte liefern: + *
      + *
    • HANDBALL: 5
    • + *
    • RUDERN: 3
    • + *
    • FUSSBALL: 2
    • + *
    • REITEN: 0
    • + *
    + *
  • + *
+ */ + @Test (timeout = 1000) + @AfterMethod("testKonstruktorZehnDatensaetze") + @TestDescription("Testen der size(KindOfSport)-Methode mit 10 Datensaetzen.") + public void testSizeKindOfSport() { + trace.add("Konstruktoraufruf Management(String[])"); + IManagement mgnt = new Management(data10); + evaluate(mgnt, all); + + String msg = "Falsche Anzahl der Mitglieder fuer die Sportarten %s erhalten."; + + KindOfSport sport = KindOfSport.HANDBALL; + trace.add("Aufruf von size(%s).", sport); + trace.addInfo(PassTrace.ifEquals(msg, 5, mgnt.size(sport), sport)); + + sport = KindOfSport.RUDERN; + trace.add("Aufruf von size(%s).", sport); + trace.addInfo(PassTrace.ifEquals(msg, 3, mgnt.size(sport), sport)); + + sport = KindOfSport.FUSSBALL; + trace.add("Aufruf von size(%s).", sport); + trace.addInfo(PassTrace.ifEquals(msg, 2, mgnt.size(sport), sport)); + + sport = KindOfSport.REITEN; + trace.add("Aufruf von size(%s).", sport); + trace.addInfo(PassTrace.ifEquals(msg, 0, mgnt.size(sport), sport)); + + assertFalse("Methode size(KindOfSport) liefert falsches Ergebnis.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String[]) mit 10 Datensaetzen + * und anschliessendes Ermitteln der Eintraege fuer die Sportarten + * HANDBALL, RUDERN, FUSSBALL und REITEN in der Mitgliederverwaltung.
  • + *
  • Erwartet:
    + * Die Methode discipline(KindOfSport) muss folgende Datensaetze + * liefern (angegeben ist jeweils der Index im Datensatz data10): + *
      + *
    • HANDBALL: [8], [6], [3], [1], [0]
    • + *
    • RUDERN: [9], [7], [2]
    • + *
    • FUSSBALL: [5], [4]
    • + *
    • REITEN: nicht im Datensatz vorhanden
    • + *
    + *
  • + *
+ */ + @Test (timeout = 1000) + @AfterMethod("testKonstruktorZehnDatensaetze") + public void testDiscipline() { + trace.add("Konstruktoraufruf Management(String[])"); + IManagement mgnt = new Management(data10); + evaluate(mgnt, all); + + KindOfSport sport = KindOfSport.HANDBALL; + trace.add("Aufruf von discipline(%s).", sport); + evaluate(mgnt.discipline(sport), 8, 6, 3, 1, 0); + + sport = KindOfSport.RUDERN; + trace.add("Aufruf von discipline(%s).", sport); + evaluate(mgnt.discipline(sport), 9, 7, 2); + + sport = KindOfSport.FUSSBALL; + trace.add("Aufruf von discipline(%s).", sport); + evaluate(mgnt.discipline(sport), 5, 4); + + sport = KindOfSport.REITEN; + trace.add("Aufruf von discipline(%s).", sport); + evaluate(mgnt.discipline(sport)); + + assertFalse("Methode discipline(KindOfSport) liefert falsches Ergebnis.", + trace.hasOccurrences()); + } + + //----------------------------------------------------------------- + + /** + * Ueberpruefung der durch die Methode toArray() der Mitgilderverwaltung + * zurueckgelieferten Datensaetze. + * @param mgnt - Mitgliederverwaltung: IManagement. + * @param elements - Indizes der erwarteten Testdatensaetze: int... + */ + private void evaluate(IManagement mgnt, int... elements) { + evaluate(mgnt.toArray(), elements); + } + + /** + * Ueberpruefung der uebergebenen Datensaetze anhand der Indizes der + * erwarteten Testdatensaetze. + * @param members - Array mit Datensaetze: IMember[]. + * @param elements - Indizes der erwarteten Testdatensaetze: int... + */ + private void evaluate(IMember[] members, int... elements) { + trace.addInfo(PassTrace.ifEquals("Anzahl der Mitglieder nicht korrekt.", + elements.length, members.length)); + int length = Integer.min(elements.length, members.length); + for (int i = 0; i < length; i++) { + int index = elements[i]; + String exp = concat(index); + trace.addInfo(PassTrace.ifEquals("Fehler im Datensatz %d.", + exp, members[i], i + 1)); + } + assertFalse("Fehlerhafte Datensaetze in der Mitgliederverwaltung.", + trace.hasOccurrences()); + } + + /** + * Zusammenfuegen eines Schluesselwerts mit dem zuhegoerigen Datensatz + * entsprechend ihrem Index in den Testdatensaetzen. + * @param element - Index im Datensatz: int. + * @return Schluesselwert mit dem zuhegoerigen Datensatz: String. + */ + private String concat(int element) { + return keys10[element] + ", " + data10[element]; + } + +} diff --git a/src/de/ostfalia/algo/ws18/s1/test/MemberTest.java b/src/de/ostfalia/algo/ws18/s1/test/MemberTest.java new file mode 100644 index 0000000..bd3ccd2 --- /dev/null +++ b/src/de/ostfalia/algo/ws18/s1/test/MemberTest.java @@ -0,0 +1,260 @@ +package de.ostfalia.algo.ws18.s1.test; + +import static org.junit.Assert.*; + +import java.time.LocalDate; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.RuleChain; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; + +import de.ostfalia.algo.ws18.base.Gender; +import de.ostfalia.algo.ws18.base.IMember; +import de.ostfalia.algo.ws18.base.KindOfSport; +import de.ostfalia.algo.ws18.base.Member; +import de.ostfalia.junit.annotations.TestDescription; +import de.ostfalia.junit.base.IMessengerRules; +import de.ostfalia.junit.base.ITraceRules; +import de.ostfalia.junit.conditional.PassTrace; +import de.ostfalia.junit.rules.MessengerRule; +import de.ostfalia.junit.rules.RuleControl; +import de.ostfalia.junit.rules.TraceRule; +import de.ostfalia.junit.runner.TopologicalSortRunner; + +@RunWith(TopologicalSortRunner.class) +public class MemberTest { + + public RuleControl opt = RuleControl.NONE; + public IMessengerRules messenger = MessengerRule.newInstance(opt); + public ITraceRules trace = TraceRule.newInstance(opt); + + + @Rule + public TestRule chain = RuleChain + .outerRule(trace) + .around(messenger); + + /** + * Datensatz mit 10 Eintraegen als Testdaten fuer die JUnit-Tests. + */ + public String[] data = {"Ackerman, Niklas, 1979-04-08, M, SCHWIMMEN", //[0] + "Bauer, Juliane, 1939-01-16, F, FECHTEN", //[1] + "Kirsch, Antje, 1960-07-13, F, TURNEN", //[2] + "Koertig, Dominik, 1933-09-28, M, HANDBALL", //[3] + "Trommler, Ines, 1924-10-29, F, TURNEN", //[4] + "Hirsch, Manuela, 1948-05-10, F, RUDERN", //[5] + "Schaefer, Stephanie, 1997-05-31, F, FECHTEN", //[6] + "Schultz, Katrin, 1952-08-18, F, REITEN", //[7] + "Fried, Leonie, 1965-09-24, F, TURNEN", //[8] + "Lemann, Philipp, 1936-10-30, M, RADSPORT"}; //[9] + + /** + * Datensatz mit 3 Eintraegen als Testdaten fuer die JUnit-Tests. + */ + public String[] test = {"Ackerman, Niklas, 1979-04-08, M, SCHWIMMEN", + "Acker, Nadine, 1979-04-08, F, HANDBALL", + "Acker, Nadine, 1979-04-10, F, HANDBALL"}; + + /** + * Schluesselwerte fuer den Datensatz data (10 Eintraege). + */ + public long[] keys = {11408041979L, 21016011939L, 110113071960L, 110428091933L, + 200929101924L, 81310051948L, 191931051997L, 191118081952L, + 61224091965L, 121630101936L}; + + @Before + public void setUp() throws Exception { + } + + /** + *
    + *
  • Testfall: toString()-Methode der Klasse Member.
    + * Es werden alle 10 Datensaetze nacheinander druchlaufen.
  • + *
  • Erwartet: Rueckgabe aller Attribute inkl. des berechneten Schluessels als String.
  • + *
  • Beispiel fuer data[0]: 11408041979, Ackerman, Niklas, 1979-04-08, M, SCHWIMMEN.
  • + *
+ */ + @Test (timeout = 1000) + @TestDescription("Testen der toString()-Methode.") + public void testToString() { + for (int i = 0; i < keys.length; i++) { + trace.add("Konstruktoraufruf Member(%s)", data[i]); + IMember member = new Member(data[i]); + String exp = keys[i] + ", " + data[i]; + String got = member.toString(); + trace.addInfo(PassTrace.ifEquals("Fehler im Datensatz %d", + exp, got, i + 1)); + } + assertFalse("Fehler bei der Implementierung toString()-Methode.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: getKey()-Methode der Klasse Member.
  • + *
  • Erwartet: Rueckgabe des Schluessels als Long-Wert.
  • + *
  • Beispiel fuer data[0]: 11408041979.
  • + *
+ */ + @Test (timeout = 1000) + @TestDescription("Testen der getKey()-Methode.") + public void testGetKey() { + for (int i = 0; i < keys.length; i++) { + trace.add("Konstruktoraufruf Member(%s)", data[i]); + IMember member = new Member(data[i]); + Long exp = keys[i]; + Long got = member.getKey(); + trace.addInfo(PassTrace.ifEquals("Fehlerhafter Schuessel im Datensatz %d", + exp, got, i + 1)); + } + assertFalse("Fehler bei der Rueckgabe des Schluesselwertes.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: getName()-Methode der Klasse Member.
  • + *
  • Erwartet: Rueckgabe des Nachnamens als String.
  • + *
  • Beispiel fuer data[0]: Ackerman.
  • + *
+ */ + @Test (timeout = 1000) + @TestDescription("Testen der getName()-Methode.") + public void testGetName() { + for (int i = 0; i < keys.length; i++) { + trace.add("Konstruktoraufruf Member(%s)", data[i]); + IMember member = new Member(data[i]); + String exp = data[i].split(",")[0]; + String got = member.getName(); + trace.addInfo(PassTrace.ifEquals("Fehlerhafter Nachname im Datensatz %d", + exp, got, i + 1)); + } + assertFalse("Fehler bei der Rueckgabe des Nachnamens.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: getFirstName()-Methode der Klasse Member.
  • + *
  • Erwartet: Rueckgabe des Vornamens als String.
  • + *
  • Beispiel fuer data[0]: Niklas.
  • + *
+ */ + @Test (timeout = 1000) + @TestDescription("Testen der getFirstName()-Methode.") + public void testGetFirstName() { + for (int i = 0; i < keys.length; i++) { + trace.add("Konstruktoraufruf Member(%s)", data[i]); + IMember member = new Member(data[i]); + String exp = data[i].split(",")[1]; + String got = member.getFirstName(); + trace.addInfo(PassTrace.ifEquals("Fehlerhafter Vornamen im Datensatz %d", + exp, got, i + 1)); + } + assertFalse("Fehler bei der Rueckgabe des Vornamens.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: getDate()-Methode der Klasse Member.
  • + *
  • Erwartet: Rueckgabe des Geburtsdatum als LocalDate.
  • + *
  • Beispiel fuer data[0]: 1979-04-08.
  • + *
+ */ + @Test (timeout = 1000) + @TestDescription("Testen der geDate()-Methode.") + public void testGetDate() { + for (int i = 0; i < keys.length; i++) { + trace.add("Konstruktoraufruf Member(%s)", data[i]); + IMember member = new Member(data[i]); + String exp = data[i].split(",")[2]; + LocalDate got = member.getDate(); + trace.addInfo(PassTrace.ifEquals("Fehlerhaftes Geburtsdatum im Datensatz %d", + exp, got, i + 1)); + } + assertFalse("Fehler bei der Rueckgabe des Geburtsdatums.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: getGender()-Methode der Klasse Member.
  • + *
  • Erwartet: Rueckgabe des Geschlechts als enum Gender.
  • + *
  • Beispiel fuer data[0]: M.
  • + *
+ */ + @Test (timeout = 1000) + @TestDescription("Testen der getGender()-Methode.") + public void testGender() { + for (int i = 0; i < keys.length; i++) { + trace.add("Konstruktoraufruf Member(%s)", data[i]); + IMember member = new Member(data[i]); + String exp = data[i].split(",")[3]; + Gender got = member.getGender(); + trace.addInfo(PassTrace.ifEquals("Fehlerhaftes Geschlecht im Datensatz %d", + exp, got, i + 1)); + } + assertFalse("Fehler bei der Rueckgabe des Geschlechts.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: getKindOfSport()-Methode der Klasse Member.
  • + *
  • Erwartet: Rueckgabe der Sportart als enum KindOfSport.
  • + *
  • Beispiel fuer data[0]: SCHWIMMEN.
  • + *
+ */ + @Test (timeout = 1000) + @TestDescription("Testen der getKindOfSport()-Methode.") + public void testGetKindOfSport() { + for (int i = 0; i < keys.length; i++) { + trace.add("Konstruktoraufruf Member(%s)", data[i]); + IMember member = new Member(data[i]); + String exp = data[i].split(",")[4]; + KindOfSport got = member.getKindOfSport(); + trace.addInfo(PassTrace.ifEquals("Fehlerhafte Sportart im Datensatz %d", + exp, got, i + 1)); + } + assertFalse("Fehler bei der Rueckgabe der Sportart.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: equals()-Methode der Klasse Member.
  • + *
  • Erwartet: true, wenn die Member inhaltlich gleich sind, sonst false.
  • + *
+ */ + @Ignore + @Test (timeout = 1000) + @TestDescription("Testen der equals()-Methode.") + public void testEqualsObject() { + trace.add("Konstruktoraufruf Member(%s) fuer Mitglied %d", data[0], 1); + IMember member1 = new Member(test[0]); + trace.add("Konstruktoraufruf Member(%s) fuer Mitglied %d", data[0], 2); + IMember duplikat = new Member(test[0]); + trace.add("Konstruktoraufruf Member(%s) fuer Mitglied %d", data[1], 3); + IMember member2 = new Member(test[1]); + trace.add("Konstruktoraufruf Member(%s) fuer Mitglied %d", data[1], 4); + IMember member3 = new Member(test[2]); + + trace.addInfo(PassTrace.ifTrue("[%s] gleich [%s]?", + member1.equals(duplikat), member1, duplikat)); + trace.addInfo(PassTrace.ifTrue("[%s] gleich [%s]", + member1.equals(member2), member1, member2)); + trace.addInfo(PassTrace.ifFalse("[%s] gleich [%s]", + member1.equals(member3), member1, member3)); + trace.addInfo(PassTrace.ifFalse("[%s] gleich [%s]", + member2.equals(member3), member2, member3)); + + assertFalse("equals()-Methode fehlerhaft implementiert.", + trace.hasOccurrences()); + } + +} diff --git a/src/de/ostfalia/algo/ws18/s2/Management.java b/src/de/ostfalia/algo/ws18/s2/Management.java new file mode 100644 index 0000000..c88c13b --- /dev/null +++ b/src/de/ostfalia/algo/ws18/s2/Management.java @@ -0,0 +1,84 @@ +package de.ostfalia.algo.ws18.s2; + +import de.ostfalia.algo.ws18.base.IManagement; +import de.ostfalia.algo.ws18.base.IMember; +import de.ostfalia.algo.ws18.s1.LinkedListNode; + +public class Management extends de.ostfalia.algo.ws18.s1.Management implements IManagement { + public Management() { + super(); + } + + public Management(String csvMembers[]) { + super(csvMembers); + } + + public Management(String filename) { + super(filename); + } + + /** + * Add an element at TODO. + * + * @return true + */ + @Override + public boolean insert(IMember value) { + this.size++; + + LinkedListNode newNode = new LinkedListNode(value); + + if (this.head == null) { + this.head = newNode; + return true; + } + + this.numberOfOperations++; + if (newNode.getValue().getKey() < head.getValue().getKey()) { + newNode.setNext(this.head); + this.head = newNode; + return true; // added at the head + } + + LinkedListNode currentNode = this.head; + while (currentNode.getNext() != null) { + this.numberOfOperations++; + if (newNode.getValue().getKey() < currentNode.getNext().getValue().getKey()) { + newNode.setNext(currentNode.getNext()); + currentNode.setNext(newNode); + return true; // added in between + } + + currentNode = currentNode.getNext(); + } + + currentNode.setNext(newNode); + return true; // added at the tail + } + + @Override + public IMember search(long key) { + this.numberOfOperations = 0; + + if (this.size == 0) { + return null; // won't find + } + + LinkedListNode currentNode = this.head; + do { + this.numberOfOperations++; + long currentKey = currentNode.getValue().getKey(); + if (currentKey == key) { + return currentNode.getValue(); // found + } + if (currentKey > key) { + return null; // won't find + } + + currentNode = currentNode.getNext(); + } while (currentNode != null); + + return null; // not found + } + +} diff --git a/src/de/ostfalia/algo/ws18/s2/test/LageTestS2.java b/src/de/ostfalia/algo/ws18/s2/test/LageTestS2.java new file mode 100644 index 0000000..8a323ff --- /dev/null +++ b/src/de/ostfalia/algo/ws18/s2/test/LageTestS2.java @@ -0,0 +1,366 @@ +package de.ostfalia.algo.ws18.s2.test; + +import static org.junit.Assert.assertFalse; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.RuleChain; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; + +import de.ostfalia.algo.ws18.base.IManagement; +import de.ostfalia.algo.ws18.base.IMember; +import de.ostfalia.algo.ws18.base.KindOfSport; +import de.ostfalia.algo.ws18.base.Member; +import de.ostfalia.algo.ws18.s2.Management; +import de.ostfalia.junit.annotations.AfterMethod; +import de.ostfalia.junit.annotations.TestDescription; +import de.ostfalia.junit.base.IMessengerRules; +import de.ostfalia.junit.base.ITraceRules; +import de.ostfalia.junit.conditional.Natural; +import de.ostfalia.junit.conditional.PassTrace; +import de.ostfalia.junit.rules.MessengerRule; +import de.ostfalia.junit.rules.RuleControl; +import de.ostfalia.junit.rules.TraceRule; +import de.ostfalia.junit.runner.TopologicalSortRunner; + +@RunWith(TopologicalSortRunner.class) +public class LageTestS2 { + + public boolean evalOperations = true; + public RuleControl opt = RuleControl.NONE; + public IMessengerRules messenger = MessengerRule.newInstance(opt); + public ITraceRules trace = TraceRule.newInstance(opt); + + @Rule + public TestRule chain = RuleChain + .outerRule(trace) + .around(messenger); + + private int fileLength = 10000; + /** + * Datei mit 10000 Datensaetze fuer die JUnit-Tests. + */ + public String fileName = "Materialien/Mitglieder10000.txt"; + public String fileSort = "Materialien/JUnitTestdaten.txt"; + + private FileReader fileReader; + private BufferedReader bufferedReader; + + @Before + public void setUp() throws Exception { + fileReader = new FileReader(new File(fileName)); + bufferedReader = new BufferedReader(fileReader); + } + + @After + public void after() throws Exception { + if (bufferedReader != null) bufferedReader.close(); + if (fileReader != null) fileReader.close(); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String) und anschliessendes + * Ueberpruefen der Anzahl der gespeicherten Eintraege in der + * Mitgliederverwaltung. + * Die verwendete Datensatzdatei enthaelt 10000 Eintraege.
  • + *
  • Erwartet: + *
      + *
    • Anzahl Eintraege in der Mitgliederverwaltung: 10000.
    • + *
    • toArray() liefert ein Array der Groesse 10000.
    • + *
    • Anzahl Operationen: 24833052 ± 1000.
    • + *
    + *
  • + *
+ * @throws IOException + * wird ausgeloest, wenn ein E/A-Fehler auftritt, also das Lesen aus + * der Datensatzdatei fehlschlaegt. + */ + @Test + @TestDescription("Testen des Kontruktors(String).") + public void testKonstruktorString() throws IOException { + trace.add("Konstruktoraufruf Management(\"%s\")", fileName); + IManagement mgnt = new Management(fileName); + int count = mgnt.numberOfOperations(); + trace.add("Aufruf der Methode toArray()."); + IMember[] members = mgnt.toArray(); + + evaluate(members, mgnt.size(), fileLength); + evaluate(members, fileLength); + evaluate(count, 24833052, 1000); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management() und anschliessendes Einfuegen + * von 10000 Datensaetze in die Mitgliederverwaltung. + * Die 10000 Datensaetze werden durch Aufruf der Methode insert(IMember) + * einzeln in die Mitgliederverwaltung eingefuegt.
  • + *
  • Erwartet: + *
      + *
    • Anzahl Eintraege in der Mitgliederverwaltung: 10000.
    • + *
    • toArray() liefert ein Array der Groesse 10000.
    • + *
    • Anzahl Operationen: 24833052 ± 1000.
    • + *
    + *
  • + *
+ * @throws IOException + * wird ausgeloest, wenn ein E/A-Fehler auftritt, also das Lesen aus + * der Datensatzdatei fehlschlaegt. + */ + @Test + @AfterMethod ("testKonstruktorString") + @TestDescription("Testen der Insert-Methode.") + public void testEinfuegen() throws IOException { + trace.add("Konstruktoraufruf Management()"); + IManagement mgnt = new Management(); + trace.add("Aufruf der Methode toArray()."); + IMember[] members = mgnt.toArray(); + + evaluate(members, mgnt.size(), 0); + + trace.add("Einfuegen der Datensaetze in die Mitgliederverwaltung."); + String line; + int count = 0; + while ((line = bufferedReader.readLine()) != null) { + trace.addInfo(PassTrace.ifTrue("Einfuegen von Datensatz \"%s\".", + mgnt.insert(new Member(line)), line)); + count += mgnt.numberOfOperations(); + } + assertFalse("Datensatz/-saetze konnten nicht eingefügt werden.", + trace.hasOccurrences()); + trace.add("Aufruf der Methode toArray() nach dem Einfuegen."); + members = mgnt.toArray(); + + evaluate(members, mgnt.size(), fileLength); + evaluate(members, fileLength); + evaluate(count, 24833052, 1000); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String) und anschliessendes + * Suchen nach allen Schluesselwerten in der Mitgliederverwaltung. + * Die Datensatzdatei enthaelt 10000 Eintraege.
  • + *
  • Erwartet: + *
      + *
    • Anzahl Eintraege in der Mitgliederverwaltung: 10000.
    • + *
    • Alle Schluesselwerte muessen in der Mitgliederverwaltung + * gefunden werden.
    • + *
    • Gesamtanzahl Operationen beim Suchen aller 10000 Eintraege: + * 50005000 ± 10000.
    • + *
    + *
  • + *
+ * @throws IOException + * wird ausgeloest, wenn ein E/A-Fehler auftritt, also das Lesen aus + * der Datensatzdatei fehlschlaegt. + */ + @Test + @AfterMethod("testKonstruktorString") + @TestDescription("Testen der search(long)-Methode.") + public void testSuchen() throws IOException { + trace.add("Konstruktoraufruf Management(%s)", fileName); + IManagement mgnt = new Management(fileName); + trace.add("Aufruf der Methode toArray()."); + IMember[] members = mgnt.toArray(); + + evaluate(members, mgnt.size(), fileLength); + + trace.add("Suchen nach Datensaetze in die Mitgliederverwaltung."); + String line; + int count = 0; + while ((line = bufferedReader.readLine()) != null) { + IMember exp = new Member(line); + IMember got = mgnt.search(exp.getKey()); + trace.addInfo(PassTrace.ifEquals("Suchen nach Schluessel \"%d\".", + exp, got, exp.getKey())); + count += mgnt.numberOfOperations(); + } + assertFalse("Fehlerhafte / fehlende Datensaetze in der Mitgliederverwaltung.", + trace.hasOccurrences()); + evaluate(count, 50005000, fileLength); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String) und anschliessendes + * Ueberpruefen der Anzahl der Eintraege der Sportarten in der + * Mitgliederverwaltung. + * Die Datensatzdatei enthaelt 10000 Eintraege.
  • + *
  • Erwartete:
    + * Methode size(KindOfSport) muss folgende Werte liefern: + *
      + *
    • FUSSBALL: 985.
    • + *
    • HANDBALL: 989.
    • + *
    • SCHWIMMEN: 1037.
    • + *
    • LEICHTATHLETIK: 973.
    • + *
    • REITEN: 1000.
    • + *
    • FECHTEN: 985.
    • + *
    • TURNEN: 1033.
    • + *
    • RADSPORT: 996.
    • + *
    • TANZEN: 992.
    • + *
    • RUDERN: 1010.
    • + *
    + *
  • + *
  • Erwartete Gesamtanzahl Operationen beim Suchen aller 10000 Eintraege: + * 100000 ± 10000. + *
  • + *
+ * @throws IOException + * wird ausgeloest, wenn ein E/A-Fehler auftritt, also das Lesen aus + * der Datensatzdatei fehlschlaegt. + */ + @Test + @AfterMethod("testKonstruktorString") + @TestDescription("Testen der size(KindOfSport)-Methode.") + public void testTraversieren() throws IOException { + final int[] exp = {985, 989, 1037, 973, 1000, 985, 1033, 996, 992, 1010}; + + trace.add("Konstruktoraufruf Management(%s)", fileName); + IManagement mgnt = new Management(fileName); + + String msg = "Falsche Anzahl der Mitglieder fuer die Sportarten %s erhalten."; + int index = 0, count = 0; + for (KindOfSport sport : KindOfSport.values()) { + trace.add("Aufruf von size(%s).", sport); + trace.addInfo(PassTrace.ifEquals(msg, exp[index++], mgnt.size(sport), sport)); + count += mgnt.numberOfOperations(); + } + assertFalse("Methode size(KindOfSport) liefert falsches Ergebnis.", + trace.hasOccurrences()); + evaluate(count, 10 * 10000, 10000); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String) und anschliessendes + * Ueberpruefen der Eintraege der 10 Sportarten in der Mitgliederverwaltung. + * Mit Hilfe einer Pruefsumme wird festgestellt, ob die Eintraege + * korrekt sind. Die Datensatzdatei enthaelt 10000 Eintraege.
  • + *
  • Erwartete:
    + * Methode discipline(KindOfSport) muss folgende Werte liefern: + *
      + *
    • FUSSBALL: 985 Eintraege (Pruefsumme: 225236503928).
    • + *
    • HANDBALL: 989 Eintraege (Pruefsumme: 173758233713).
    • + *
    • SCHWIMMEN: 1037 Eintraege (Pruefsumme: 183013252630).
    • + *
    • LEICHTATHLETIK: 973 Eintraege (Pruefsumme: 161145468810).
    • + *
    • REITEN: 1000 Eintraege (Pruefsumme: 152686351492).
    • + *
    • FECHTEN: 985 Eintraege (Pruefsumme: 257673959686).
    • + *
    • TURNEN: 1033 Eintraege (Pruefsumme: 90525160369).
    • + *
    • RADSPORT: 996 Eintraege (Pruefsumme: 266557207632).
    • + *
    • TANZEN: 992 Eintraege (Pruefsumme: 74094229376).
    • + *
    • RUDERN: 1010 Eintraege (Pruefsumme: 58704317911).
    • + *
    + *
  • + *
+ * @throws IOException + * wird ausgeloest, wenn ein E/A-Fehler auftritt, also das Lesen aus + * der Datensatzdatei fehlschlaegt. + */ + @Test + @AfterMethod("testKonstruktorString") + @TestDescription("Testen der discipline(KindOfSport)-Methode.") + public void testTraversieren2() throws IOException { + final int[] exp = {985, 989, 1037, 973, 1000, 985, 1033, 996, 992, 1010}; + final long[] chk = {225236503928L, 173758233713L, 183013252630L, 161145468810L, + 152686351492L, 257673959686L, 90525160369L, 266557207632L, + 74094229376L, 58704317911L}; + + trace.add("Konstruktoraufruf Management(%s)", fileName); + IManagement mgnt = new Management(fileName); + + String msg = "Anzahl der Mitglieder fuer die Sportarten %s."; + int index = 0; + for (KindOfSport sport : KindOfSport.values()) { + trace.add("Aufruf von discipline(%s).", sport); + IMember[] got = mgnt.discipline(sport); + trace.addInfo(PassTrace.ifEquals(msg, exp[index], got.length, sport)); + trace.add("Alle Eintraege muessen der Sportart %s entprechen.", sport); + int idx = 0; + long chkSum = 0; + for (IMember member : got) { + trace.addInfo(PassTrace.ifEquals("[%d] Unerwartete Sportart %s.", + sport, member.getKindOfSport(), idx++, sport)); + chkSum ^= member.getKey(); + } + trace.add("Pruefsumme fuer die Sportart %s.", sport); + trace.addInfo(PassTrace.ifEquals("Unerwartete Pruefsumme.", chk[index], chkSum)); + index++; + } + assertFalse("Methode discipline(KindOfSport) liefert falsches Ergebnis.", + trace.hasOccurrences()); + } + + //----------------------------------------------------------------- + + /** + * Ueberpruefung der Anzahl Mitglieder in der Mitgliederverwaltung. + * @param members - Mitglieder in der Mitgliederverwaltung: IMember[]. + * @param size - erhaltene Anzahl der Mitglieder: int. + * @param exp - erwartete Anzahl der Mitglieder: int. + */ + private void evaluate(IMember[] members, int size, int exp) { + trace.add(PassTrace + .ifEquals("Anzahl der Datensaetze muss %d betragen.", exp, size, exp)); + trace.add(PassTrace + .ifEquals("toArray().length muss %d liefern.", exp, members.length, exp)); + assertFalse("Fehlerhafte Anzahl von Datensaetze in der Mitgliederverwaltung.", + trace.hasOccurrences()); + } + + /** + * Ueberpueft die Datensaetze in der Mitgliederverwaltung mit den Datensaetzen + * in der eingelesenen Datei. + * @param members - Mitglieder in der Mitgliederverwaltung: IMember[]. + * @param lines - Anzahl Zeilen (Datensaetze) in der eingelesenen Datei: int. + * @throws IOException + */ + private void evaluate(IMember[] members, int lines) throws IOException { + FileReader fr = new FileReader(new File(fileSort)); + BufferedReader br = new BufferedReader(fr); + int index = 0; + String line; + while ((line = br.readLine()) != null) { + IMember member = new Member(line); + trace.addInfo(PassTrace.ifEquals("Ungueltiger Datensatz [%d].", + member, members[index++], index)); + } + br.close(); + fr.close(); + int errors = trace.getOccurrences(); + assertFalse(errors + " fehlerhafte Datensaetze in der Mitgliederverwaltung.", + trace.hasOccurrences()); + } + + /** + * Ueberpruefung der Anzahl der Operationen. + * @param count - erhaltene Anzahl der Operationen: int. + * @param exp - erwartete Anzahl der Operationen: int. + * @param range - gueltiger Bereich um den erwarteten Wert: int. + */ + private void evaluate(int count, int exp, int range) { + if (evalOperations) { + int min = exp - range; + int max = exp + range; + Natural got = Natural.format(count); + trace.add(PassTrace.ifTrue( + "Anzahl Operationen muss im Bereich %d..%d liegen. Erhalten %d.", + got.rangeOf(min, max), min, max, count) + ); + assertFalse("Fehlerhafte Anzahl Operationen.", trace.hasOccurrences()); + } else { + System.err.println("Evaluate Operations disabled!"); + } + } + + +} diff --git a/src/de/ostfalia/algo/ws18/s2/test/ManagementTestS2.java b/src/de/ostfalia/algo/ws18/s2/test/ManagementTestS2.java new file mode 100644 index 0000000..0e539e4 --- /dev/null +++ b/src/de/ostfalia/algo/ws18/s2/test/ManagementTestS2.java @@ -0,0 +1,424 @@ +package de.ostfalia.algo.ws18.s2.test; + +import static org.junit.Assert.assertFalse; + +import java.util.Arrays; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.RuleChain; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; + +import de.ostfalia.algo.ws18.base.IManagement; +import de.ostfalia.algo.ws18.base.IMember; +import de.ostfalia.algo.ws18.base.KindOfSport; +import de.ostfalia.algo.ws18.base.Member; +import de.ostfalia.algo.ws18.s2.Management; +import de.ostfalia.junit.annotations.AfterMethod; +import de.ostfalia.junit.annotations.TestDescription; +import de.ostfalia.junit.base.IMessengerRules; +import de.ostfalia.junit.base.ITraceRules; +import de.ostfalia.junit.conditional.PassTrace; +import de.ostfalia.junit.rules.MessengerRule; +import de.ostfalia.junit.rules.RuleControl; +import de.ostfalia.junit.rules.TraceRule; +import de.ostfalia.junit.runner.TopologicalSortRunner; + +@RunWith(TopologicalSortRunner.class) +public class ManagementTestS2 { + + public RuleControl opt = RuleControl.NONE; + public IMessengerRules messenger = MessengerRule.newInstance(opt); + public ITraceRules trace = TraceRule.newInstance(opt); + + + @Rule + public TestRule chain = RuleChain + .outerRule(trace) + .around(messenger); + /** + * Datensatz mit 10 Eintraegen als Testdaten fuer die JUnit-Tests. + */ + public String[] data10 = {"Hueber, Uta, 1922-10-15, F, HANDBALL", //[0] + "Muller, Ursula, 1964-01-28, F, HANDBALL", //[1] + "Fried, Heike, 1997-12-14, F, RUDERN", //[2] + "Meyer, Tanja, 1946-04-16, F, HANDBALL", //[3] + "Brauer, Mandy, 1933-07-21, F, FUSSBALL", //[4] + "Weiss, Ulrich, 1987-06-09, M, FUSSBALL", //[5] + "Bohm, Stephanie, 1931-10-22, F, HANDBALL", //[6] + "Huber, Annett, 1936-11-19, F, RUDERN", //[7] + "Hertz, Thomas, 1946-10-01, M, HANDBALL", //[8] + "Scholz, Anja, 1933-01-12, F, RUDERN"}; //[9] + + + /** + * Schluesselwerte fuer den Datensatz data (10 Eintraege). + */ + public long[] keys10 = {82115101922L, 132128011964L, 60814121997L, 132016041946L, + 21321071933L, 232109061987L, 21922101931L, 80119111936L, + 82001101946L, 190112011933L}; + + int[] all = {4, 6, 2, 7, 8, 0, 3, 1, 9, 5}; + int[] ofs = {-1, +1}; + + @Before + public void setUp() throws Exception { + } + + /** + *
    + *
  • Testfall: Standard-Konstruktoraufruf Management().
    + * Nach Aufruf des Standard-Konstruktors duerfen sich keine Datensaetze + * in der Mitgliederverwaltung befinden.
  • + *
  • Erwartet: Anzahl der Datensaetze = 0.
  • + *
+ */ + @Test + @TestDescription("Testen des Kontruktors().") + public void testKonstruktorOhneParameter() { + trace.add("Konstruktoraufruf Management()"); + IManagement mgnt = new Management(); + evaluate(mgnt); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String[]) mit einem Datensatz.
    + * Nach Aufruf Konstruktors muss sich genau ein Datensatz (data10[0]) + * in der Mitgliederverwaltung befinden.
  • + *
  • Erwartet: data10[0] in der Mitgliederverwaltung.
  • + *
+ */ + @Test + @AfterMethod("testKonstruktorOhneParameter") + @TestDescription("Testen des Kontruktors(String[]) mit einem Datensatz.") + public void testKonstruktorEinDatensatz() { + trace.add("Konstruktoraufruf Management(String[])"); + IManagement mgnt = new Management(Arrays.copyOf(data10, 1)); + evaluate(mgnt, 0); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String[]) mit 10 Datensaetzen.
    + * Nach Aufruf Konstruktors mussen sich alle 10 Datensaetze in der + * Mitgliederverwaltung befinden.
  • + *
  • Erwartet: data10[0] bis data10[9] in der Mitgliederverwaltung.
  • + *
+ */ + @Test + @AfterMethod("testKonstruktorEinDatensatz") + @TestDescription("Testen des Kontruktors(String[]) mit 10 Datensaetzen.") + public void testKonstruktorZehnDatensaetze() { + trace.add("Konstruktoraufruf Management(String[])"); + IManagement mgnt = new Management(data10); + evaluate(mgnt, all); + } + + /** + *
    + *
  • Testfall: Standard-Konstruktoraufruf Management() und anschliessendes + * Einfuegen von 10 Datensaetzen.
    + * Alle Datensaetze muessen in die Mitgliederverwaltung eingefuegt + * werden koennen.
  • + *
  • Erwartet: data10[0] bis data10[9] in der Mitgliederverwaltung.
  • + *
+ */ + @Test + @AfterMethod("testKonstruktorZehnDatensaetze") + @TestDescription("Testen der insert(IMember)-Methode mit 10 Datensaetzen.") + public void testInsert() { + trace.add("Konstruktoraufruf Management()"); + IManagement mgnt = new Management(); + evaluate(mgnt); + + String msg = "Falscher Rueckgabe beim Einfuegen errhalten."; + for (int i = 0; i < data10.length; i++) { + trace.add("Datensatz \"%s\" hinzufuegen.", data10[i]); + IMember member = new Member(data10[i]); + trace.addInfo("Aufruf von insert(%s).", member); + trace.addInfo(PassTrace.ifTrue(msg, mgnt.insert(member))); + } + evaluate(mgnt, all); + } + + /** + *
    + *
  • Testfall: Standard-Konstruktoraufruf Management() und anschliessendes + * Einfuegen von 10 Datensaetzen in umgekehrter Reihenfolge.
    + * Alle Datensaetze muessen in die Mitgliederverwaltung eingefuegt + * werden koennen.
  • + *
  • Erwartet: data10[0] bis data10[9] in der Mitgliederverwaltung.
  • + *
+ */ + @Test + @AfterMethod("testKonstruktorZehnDatensaetze") + @TestDescription("Testen der insert(IMember)-Methode mit 10 Datensaetzen.") + public void testInsertReverse() { + trace.add("Konstruktoraufruf Management()"); + IManagement mgnt = new Management(); + evaluate(mgnt); + + String msg = "Falscher Rueckgabe beim Einfuegen errhalten."; + for (int i = data10.length ; i > 0; i--) { + trace.add("Datensatz \"%s\" hinzufuegen.", data10[i - 1]); + IMember member = new Member(data10[i - 1]); + trace.addInfo("Aufruf von insert(%s).", member); + trace.addInfo(PassTrace.ifTrue(msg, mgnt.insert(member))); + } + evaluate(mgnt, all); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String[]) mit 10 Datensaetzen + * und anschliessendes Suchen nach den Schuesselwerten in der + * Mitgliederverwaltung.
  • + *
  • Erwartet: Alle Schuesselwerten muessen in der Mitgliederverwaltung + * gefunden werden. Die Methode search(long) muss den zugehoerigen + * Datensatz zurueckliefern.
  • + *
+ */ + @Test + @AfterMethod("testKonstruktorZehnDatensaetze") + @TestDescription("Testen der search(long)-Methode mit 10 Datensaetzen.") + public void testSearchLong() { + trace.add("Konstruktoraufruf Management(String[])"); + IManagement mgnt = new Management(data10); + evaluate(mgnt, all); + + String msg = "Falscher Datensatz bei der Suche nach %d geliefert."; + for (int i = 0; i < data10.length; i++) { + trace.add("Aufruf von search(%d)", keys10[i]); + String exp = concat(i); + IMember got = mgnt.search(keys10[i]); + trace.addInfo(PassTrace.ifEquals(msg, exp, got, keys10[i])); + } + assertFalse("Methode search(long) liefert falschen Datensatz.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String[]) mit 10 Datensaetzen + * und anschliessendes Suchen nach Schuesselwerten, die nicht in der + * Mitgliederverwaltung existieren.
  • + *
  • Erwartet: Kein Schuesselwert darf in der Mitgliederverwaltung + * gefunden werden. Methode search(long) muss null liefern.
  • + *
+ */ + @Test + @AfterMethod("testKonstruktorZehnDatensaetze") + @TestDescription("Methode search(long) muss bei nicht vorhandenen Schluesseln null liefern.") + public void testSearchNotExist() { + trace.add("Konstruktoraufruf Management(String[])"); + IManagement mgnt = new Management(data10); + evaluate(mgnt, all); + + String msg = "Nicht vorhandener Schluessel %d geliefert ungueltigen Datensatz."; + for (int i = 0; i < data10.length; i++) { + for (int j = 0; j < ofs.length; j++) { + long key = keys10[i] + ofs[j]; + trace.add("Aufruf von search(%d)", key); + IMember got = mgnt.search(key); + trace.addInfo(PassTrace.ifEquals(msg, null, got, key)); + } + } + assertFalse("Methode search(long) liefert falschen Datensatz.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String[]) mit 10 Datensaetzen + * und anschliessendes Suchen nach dem Nach- und Vornamen in der + * Mitgliederverwaltung.
  • + *
  • Erwartet: Alle Namen muessen in der Mitgliederverwaltung + * gefunden. Die Methode search(String, String) muss den zugehoerigen + * Datensatz zurueckliefern.
  • + *
+ */ + @Test + @AfterMethod("testKonstruktorZehnDatensaetze") + @TestDescription("Testen der search(String, String)-Methode mit 10 Datensaetzen.") + public void testSearchName() { + trace.add("Konstruktoraufruf Management(String[])"); + IManagement mgnt = new Management(data10); + evaluate(mgnt, all); + + String msg = "Falscher Datensatz bei der Suche nach \"%s, %s\" geliefert."; + for (int i = 0; i < data10.length; i++) { + String[] parts = data10[i].split(","); + trace.add("Aufruf von search(\"%s, %s\")", parts[0], parts[1]); + String exp = concat(i); + IMember got = mgnt.search(parts[0].trim(), parts[1].trim()); + trace.addInfo(PassTrace.ifEquals(msg, exp, got, parts[0], parts[1])); + } + assertFalse("Methode search(String, String) liefert falschen Datensatz.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String[]) mit 10 Datensaetzen + * und anschliessendes Suchen nach dem Nach- und Vornamen in der + * Mitgliederverwaltung, wobei der Nachname nicht exsistiert.
  • + *
  • Erwartet: Kein Namen darf in der Mitgliederverwaltung + * gefunden werden. Die Methode search(String, String) muss null liefern.
  • + *
+ */ + @Test + @AfterMethod("testKonstruktorZehnDatensaetze") + @TestDescription("Methode search(String, String) nuss bei unbekannen Namen null liefern.") + public void testSearchUnknown() { + trace.add("Konstruktoraufruf Management(String[])"); + IManagement mgnt = new Management(data10); + evaluate(mgnt, all); + + String msg = "Ungueltiger Datensatz bei der Suche nach \"%s, %s\" geliefert."; + for (int i = 0; i < data10.length; i++) { + String[] parts = data10[i].split(","); + String unknown = parts[0] + "s"; + trace.add("Aufruf von search(\"%s, %s\")", unknown, parts[1]); + IMember got = mgnt.search(unknown.trim(), parts[1].trim()); + trace.addInfo(PassTrace.ifEquals(msg, null, got, unknown, parts[1])); + } + assertFalse("Methode search(String, String) liefert falschen Datensatz.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String[]) mit 10 Datensaetzen + * und anschliessendes Ermitteln der Anzahl der Eintraege fuer die + * Sportarten HANDBALL, RUDERN, FUSSBALL und REITEN in der + * Mitgliederverwaltung.
  • + *
  • Erwartet: Die Methode size(KindOfSport) muss folgende Werte liefern: + *
      + *
    • HANDBALL: 5
    • + *
    • RUDERN: 3
    • + *
    • FUSSBALL: 2
    • + *
    • REITEN: 0
    • + *
    + *
  • + *
+ */ + @Test + @AfterMethod("testKonstruktorZehnDatensaetze") + @TestDescription("Testen der size(KindOfSport)-Methode mit 10 Datensaetzen.") + public void testSizeKindOfSport() { + trace.add("Konstruktoraufruf Management(String[])"); + IManagement mgnt = new Management(data10); + evaluate(mgnt, all); + + String msg = "Falsche Anzahl der Mitglieder fuer die Sportarten %s erhalten."; + + KindOfSport sport = KindOfSport.HANDBALL; + trace.add("Aufruf von size(%s).", sport); + trace.addInfo(PassTrace.ifEquals(msg, 5, mgnt.size(sport), sport)); + + sport = KindOfSport.RUDERN; + trace.add("Aufruf von size(%s).", sport); + trace.addInfo(PassTrace.ifEquals(msg, 3, mgnt.size(sport), sport)); + + sport = KindOfSport.FUSSBALL; + trace.add("Aufruf von size(%s).", sport); + trace.addInfo(PassTrace.ifEquals(msg, 2, mgnt.size(sport), sport)); + + sport = KindOfSport.REITEN; + trace.add("Aufruf von size(%s).", sport); + trace.addInfo(PassTrace.ifEquals(msg, 0, mgnt.size(sport), sport)); + + assertFalse("Methode size(KindOfSport) liefert falsches Ergebnis.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: Konstruktoraufruf Management(String[]) mit 10 Datensaetzen + * und anschliessendes Ermitteln der Eintraege fuer die Sportarten + * HANDBALL, RUDERN, FUSSBALL und REITEN in der Mitgliederverwaltung.
  • + *
  • Erwartet:
    + * Die Methode discipline(KindOfSport) muss folgende Datensaetze + * liefern (angegeben ist jeweils der Index im Datensatz data10): + *
      + *
    • HANDBALL: [6], [8], [0], [3], [1]
    • + *
    • RUDERN: [2], [7], [9]
    • + *
    • FUSSBALL: [4], [5]
    • + *
    • REITEN: nicht im Datensatz vorhanden
    • + *
    + *
  • + *
+ */ + @Test + @AfterMethod("testKonstruktorZehnDatensaetze") + public void testDiscipline() { + trace.add("Konstruktoraufruf Management(String[])"); + IManagement mgnt = new Management(data10); + evaluate(mgnt, all); + + KindOfSport sport = KindOfSport.HANDBALL; + trace.add("Aufruf von discipline(%s).", sport); + evaluate(mgnt.discipline(sport), 6, 8, 0, 3, 1); + + sport = KindOfSport.RUDERN; + trace.add("Aufruf von discipline(%s).", sport); + evaluate(mgnt.discipline(sport), 2, 7, 9); + + sport = KindOfSport.FUSSBALL; + trace.add("Aufruf von discipline(%s).", sport); + evaluate(mgnt.discipline(sport), 4, 5); + + sport = KindOfSport.REITEN; + trace.add("Aufruf von discipline(%s).", sport); + evaluate(mgnt.discipline(sport)); + + assertFalse("Methode discipline(KindOfSport) liefert falsches Ergebnis.", + trace.hasOccurrences()); + } + + //----------------------------------------------------------------- + + /** + * Ueberpruefung der durch die Methode toArray() der Mitgilderverwaltung + * zurueckgelieferten Datensaetze. + * @param mgnt - Mitgliederverwaltung: IManagement. + * @param elements - Indizes der erwarteten Testdatensaetze: int... + */ + private void evaluate(IManagement mgnt, int... elements) { + evaluate(mgnt.toArray(), elements); + } + + /** + * Ueberpruefung der uebergebenen Datensaetze anhand der Indizes der + * erwarteten Testdatensaetze. + * @param members - Array mit Datensaetze: IMember[]. + * @param elements - Indizes der erwarteten Testdatensaetze: int... + */ + private void evaluate(IMember[] members, int... elements) { + trace.addInfo(PassTrace.ifEquals("Anzahl der Mitglieder nicht korrekt.", + elements.length, members.length)); + int length = Integer.min(elements.length, members.length); + for (int i = 0; i < length; i++) { + int index = elements[i]; + String exp = concat(index); + trace.addInfo(PassTrace.ifEquals("Fehler im Datensatz %d.", + exp, members[i], i + 1)); + } + assertFalse("Fehlerhafte Datensaetze in der Mitgliederverwaltung.", + trace.hasOccurrences()); + } + + /** + * Zusammenfuegen eines Schluesselwerts mit dem zuhegoerigen Datensatz + * entsprechend ihrem Index in den Testdatensaetzen. + * @param element - Index im Datensatz: int. + * @return Schluesselwert mit dem zuhegoerigen Datensatz: String. + */ + private String concat(int element) { + return keys10[element] + ", " + data10[element]; + } + +} diff --git a/src/de/ostfalia/algo/ws18/s2/test/MemberTest.java b/src/de/ostfalia/algo/ws18/s2/test/MemberTest.java new file mode 100644 index 0000000..1078cdc --- /dev/null +++ b/src/de/ostfalia/algo/ws18/s2/test/MemberTest.java @@ -0,0 +1,260 @@ +package de.ostfalia.algo.ws18.s2.test; + +import static org.junit.Assert.*; + +import java.time.LocalDate; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.RuleChain; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; + +import de.ostfalia.algo.ws18.base.Gender; +import de.ostfalia.algo.ws18.base.IMember; +import de.ostfalia.algo.ws18.base.KindOfSport; +import de.ostfalia.algo.ws18.base.Member; +import de.ostfalia.junit.annotations.TestDescription; +import de.ostfalia.junit.base.IMessengerRules; +import de.ostfalia.junit.base.ITraceRules; +import de.ostfalia.junit.conditional.PassTrace; +import de.ostfalia.junit.rules.MessengerRule; +import de.ostfalia.junit.rules.RuleControl; +import de.ostfalia.junit.rules.TraceRule; +import de.ostfalia.junit.runner.TopologicalSortRunner; + +@RunWith(TopologicalSortRunner.class) +public class MemberTest { + + public RuleControl opt = RuleControl.NONE; + public IMessengerRules messenger = MessengerRule.newInstance(opt); + public ITraceRules trace = TraceRule.newInstance(opt); + + + @Rule + public TestRule chain = RuleChain + .outerRule(trace) + .around(messenger); + + /** + * Datensatz mit 10 Eintraegen als Testdaten fuer die JUnit-Tests. + */ + public String[] data = {"Ackerman, Niklas, 1979-04-08, M, SCHWIMMEN", //[0] + "Bauer, Juliane, 1939-01-16, F, FECHTEN", //[1] + "Kirsch, Antje, 1960-07-13, F, TURNEN", //[2] + "Koertig, Dominik, 1933-09-28, M, HANDBALL", //[3] + "Trommler, Ines, 1924-10-29, F, TURNEN", //[4] + "Hirsch, Manuela, 1948-05-10, F, RUDERN", //[5] + "Schaefer, Stephanie, 1997-05-31, F, FECHTEN", //[6] + "Schultz, Katrin, 1952-08-18, F, REITEN", //[7] + "Fried, Leonie, 1965-09-24, F, TURNEN", //[8] + "Lemann, Philipp, 1936-10-30, M, RADSPORT"}; //[9] + + /** + * Datensatz mit 3 Eintraegen als Testdaten fuer die JUnit-Tests. + */ + public String[] test = {"Ackerman, Niklas, 1979-04-08, M, SCHWIMMEN", + "Acker, Nadine, 1979-04-08, F, HANDBALL", + "Acker, Nadine, 1979-04-10, F, HANDBALL"}; + + /** + * Schluesselwerte fuer den Datensatz data (10 Eintraege). + */ + public long[] keys = {11408041979L, 21016011939L, 110113071960L, 110428091933L, + 200929101924L, 81310051948L, 191931051997L, 191118081952L, + 61224091965L, 121630101936L}; + + @Before + public void setUp() throws Exception { + } + + /** + *
    + *
  • Testfall: toString()-Methode der Klasse Member.
    + * Es werden alle 10 Datensaetze nacheinander druchlaufen.
  • + *
  • Erwartet: Rueckgabe aller Attribute inkl. des berechneten Schluessels als String.
  • + *
  • Beispiel fuer data[0]: 11408041979, Ackerman, Niklas, 1979-04-08, M, SCHWIMMEN.
  • + *
+ */ + @Test (timeout = 1000) + @TestDescription("Testen der toString()-Methode.") + public void testToString() { + for (int i = 0; i < keys.length; i++) { + trace.add("Konstruktoraufruf Member(%s)", data[i]); + IMember member = new Member(data[i]); + String exp = keys[i] + ", " + data[i]; + String got = member.toString(); + trace.addInfo(PassTrace.ifEquals("Fehler im Datensatz %d", + exp, got, i + 1)); + } + assertFalse("Fehler bei der Implementierung toString()-Methode.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: getKey()-Methode der Klasse Member.
  • + *
  • Erwartet: Rueckgabe des Schluessels als Long-Wert.
  • + *
  • Beispiel fuer data[0]: 11408041979.
  • + *
+ */ + @Test (timeout = 1000) + @TestDescription("Testen der getKey()-Methode.") + public void testGetKey() { + for (int i = 0; i < keys.length; i++) { + trace.add("Konstruktoraufruf Member(%s)", data[i]); + IMember member = new Member(data[i]); + Long exp = keys[i]; + Long got = member.getKey(); + trace.addInfo(PassTrace.ifEquals("Fehlerhafter Schuessel im Datensatz %d", + exp, got, i + 1)); + } + assertFalse("Fehler bei der Rueckgabe des Schluesselwertes.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: getName()-Methode der Klasse Member.
  • + *
  • Erwartet: Rueckgabe des Nachnamens als String.
  • + *
  • Beispiel fuer data[0]: Ackerman.
  • + *
+ */ + @Test (timeout = 1000) + @TestDescription("Testen der getName()-Methode.") + public void testGetName() { + for (int i = 0; i < keys.length; i++) { + trace.add("Konstruktoraufruf Member(%s)", data[i]); + IMember member = new Member(data[i]); + String exp = data[i].split(",")[0]; + String got = member.getName(); + trace.addInfo(PassTrace.ifEquals("Fehlerhafter Nachname im Datensatz %d", + exp, got, i + 1)); + } + assertFalse("Fehler bei der Rueckgabe des Nachnamens.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: getFirstName()-Methode der Klasse Member.
  • + *
  • Erwartet: Rueckgabe des Vornamens als String.
  • + *
  • Beispiel fuer data[0]: Niklas.
  • + *
+ */ + @Test (timeout = 1000) + @TestDescription("Testen der getFirstName()-Methode.") + public void testGetFirstName() { + for (int i = 0; i < keys.length; i++) { + trace.add("Konstruktoraufruf Member(%s)", data[i]); + IMember member = new Member(data[i]); + String exp = data[i].split(",")[1]; + String got = member.getFirstName(); + trace.addInfo(PassTrace.ifEquals("Fehlerhafter Vornamen im Datensatz %d", + exp, got, i + 1)); + } + assertFalse("Fehler bei der Rueckgabe des Vornamens.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: getDate()-Methode der Klasse Member.
  • + *
  • Erwartet: Rueckgabe des Geburtsdatum als LocalDate.
  • + *
  • Beispiel fuer data[0]: 1979-04-08.
  • + *
+ */ + @Test (timeout = 1000) + @TestDescription("Testen der geDate()-Methode.") + public void testGetDate() { + for (int i = 0; i < keys.length; i++) { + trace.add("Konstruktoraufruf Member(%s)", data[i]); + IMember member = new Member(data[i]); + String exp = data[i].split(",")[2]; + LocalDate got = member.getDate(); + trace.addInfo(PassTrace.ifEquals("Fehlerhaftes Geburtsdatum im Datensatz %d", + exp, got, i + 1)); + } + assertFalse("Fehler bei der Rueckgabe des Geburtsdatums.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: getGender()-Methode der Klasse Member.
  • + *
  • Erwartet: Rueckgabe des Geschlechts als enum Gender.
  • + *
  • Beispiel fuer data[0]: M.
  • + *
+ */ + @Test (timeout = 1000) + @TestDescription("Testen der getGender()-Methode.") + public void testGender() { + for (int i = 0; i < keys.length; i++) { + trace.add("Konstruktoraufruf Member(%s)", data[i]); + IMember member = new Member(data[i]); + String exp = data[i].split(",")[3]; + Gender got = member.getGender(); + trace.addInfo(PassTrace.ifEquals("Fehlerhaftes Geschlecht im Datensatz %d", + exp, got, i + 1)); + } + assertFalse("Fehler bei der Rueckgabe des Geschlechts.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: getKindOfSport()-Methode der Klasse Member.
  • + *
  • Erwartet: Rueckgabe der Sportart als enum KindOfSport.
  • + *
  • Beispiel fuer data[0]: SCHWIMMEN.
  • + *
+ */ + @Test (timeout = 1000) + @TestDescription("Testen der getKindOfSport()-Methode.") + public void testGetKindOfSport() { + for (int i = 0; i < keys.length; i++) { + trace.add("Konstruktoraufruf Member(%s)", data[i]); + IMember member = new Member(data[i]); + String exp = data[i].split(",")[4]; + KindOfSport got = member.getKindOfSport(); + trace.addInfo(PassTrace.ifEquals("Fehlerhafte Sportart im Datensatz %d", + exp, got, i + 1)); + } + assertFalse("Fehler bei der Rueckgabe der Sportart.", + trace.hasOccurrences()); + } + + /** + *
    + *
  • Testfall: equals()-Methode der Klasse Member.
  • + *
  • Erwartet: true, wenn die Member inhaltlich gleich sind, sonst false.
  • + *
+ */ + @Ignore + @Test (timeout = 1000) + @TestDescription("Testen der equals()-Methode.") + public void testEqualsObject() { + trace.add("Konstruktoraufruf Member(%s) fuer Mitglied %d", data[0], 1); + IMember member1 = new Member(test[0]); + trace.add("Konstruktoraufruf Member(%s) fuer Mitglied %d", data[0], 2); + IMember duplikat = new Member(test[0]); + trace.add("Konstruktoraufruf Member(%s) fuer Mitglied %d", data[1], 3); + IMember member2 = new Member(test[1]); + trace.add("Konstruktoraufruf Member(%s) fuer Mitglied %d", data[1], 4); + IMember member3 = new Member(test[2]); + + trace.addInfo(PassTrace.ifTrue("[%s] gleich [%s]?", + member1.equals(duplikat), member1, duplikat)); + trace.addInfo(PassTrace.ifTrue("[%s] gleich [%s]", + member1.equals(member2), member1, member2)); + trace.addInfo(PassTrace.ifFalse("[%s] gleich [%s]", + member1.equals(member3), member1, member3)); + trace.addInfo(PassTrace.ifFalse("[%s] gleich [%s]", + member2.equals(member3), member2, member3)); + + assertFalse("equals()-Methode fehlerhaft implementiert.", + trace.hasOccurrences()); + } + +} -- cgit v1.3.1