package pl.edu.amu.wmi.daut.base; import java.util.ArrayList; import java.util.Collections; import java.util.List; import junit.framework.TestCase; /** * Klasa Testująca metodę zwracającą przykładowe słowo * akceprowane przez automat. * * @author JakubS91 */ public class TestGeneratorRandomWord extends TestCase { /** * Metoda zwraca deterministyczny automat sk. stanowy akceptujący słowa * z parzystą liczbą wystąpień 'a' i parzystą liczbą wystąpień 'b' * nad językiem {a,b}*. */ private AutomatonSpecification getAutomatonA() { AutomatonSpecification automaton = new NaiveAutomatonSpecification(); State qpp = automaton.addState(); State qnp = automaton.addState(); State qnn = automaton.addState(); State qpn = automaton.addState(); automaton.addTransition(qpp, qnp, new CharTransitionLabel('a')); automaton.addTransition(qnp, qpp, new CharTransitionLabel('a')); automaton.addTransition(qnp, qnn, new CharTransitionLabel('b')); automaton.addTransition(qnn, qnp, new CharTransitionLabel('b')); automaton.addTransition(qnn, qpn, new CharTransitionLabel('a')); automaton.addTransition(qpn, qnn, new CharTransitionLabel('a')); automaton.addTransition(qpn, qpp, new CharTransitionLabel('b')); automaton.addTransition(qpp, qpn, new CharTransitionLabel('b')); automaton.markAsInitial(qpp); automaton.markAsFinal(qpp); return automaton; } /** * Metoda zwraca deterministyczny automat sk. stanowy akceptujący słowa * które zawierają ciąg "aba" nad językiem {a,b}*. */ private AutomatonSpecification getAutomatonB() { AutomatonSpecification automaton = new NaiveAutomatonSpecification(); State q0 = automaton.addState(); State q1 = automaton.addState(); State q2 = automaton.addState(); State q3 = automaton.addState(); automaton.addTransition(q0, q1, new CharTransitionLabel('a')); automaton.addLoop(q0, new CharTransitionLabel('b')); automaton.addTransition(q1, q2, new CharTransitionLabel('b')); automaton.addLoop(q1, new CharTransitionLabel('a')); automaton.addTransition(q2, q3, new CharTransitionLabel('a')); automaton.addTransition(q2, q0, new CharTransitionLabel('b')); automaton.addLoop(q3, new CharTransitionLabel('a')); automaton.addLoop(q3, new CharTransitionLabel('b')); automaton.markAsInitial(q0); automaton.markAsFinal(q3); return automaton; } /** * Metoda zwraca niedeterministyczny automat sk. stanowy akceptujący słowa * które zawierają ciąg literę 'b' na przedostatnim miejscu * nad językiem {a,b}*. */ private AutomatonSpecification getAutomatonC() { AutomatonSpecification automaton = new NaiveAutomatonSpecification(); State q0 = automaton.addState(); State q1 = automaton.addState(); State q2 = automaton.addState(); automaton.addLoop(q0, new CharTransitionLabel('a')); automaton.addLoop(q0, new CharTransitionLabel('b')); automaton.addTransition(q0, q1, new CharTransitionLabel('b')); automaton.addTransition(q1, q2, new CharTransitionLabel('a')); automaton.addTransition(q1, q2, new CharTransitionLabel('b')); automaton.markAsInitial(q0); automaton.markAsFinal(q2); return automaton; } /** * Metoda zwraca deterministyczny automat sk. stanowy akceptujący słowa * "a", "b" i "c" nad językiem {a, b, c}*. */ private AutomatonSpecification getAutomatonD() { AutomatonSpecification automaton = new NaiveAutomatonSpecification(); State q0 = automaton.addState(); State q1 = automaton.addState(); State q2 = automaton.addState(); State q3 = automaton.addState(); automaton.addTransition(q0, q1, new CharTransitionLabel('a')); automaton.addTransition(q0, q2, new CharTransitionLabel('b')); automaton.addTransition(q0, q3, new CharTransitionLabel('c')); automaton.markAsInitial(q0); automaton.markAsFinal(q1); automaton.markAsFinal(q2); automaton.markAsFinal(q3); return automaton; } /** * Metoda zwraca deterministyczny automat sk. stanowy akceptujący słowa * "a" i "ab". */ private AutomatonSpecification getAutomatonE() { AutomatonSpecification automaton = new NaiveAutomatonSpecification(); State q0 = automaton.addState(); State q1 = automaton.addState(); State q2 = automaton.addState(); automaton.addTransition(q0, q1, new CharTransitionLabel('a')); automaton.addTransition(q1, q2, new CharTransitionLabel('b')); automaton.markAsInitial(q0); automaton.markAsFinal(q1); automaton.markAsFinal(q2); return automaton; } /** * Sprawdza poprawność wygenerowanych słów. Sprawdza czy zwrócone słowo * przez metodę randomWord z klasy Generator jest akceptowane przez dany automat. * Test jest przeprowadzony określoną ilość razy. */ private boolean check(AutomatonSpecification automaton, String alphabet, int numberOfTests) { AutomatonByRecursion automatonCheck = new AutomatonByRecursion(automaton); Generator generator = new Generator(); boolean result = true; String generatedWord = new String(); for (int i = 0; i < numberOfTests; i++) { generatedWord = generator.randomWord(automaton, alphabet, automaton.getInitialState()); if (!automatonCheck.accepts(generatedWord)) { result = false; break; } } return result; } /** * Metoda sprawdza losowość wygenerowanych słów. Sprawdza czy zostały * wygenerowane wszystkie możliwe słowa przez metodę randomWord z klasy * Generator akceptowane przez dany automat. * Ilość wygenerowanych słów jest sprawdzana po wywołaniu metody * określoną ilość razy. */ private boolean checkAllPossibilities(AutomatonSpecification automaton, String alphabet, int numberOfTests, int allPossibilities) { List<String> words = new ArrayList<String>(); Generator generator = new Generator(); for (int i = 0; i < numberOfTests; i++) { String generatedWord = generator.randomWord(automaton, alphabet, automaton.getInitialState()); if (!(Collections.binarySearch(words, generatedWord) >= 0)) { words.add(generatedWord); Collections.sort(words); } } return (words.size() == allPossibilities); } /** * Metoda wywołująca test która sprawdza czy zwrócone słowo ma parzystą * liczba wystąpień 'a' i 'b'. */ public final void testGeneratorRandomWordOdd() { assertTrue(check(getAutomatonA(), "ab", 100)); } /** * Metoda wywołująca test która sprawdza czy zwrócone słowo * zawiera w sobie ciąg "aba". */ public final void testGeneratorRandomWordABA() { assertTrue(check(getAutomatonB(), "ab", 100)); } /** * Metoda wywołująca test która sprawdza czy zwrócone słowo * mające na przedostatnim miejscu 'b'. */ public final void testGeneratorRandomWordPenultimate() { assertTrue(check(getAutomatonC(), "ab", 100)); } /** * Metoda wywołująca test która sprawdza czy zwrócone słowo * mające na przedostatnim miejscu 'b'. */ public final void testGeneratorRandomWordAb() { assertTrue(check(getAutomatonE(), "a", 100)); assertTrue(check(getAutomatonE(), "ab", 100)); } /** * Metoda wywołująca test która sprawdza losowość wybenerowanych słów. */ public final void testGeneratorRandomWord() { assertTrue(checkAllPossibilities(getAutomatonD(), "abc", 1000, 3)); } }