package pl.edu.amu.wmi.daut.base;
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import junit.framework.TestCase;
/**
* Testy klasy AutomatonSpecification.
*/
public class TestAutomatonSpecification extends TestCase {
/**
* Test metody countStates.
*/
public final void testCountStates() {
NaiveAutomatonSpecification spec = new NaiveAutomatonSpecification();
//Test 1
assertEquals(spec.countStates(), 0);
//Test 2
State q0 = spec.addState();
assertEquals(spec.countStates(), 1);
//Test 3
for (int i = 1; i <= 123456; i++) {
State q = spec.addState();
}
assertEquals(spec.countStates(), 123456 + 1);
}
/**
* Test metody acceptEmptyWord dla automatu z tym samym stanem poczatkowym i koncowym.
*/
public final void testAcceptEmptyWordFinalTheSameAsInitial() {
//Test 1 - stan poczatkowy jest stanem koncowym
NaiveAutomatonSpecification testSpec1 = new NaiveAutomatonSpecification();
State state = testSpec1.addState();
testSpec1.markAsInitial(state);
testSpec1.markAsFinal(state);
assertTrue(testSpec1.acceptEmptyWord());
}
/**
* Test metody acceptEmptyWord dla automatu bez epsilon-przejsc.
*/
public final void testAcceptEmptyWordNoEpsilonTransitions() {
//Test 2 - automat ma wiecej stanow, bez epsilon-przejsc do stanu koncowego
NaiveAutomatonSpecification testSpec2 = new NaiveAutomatonSpecification();
State q0 = testSpec2.addState();
State q1 = testSpec2.addState();
State q2 = testSpec2.addState();
testSpec2.addTransition(q0, q1, new CharTransitionLabel('a'));
testSpec2.addTransition(q1, q2, new CharTransitionLabel('b'));
testSpec2.markAsInitial(q0);
testSpec2.markAsFinal(q2);
assertFalse(testSpec2.acceptEmptyWord());
}
/**
* Test metody acceptEmptyWord dla automatu z epsilon przejsciami
* ze stanu poczatkowego do koncowego.
*/
public final void testAcceptEmptyWordWithEpsilonTransitions() {
//Test 3 - automat jak w poprzednim przypadku
//ale zawiera epsilon-przejscia do stanu koncowego
NaiveAutomatonSpecification testSpec2 = new NaiveAutomatonSpecification();
State q0 = testSpec2.addState();
State q1 = testSpec2.addState();
State q2 = testSpec2.addState();
State q3 = testSpec2.addState();
testSpec2.markAsInitial(q0);
testSpec2.markAsFinal(q2);
testSpec2.addTransition(q0, q1, new CharTransitionLabel('a'));
testSpec2.addTransition(q1, q2, new CharTransitionLabel('b'));
testSpec2.addTransition(q0, q3, new EpsilonTransitionLabel());
testSpec2.addTransition(q3, q2, new EpsilonTransitionLabel());
assertTrue(testSpec2.acceptEmptyWord());
}
/**
* Test metody acceptEmptyWord dla automatu z pętlą.
*/
public final void testAcceptEmptyWordForAutomatonWithLoop() {
NaiveAutomatonSpecification spec = new NaiveAutomatonSpecification();
State s0 = spec.addState();
State s1 = spec.addState();
spec.markAsInitial(s0);
spec.markAsFinal(s1);
spec.addLoop(s0, new CharTransitionLabel('a'));
spec.addTransition(s1, s0, new CharTransitionLabel('b'));
assertFalse(spec.acceptEmptyWord());
spec.markAsFinal(s0);
assertTrue(spec.acceptEmptyWord());
}
/**
* Test metody countTransitions.
*/
public final void testCountTransitions() {
NaiveAutomatonSpecification spec = new NaiveAutomatonSpecification();
//Test 1
assertEquals(spec.countTransitions(), 0);
//Test 2
State q0 = spec.addState();
State q1 = spec.addState();
State q2 = spec.addState();
spec.addTransition(q0, q1, new CharTransitionLabel('a'));
spec.addTransition(q1, q2, new CharTransitionLabel('b'));
spec.markAsInitial(q0);
spec.markAsFinal(q2);
assertEquals(spec.countTransitions(), 2);
//Test 3
spec.addTransition(q2, q0, new CharTransitionLabel('c'));
assertEquals(spec.countTransitions(), 3);
//Test 4
spec.addTransition(q0, q2, new CharTransitionLabel('d'));
assertEquals(spec.countTransitions(), 4);
//Test 5
spec.addTransition(q2, q2, new CharTransitionLabel('d'));
assertEquals(spec.countTransitions(), 5);
}
/**
* Test metody makeEmptyStringAutomaton.
*/
public final void testmakeEmptyStringAutomaton() {
AutomatonSpecification automaton1 = new NaiveAutomatonSpecification();
automaton1.makeEmptyStringAutomaton();
AutomatonByRecursion angle = new AutomatonByRecursion(automaton1);
assertFalse(angle.accepts("qqqqqq"));
assertTrue(angle.accepts(""));
assertFalse(angle.accepts("x"));
assertFalse(angle.accepts("qwertyuiopasdfghjklzxcvbnm1234567890"));
assertFalse(angle.accepts(" "));
}
/**
* Testy dla metody addTransitionSequence().
*/
public final void testAddTransitionSequence() {
// Tworzymy automat do testów
AutomatonSpecification spec = new NaiveAutomatonSpecification();
// Proste testy ilości stanów i przejść
// Pusty ciąg przejść
State s0 = spec.addState();
spec.markAsInitial(s0);
spec.addTransitionSequence(s0, "");
assertEquals(0, spec.countTransitions());
assertEquals(1, spec.countStates());
// Ciąg przejść składający się z jednego znaku
spec = new NaiveAutomatonSpecification();
s0 = spec.addState();
spec.markAsInitial(s0);
spec.addTransitionSequence(s0, "a");
assertEquals(1, spec.countTransitions());
assertEquals(2, spec.countStates());
// Ciąg przejść składający się z jednego znaku
// i dodanie stanu na podstawie tego co zwróciła
// metoda addTransitionSequence()
spec = new NaiveAutomatonSpecification();
s0 = spec.addState();
spec.markAsInitial(s0);
State s1 = spec.addTransitionSequence(s0, "a");
spec.addTransition(s1, new CharTransitionLabel('b'));
assertEquals(2, spec.countTransitions());
assertEquals(3, spec.countStates());
// Ciąg przejść składający się z takich samych znaków
spec = new NaiveAutomatonSpecification();
s0 = spec.addState();
spec.markAsInitial(s0);
spec.addTransitionSequence(s0, "aa");
assertEquals(2, spec.countTransitions());
assertEquals(3, spec.countStates());
// Ciąg przejść składający się z różnych znaków
spec = new NaiveAutomatonSpecification();
s0 = spec.addState();
spec.markAsInitial(s0);
spec.addTransitionSequence(s0, "abc");
assertEquals(3, spec.countTransitions());
assertEquals(4, spec.countStates());
// Sprawdzamy czy przejścia mają odpowiednie oznaczenia oraz
// akceptują odpowiednie znaki, dla ciągu "abc"
State s;
List<OutgoingTransition> sOuts;
// Dla jasności pobieramy stan początkowy automatu
s = spec.getInitialState();
// Sprawdzamy możliwe przejścia ze stanu początkowego,
// sprawdzamy ich ilość, oznaczenia oraz jakie znaki akceptują
// (oczekujemy a)
sOuts = spec.allOutgoingTransitions(s);
assertEquals(1, sOuts.size());
assertEquals('a', ((CharTransitionLabel) sOuts.get(0).getTransitionLabel()).getChar());
assertTrue(((CharTransitionLabel) sOuts.get(0).getTransitionLabel())
.canAcceptCharacter('a'));
assertFalse(((CharTransitionLabel) sOuts.get(0).getTransitionLabel())
.canAcceptCharacter('c'));
// Kolejne przejście (oczekujemy b)
s = sOuts.get(0).getTargetState();
sOuts = spec.allOutgoingTransitions(s);
assertEquals(1, sOuts.size());
assertEquals('b', ((CharTransitionLabel) sOuts.get(0).getTransitionLabel()).getChar());
assertTrue(((CharTransitionLabel) sOuts.get(0).getTransitionLabel())
.canAcceptCharacter('b'));
assertFalse(((CharTransitionLabel) sOuts.get(0).getTransitionLabel())
.canAcceptCharacter('a'));
assertFalse(((CharTransitionLabel) sOuts.get(0).getTransitionLabel())
.canAcceptCharacter('c'));
// Kolejne przejście (oczekujemy c)
s = sOuts.get(0).getTargetState();
sOuts = spec.allOutgoingTransitions(s);
assertEquals(1, sOuts.size());
assertEquals('c', ((CharTransitionLabel) sOuts.get(0).getTransitionLabel()).getChar());
assertTrue(((CharTransitionLabel) sOuts.get(0).getTransitionLabel())
.canAcceptCharacter('c'));
assertFalse(((CharTransitionLabel) sOuts.get(0).getTransitionLabel())
.canAcceptCharacter('a'));
}
/**
* Test metody addBranch(). Automat o 4 stanach.
*/
public final void testAddBranchWithFourStates() {
// Budowanie automatu o 4 stanach.
AutomatonSpecification spec = new NaiveAutomatonSpecification();
State s0 = spec.addState();
spec.markAsInitial(s0);
List<TransitionLabel> transitions =
Arrays.<TransitionLabel>asList(
new CharTransitionLabel('a'),
new CharTransitionLabel('b'),
new CharTransitionLabel('c'));
State s3 = spec.addBranch(s0, transitions);
spec.markAsFinal(s3);
//testowanie
State r0 = spec.getInitialState();
List<OutgoingTransition> r0Outs = spec.allOutgoingTransitions(r0);
assertEquals(r0Outs.size(), 1); //sprawdza ze jest tylko jedno przejscie
assertTrue(((CharTransitionLabel) r0Outs.get(0).getTransitionLabel()).getChar() == 'a');
assertFalse(((CharTransitionLabel) r0Outs.get(0).getTransitionLabel()).getChar() == 'b');
assertFalse(((CharTransitionLabel) r0Outs.get(0).getTransitionLabel()).getChar() == 'c');
assertFalse(((CharTransitionLabel) r0Outs.get(0).getTransitionLabel()).canBeEpsilon());
State r1 = r0Outs.get(0).getTargetState();
List<OutgoingTransition> r1Outs = spec.allOutgoingTransitions(r1);
assertEquals(r1Outs.size(), 1); //sprawdza ze jest tylko jedno przejscie
assertTrue(((CharTransitionLabel) r1Outs.get(0).getTransitionLabel()).getChar() == 'b');
assertFalse(((CharTransitionLabel) r1Outs.get(0).getTransitionLabel()).getChar() == 'a');
assertFalse(((CharTransitionLabel) r1Outs.get(0).getTransitionLabel()).getChar() == 'c');
assertFalse(((CharTransitionLabel) r1Outs.get(0).getTransitionLabel()).canBeEpsilon());
State r2 = r1Outs.get(0).getTargetState();
List<OutgoingTransition> r2Outs = spec.allOutgoingTransitions(r2);
assertEquals(r2Outs.size(), 1); //sprawdza ze jest tylko jedno przejscie
assertTrue(((CharTransitionLabel) r2Outs.get(0).getTransitionLabel()).getChar() == 'c');
assertFalse(((CharTransitionLabel) r2Outs.get(0).getTransitionLabel()).getChar() == 'a');
assertFalse(((CharTransitionLabel) r2Outs.get(0).getTransitionLabel()).getChar() == 'b');
assertFalse(((CharTransitionLabel) r2Outs.get(0).getTransitionLabel()).canBeEpsilon());
State r3 = r2Outs.get(0).getTargetState();
assertFalse(spec.isFinal(r2));
assertTrue(spec.isFinal(r3));
assertSame(r0, spec.getInitialState());
assertNotSame(r0, r1);
assertNotSame(r1, r2);
assertNotSame(r2, r3);
List<State> states = spec.allStates();
assertEquals(states.size(), 4);
}
/**
* Test metody addBranch(). Automat o 1 stanie.
*/
public final void testAddBranchWithOneStates() {
// Budowanie automatu o 1 stanie.
AutomatonSpecification spec2 = new NaiveAutomatonSpecification();
State st0 = spec2.addState();
spec2.markAsInitial(st0);
List<TransitionLabel> transitions2 =
Arrays.<TransitionLabel>asList();
State st1 = spec2.addBranch(st0, transitions2);
spec2.markAsFinal(st0);
//testowanie
State rr0 = spec2.getInitialState();
List<OutgoingTransition> r0Outs2 = spec2.allOutgoingTransitions(rr0);
assertEquals(r0Outs2.size(), 0);
assertTrue(spec2.isFinal(st1));
assertSame(st1, spec2.getInitialState());
}
/**
* Testuje działanie metody toString().
*/
public final void testToString() {
/**
* Pozwala na wygenerowanie tekstu "oszukanego" automatu
* na podstawie stanów i krawędzi wprowadzonych jako tekst.
* Imitacja działania metody toString() dla automatu.
*/
class AutomatonString {
private String states, transitions, istates, fstates;
/**
* Ustala stany, przejścia, stan początkowy oraz stany końcowe
*/
public AutomatonString(String states, String transitions,
String istates, String fstates) {
this.states = states;
this.transitions = transitions;
this.istates = istates;
this.fstates = fstates;
}
/**
* Zwraca "oszukany" automat w postaci tekstowej.
*/
@Override
public String toString() {
StringBuffer str = new StringBuffer();
str.append("Automaton:");
str.append("\n-States: " + states);
if (states.length() > 0) {
str.append(" ");
}
str.append("\n-Transitions:\n");
if (transitions.length() > 0) {
str.append(" " + transitions.replaceAll(",", "\n "));
str.append("\n");
}
str.append("-Initial state: " + istates);
str.append("\n-Final states: " + fstates);
if (fstates.length() > 0) {
str.append(" ");
}
return str.toString();
}
}
// Pierwszy testowy automat:
// Jeden stan z krawędzią
NaiveAutomatonSpecification ta1 = new NaiveAutomatonSpecification();
State ta1s0 = ta1.addState();
ta1.addTransition(ta1s0, ta1s0, new CharTransitionLabel('a'));
ta1.markAsInitial(ta1s0);
ta1.markAsFinal(ta1s0);
AutomatonString str;
str = new AutomatonString("q0", "q0 -a-> q0", "q0", "q0");
assertEquals(str.toString(), ta1.toString());
// Drugi testowy automat:
// Dwa stany, krawędzie jak w przypadku NFA
NaiveAutomatonSpecification ta2 = new NaiveAutomatonSpecification();
State ta2s0 = ta2.addState();
State ta2s1 = ta2.addState();
ta2.addTransition(ta2s0, ta2s0, new CharTransitionLabel('a'));
ta2.addTransition(ta2s0, ta2s1, new CharTransitionLabel('a'));
ta2.markAsInitial(ta2s0);
ta2.markAsFinal(ta2s0);
ta2.markAsFinal(ta2s1);
String transitions = "q0 -a-> q0,q0 -a-> q1";
str = new AutomatonString("q0 q1", transitions, "q0", "q0 q1");
assertEquals(str.toString(), ta2.toString());
// Trzeci testowy automat:
// Dwa stany, dwa różne rodzaje krawędzi
NaiveAutomatonSpecification ta3 = new NaiveAutomatonSpecification();
State ta3s0 = ta3.addState();
State ta3s1 = ta3.addState();
ta3.addTransition(ta3s0, ta3s0, new CharTransitionLabel('a'));
ta3.addTransition(ta3s0, ta3s1, new CharTransitionLabel('b'));
ta3.addTransition(ta3s1, ta3s1, new CharTransitionLabel('a'));
ta3.addTransition(ta3s1, ta3s1, new CharTransitionLabel('b'));
ta3.markAsInitial(ta3s0);
ta3.markAsFinal(ta3s1);
transitions = "q0 -a-> q0,q0 -b-> q1,q1 -a-> q1,q1 -b-> q1";
str = new AutomatonString("q0 q1", transitions, "q0", "q1");
assertEquals(str.toString(), ta3.toString());
// Czwarty testowy automat:
// sprawdzamy co jest zwracane dla "pustej" instancji klasy automatu
NaiveAutomatonSpecification ta4 = new NaiveAutomatonSpecification();
str = new AutomatonString("", "", "", "");
assertEquals(str.toString(), ta4.toString());
// Piąty testowy automat:
// Brak stanów początkowych i końcowych
NaiveAutomatonSpecification ta5 = new NaiveAutomatonSpecification();
State ta5s0 = ta5.addState();
ta5.addTransition(ta5s0, ta5s0, new CharTransitionLabel('a'));
str = new AutomatonString("q0", "q0 -a-> q0", "", "");
assertEquals(str.toString(), ta5.toString());
}
/**
* Klasa pomocnicza do testów funkcji getDotGraph().
*/
class FakeDotGraphGenerator {
private String states, transitions, begin, ends;
private boolean isBeginTheEnd;
public FakeDotGraphGenerator(String states, String transitions,
String begin, String ends, boolean isBeginTheEnd) {
this.states = states;
this.transitions = transitions;
this.begin = begin;
this.ends = ends;
this.isBeginTheEnd = isBeginTheEnd;
}
/**
* Zwraca żądany przez testera graf w postaci String'a.
*/
@Override
public String toString() {
//Poczatek
StringBuffer dotGraphString = new StringBuffer();
dotGraphString.append("digraph finite_state_machine {\n rankdir=LR;\n"
+ " size=\"8,5\"\n node [style=filled fillcolor=\"#00ff005f\""
+ " shape = ");
if (isBeginTheEnd)
dotGraphString.append("double");
dotGraphString.append("circle];\n \"State #" + begin + "\";\n"
+ " node [shape = doublecircle style=filled "
+ "fillcolor=\"#00000000\"];\n ");
//Stany końcowe
String[] endStates = ends.split(" ");
for (String state : endStates) {
dotGraphString.append("\"State #" + state + "\" ");
}
dotGraphString.append(";\n node [shape = circle];\n");
//Przejścia
for (String transition : transitions.split(" ")) {
String[] splitedTransition = transition.split("-");
dotGraphString.append(" \"State #" + splitedTransition[0] + "\"");
dotGraphString.append(" -> \"State #" + splitedTransition[2] + "\"");
if ((splitedTransition[1].length() > 2) && (splitedTransition[1].contains(",")
&& (!(splitedTransition[1].matches("[*,*]"))))) {
String[] transitionLabel = splitedTransition[1].split(",");
dotGraphString.append(" [ label = \"" + transitionLabel[0]);
for (int i = 1; i < transitionLabel.length; i++) {
dotGraphString.append(", " + transitionLabel[i]);
}
dotGraphString.append("\" ]");
} else {
dotGraphString.append(" [ label = \"" + splitedTransition[1] + "\" ]");
}
dotGraphString.append(";\n");
}
//Koniec
dotGraphString.append("\n}\n");
return dotGraphString.toString();
}
boolean isItProper(String dotGraphFromAutomaton) {
String fakeDotGraph = this.toString();
//Pierwszy krok testu - porównanie ich długości
if (dotGraphFromAutomaton.length() != fakeDotGraph.length())
return false;
//Podział obu stringów na linie
String[] dotGraphTab = dotGraphFromAutomaton.split("\n");
String[] exampleOfDotGraphTab = fakeDotGraph.split("\n");
//Porównanie ilości linii w obu Stringach
if (dotGraphTab.length != exampleOfDotGraphTab.length)
return false;
//Porównanie 1: dokładnie ten sam porządek linii
for (int i = 0; i < 6; i++)
if (!dotGraphTab[i].equals(exampleOfDotGraphTab[i]))
return false;
//Porównanie 2: stany końcowe
int numberOfEndStates = ends.split(" ").length;
for (int i = 6; i < 6 + numberOfEndStates; i++) {
boolean doThisLineExist = false;
for (int j = 6; j < 6 + numberOfEndStates; j++) {
if (exampleOfDotGraphTab[i].equals(dotGraphTab[j])) {
doThisLineExist = true;
break;
}
}
if (!doThisLineExist)
return false;
}
//Porównanie 3: linie mogą różnić się kolejnością
for (int i = 6 + numberOfEndStates; i < exampleOfDotGraphTab.length; i++) {
boolean doThisLineExist = false;
for (int j = 6 + numberOfEndStates; j < exampleOfDotGraphTab.length; j++) {
if (exampleOfDotGraphTab[i].equals(dotGraphTab[j])) {
doThisLineExist = true;
break;
}
}
if (!doThisLineExist)
return false;
}
return true;
}
}
/**
* Pierwszy test metody getDotGraph(). Prosty automat. Akceptuje tylko słowo puste
* oraz słowo "one".
*/
public final void testGetDotGraph0EasyAutomaton() {
AutomatonSpecification testAutomaton = new NotNaiveAutomatonSpecification();
State qBegin = testAutomaton.addState();
State qEnd = testAutomaton.addTransitionSequence(qBegin, "one");
State qMore = testAutomaton.addTransition(qEnd, new CharTransitionLabel('1'));
testAutomaton.addTransition(qEnd, qMore, new CharTransitionLabel('2'));
testAutomaton.markAsInitial(qBegin);
testAutomaton.markAsFinal(qBegin);
testAutomaton.markAsFinal(qEnd);
//Tworzenie obu Stringów: przez toDotGraph() i "kłamliwą" funkcję
String dotGraph = testAutomaton.getDotGraph();
FakeDotGraphGenerator exampleOfDotGraph = new FakeDotGraphGenerator("0 1 2 3 4", "0-o-1"
+ " 1-n-2 2-e-3 3-1,2-4", "0", "0 3", true);
assertTrue(exampleOfDotGraph.isItProper(dotGraph));
}
/**
* Drugi test metody getDotGraph(). Ze wszystkich słów nad alfabetem {a,b,c} zawierających
* parzystą liczbę wystąpień podciągu "ab" i w których liczba wystąpień litery c jest
* podzielna przez trzy.
*/
public final void testGetDotGraph1BigAutomaton() {
AutomatonSpecification testAutomaton = new NotNaiveAutomatonSpecification();
State qBegin = testAutomaton.addState();
State qCMod3Is1 = testAutomaton.addTransition(qBegin, new CharTransitionLabel('c'));
State qCMod3Is2 = testAutomaton.addTransition(qCMod3Is1, new CharTransitionLabel('c'));
State qAC0 = testAutomaton.addTransition(qBegin, new CharTransitionLabel('a'));
State qACMod3Is1 = testAutomaton.addTransition(qCMod3Is1, new CharTransitionLabel('a'));
State qACMod3Is2 = testAutomaton.addTransition(qCMod3Is2, new CharTransitionLabel('a'));
State qNpC0 = testAutomaton.addTransition(qAC0, new CharTransitionLabel('b'));
State qNpCMod3Is1 = testAutomaton.addTransition(qNpC0, new CharTransitionLabel('c'));
State qNpCMod3Is2 = testAutomaton.addTransition(qNpCMod3Is1, new CharTransitionLabel('c'));
State qNpAC0 = testAutomaton.addTransition(qNpC0, new CharTransitionLabel('a'));
State qNpACMod3Is1 = testAutomaton.addTransition(qNpCMod3Is1, new CharTransitionLabel('a'));
State qNpACMod3Is2 = testAutomaton.addTransition(qNpCMod3Is2, new CharTransitionLabel('a'));
testAutomaton.addLoop(qAC0, new CharTransitionLabel('a'));
testAutomaton.addLoop(qACMod3Is1, new CharTransitionLabel('a'));
testAutomaton.addLoop(qACMod3Is2, new CharTransitionLabel('a'));
testAutomaton.addLoop(qNpAC0, new CharTransitionLabel('a'));
testAutomaton.addLoop(qNpACMod3Is1, new CharTransitionLabel('a'));
testAutomaton.addLoop(qNpACMod3Is2, new CharTransitionLabel('a'));
testAutomaton.addLoop(qBegin, new CharTransitionLabel('b'));
testAutomaton.addLoop(qCMod3Is1, new CharTransitionLabel('b'));
testAutomaton.addLoop(qCMod3Is2, new CharTransitionLabel('b'));
testAutomaton.addLoop(qNpC0, new CharTransitionLabel('b'));
testAutomaton.addLoop(qNpCMod3Is1, new CharTransitionLabel('b'));
testAutomaton.addLoop(qNpCMod3Is2, new CharTransitionLabel('b'));
testAutomaton.addTransition(qACMod3Is1, qNpCMod3Is1, new CharTransitionLabel('b'));
testAutomaton.addTransition(qACMod3Is2, qNpCMod3Is2, new CharTransitionLabel('b'));
testAutomaton.addTransition(qNpAC0, qBegin, new CharTransitionLabel('b'));
testAutomaton.addTransition(qNpACMod3Is1, qCMod3Is1, new CharTransitionLabel('b'));
testAutomaton.addTransition(qNpACMod3Is2, qCMod3Is2, new CharTransitionLabel('b'));
testAutomaton.addTransition(qCMod3Is2, qBegin, new CharTransitionLabel('c'));
testAutomaton.addTransition(qAC0, qCMod3Is1, new CharTransitionLabel('c'));
testAutomaton.addTransition(qACMod3Is1, qCMod3Is2, new CharTransitionLabel('c'));
testAutomaton.addTransition(qACMod3Is2, qBegin, new CharTransitionLabel('c'));
testAutomaton.addTransition(qNpCMod3Is2, qNpC0, new CharTransitionLabel('c'));
testAutomaton.addTransition(qNpAC0, qNpCMod3Is1, new CharTransitionLabel('c'));
testAutomaton.addTransition(qNpACMod3Is1, qNpCMod3Is2, new CharTransitionLabel('c'));
testAutomaton.addTransition(qNpACMod3Is2, qNpC0, new CharTransitionLabel('c'));
testAutomaton.markAsInitial(qBegin);
testAutomaton.markAsFinal(qBegin);
//Tworzenie obu Stringów: przez toDotGraph() i "kłamliwą" funkcję
String dotGraph = testAutomaton.getDotGraph();
FakeDotGraphGenerator exampleOfDotGraph = new FakeDotGraphGenerator("0 1 2 3 4 5 6 7 8 9"
+ " 10 11", "0-a-3 0-b-0 0-c-1 1-a-4 1-b-1 1-c-2 2-a-5 2-b-2 2-c-0 3-a-3 3-b-6"
+ " 3-c-1 4-a-4 4-b-7 4-c-2 5-a-5 5-b-8 5-c-0 6-a-9 6-b-6 6-c-7 7-a-10 7-b-7"
+ " 7-c-8 8-a-11 8-b-8 8-c-6 9-a-9 9-b-0 9-c-7 10-a-10 10-b-1 10-c-8 11-a-11"
+ " 11-b-2 11-c-6", "0", "0", true);
assertTrue(exampleOfDotGraph.isItProper(dotGraph));
}
/**
* Pierwszy test metody getDotGraph(). Automat sprawdzający poprawność działania funkcji
* dla automatów zawierających przejścia po dowolnym znaku.
*/
public final void testGetDotGraph2AutomatonWithAnyTransitionLabel() {
AutomatonSpecification testAutomaton = new NaiveAutomatonSpecification();
State qBegin = testAutomaton.addState();
State qEnd = testAutomaton.addTransition(qBegin, new AnyTransitionLabel());
testAutomaton.markAsInitial(qBegin);
testAutomaton.markAsFinal(qEnd);
//Tworzenie obu Stringów: przez toDotGraph() i "kłamliwą" funkcję
String dotGraph = testAutomaton.getDotGraph();
FakeDotGraphGenerator exampleOfDotGraph = new FakeDotGraphGenerator("0 1", "0-ANY-1", "0",
"1", false);
assertTrue(exampleOfDotGraph.isItProper(dotGraph));
}
/**
* Testuje działanie metody testPrefixChecker().
*/
public final void testPrefixChecker() {
AutomatonSpecification spec = new NaiveAutomatonSpecification();
State q0 = spec.addState();
State q1 = spec.addState();
State q2 = spec.addState();
State q3 = spec.addState();
State q4 = spec.addState();
State q5 = spec.addState();
spec.markAsInitial(q0);
spec.markAsFinal(q3);
spec.addTransition(q0, q1, new CharTransitionLabel('a'));
spec.addTransition(q0, q1, new CharTransitionLabel('b'));
spec.addTransition(q0, q3, new CharTransitionLabel('c'));
spec.addTransition(q1, q3, new CharTransitionLabel('a'));
spec.addTransition(q1, q2, new CharTransitionLabel('b'));
spec.addTransition(q1, q2, new CharTransitionLabel('c'));
spec.addTransition(q2, q3, new CharTransitionLabel('a'));
spec.addLoop(q2, new CharTransitionLabel('b'));
spec.addTransition(q2, q5, new CharTransitionLabel('c'));
spec.addTransition(q3, q0, new CharTransitionLabel('a'));
spec.addTransition(q3, q0, new CharTransitionLabel('b'));
spec.addTransition(q3, q4, new CharTransitionLabel('c'));
// Stan 4 jest pułapką
spec.addLoop(q4, new CharTransitionLabel('a'));
spec.addLoop(q4, new CharTransitionLabel('b'));
spec.addLoop(q4, new CharTransitionLabel('c'));
// Stan 5 prowadzi tylko do stanu 4
spec.addLoop(q5, new CharTransitionLabel('a'));
spec.addTransition(q5, q4, new CharTransitionLabel('b'));
spec.addLoop(q5, new CharTransitionLabel('c'));
assertTrue(spec.prefixChecker(q0));
assertTrue(spec.prefixChecker(q1));
assertTrue(spec.prefixChecker(q2));
assertTrue(spec.prefixChecker(q3));
assertFalse(spec.prefixChecker(q4));
assertFalse(spec.prefixChecker(q5));
}
/**
* Testuje działanie metody checkPrefix().
* Bazuje bezpośrednio na teście metody prefixChecker()
*/
public final void testCheckPrefix() {
AutomatonSpecification spec = new NaiveAutomatonSpecification();
State q0 = spec.addState();
State q1 = spec.addState();
State q2 = spec.addState();
State q3 = spec.addState();
State q4 = spec.addState();
State q5 = spec.addState();
State q6 = spec.addState();
spec.markAsInitial(q0);
spec.markAsFinal(q3);
spec.addTransition(q0, q1, new CharTransitionLabel('a'));
spec.addTransition(q0, q1, new CharTransitionLabel('b'));
spec.addTransition(q0, q3, new CharTransitionLabel('c'));
spec.addTransition(q0, q6, new EpsilonTransitionLabel());
spec.addTransition(q1, q3, new CharTransitionLabel('a'));
spec.addTransition(q1, q2, new CharTransitionLabel('b'));
spec.addTransition(q1, q2, new CharTransitionLabel('c'));
spec.addTransition(q2, q3, new CharTransitionLabel('a'));
spec.addLoop(q2, new CharTransitionLabel('b'));
spec.addTransition(q2, q5, new CharTransitionLabel('c'));
spec.addTransition(q3, q0, new CharTransitionLabel('a'));
spec.addTransition(q3, q0, new CharTransitionLabel('b'));
spec.addTransition(q3, q4, new CharTransitionLabel('c'));
// Stan 4 jest pułapką
spec.addLoop(q4, new CharTransitionLabel('a'));
spec.addLoop(q4, new CharTransitionLabel('b'));
spec.addLoop(q4, new CharTransitionLabel('c'));
// Stan 5 prowadzi tylko do stanu 4
spec.addLoop(q5, new CharTransitionLabel('a'));
spec.addTransition(q5, q4, new CharTransitionLabel('b'));
spec.addLoop(q5, new CharTransitionLabel('c'));
spec.addTransition(q6, q3, new CharTransitionLabel('c'));
assertTrue(spec.checkPrefix("abbb"));
assertTrue(spec.checkPrefix("cacbab"));
assertTrue(spec.checkPrefix("bbaabcaa"));
assertTrue(spec.checkPrefix("cababbc"));
assertTrue(spec.checkPrefix("c"));
assertTrue(spec.checkPrefix("cbcbcbcbcbacbbbbaab"));
assertFalse(spec.checkPrefix("aacc"));
assertFalse(spec.checkPrefix("sdfcs"));
assertFalse(spec.checkPrefix("bcca"));
assertFalse(spec.checkPrefix("cc"));
assertFalse(spec.checkPrefix("abaabacac"));
assertFalse(spec.checkPrefix("caccb"));
assertFalse(spec.checkPrefix("bac"));
}
/**
*test automatu pustego.
*/
public final void testIsEmpty() {
AutomatonSpecification automat = new NaiveAutomatonSpecification();
assertTrue(automat.isEmpty());
}
/**
*test automatu niepustego.
*/
public final void testIsEmptyforNotEmpty() {
AutomatonSpecification automat = new NaiveAutomatonSpecification();
State s1 = automat.addState();
assertFalse(automat.isEmpty());
}
/**
* Test wariacji metody addTransition, w której tworzyony jest nowy stan.
*/
public final void testAddTransitionWithAddingState() {
AutomatonSpecification automat = new NaiveAutomatonSpecification();
State s0 = automat.addState();
//Sprawdzam ilość stanów oraz przejść w automacie przed zastosowaniem metody.
int numberOfStates1 = automat.countStates();
int numberOfTransitions1 = automat.countTransitions();
//Dodaję nowy stan i przejście używając metody addTransition i sprawdzam
//ponownie ilość stanów oraz przejść.
State s1 = automat.addTransition(s0, new CharTransitionLabel('a'));
int numberOfStates2 = automat.countStates();
int numberOfTransitions2 = automat.countTransitions();
//Sprawdzam, czy ilości stanów oraz przejsć nie są równe oraz czy ze stanu
//s0 da sie przejść do stanu s1.
assertFalse(numberOfStates1 == numberOfStates2);
assertFalse(numberOfTransitions1 == numberOfTransitions2);
assertTrue(automat.allOutgoingTransitions(s0).get(0).getTargetState() == s1);
}
/**
* test metody insert: testuje zwykłe użycie.
*/
public final void testInsertSimpleTest() {
AutomatonSpecification firstAutomaton = new NaiveAutomatonSpecification();
State firstState = firstAutomaton.addState();
firstAutomaton.markAsInitial(firstState);
AutomatonSpecification second = new NaiveAutomatonSpecification();
String fromString = "Automaton:\n-States: q0 q1 q2 q3 q4 \n-Transitions:\n q0 -a-> "
+ "q1\n q1 -a-> q0\n q2 -epsilon-> q4"
+ "\n q3 -ANY-> q4\n-Initial state: q0\n-Final states: q1 ";
try {
second.fromString(fromString);
} catch (Exception e) {
fail("Nie udało się stworzyć automatu.");
}
firstAutomaton.insert(firstState, second);
assertTrue(fromString.equals(firstAutomaton.toString()));
}
/**
* test funkcji insert: dodaje do automatu pusty automat.
*/
public final void testInsertEmptyAutomaton() {
AutomatonSpecification base = new NaiveAutomatonSpecification();
State s1 = base.addState();
State s2 = base.addState();
State s3 = base.addState();
base.markAsInitial(s1);
base.markAsFinal(s1);
base.markAsFinal(s3);
base.addTransition(s1, s3, new CharTransitionLabel('a'));
base.addTransition(s2, s1, new CharTransitionLabel('b'));
base.addTransition(s2, s1, new CharTransitionLabel('c'));
AutomatonSpecification empty = new NaiveAutomatonSpecification();
String automatonString = base.toString();
base.insert(s2, empty);
assertEquals(automatonString, base.toString());
}
/**
* testuje metodę insert, ale dodaje automat bez jakichkolwiek przejść.
*/
public final void testInsertNoTransitions() {
final int automatonSize = 300;
AutomatonSpecification base = new NaiveAutomatonSpecification();
for (int iter = 0; iter < 99; ++iter) {
base.addState();
}
AutomatonSpecification secondAutomaton = new NaiveAutomatonSpecification();
State initial = secondAutomaton.addState();
secondAutomaton.markAsInitial(initial);
for (int iter = 0; iter < 201; ++iter) {
secondAutomaton.addState();
}
base.insert(initial, secondAutomaton);
assertEquals(base.countTransitions(), 0);
assertEquals(base.countStates(), automatonSize);
}
/**
* Testuje działanie metody clone(). Test 1.
*/
public final void testCloneMiniAutomaton() {
AutomatonSpecification mini = new NaiveAutomatonSpecification();
State q0 = mini.addState();
State q1 = mini.addState();
State q2 = mini.addState();
mini.markAsInitial(q0);
mini.markAsFinal(q2);
mini.addTransition(q0, q1, new CharTransitionLabel('a'));
mini.addTransition(q1, q2, new CharTransitionLabel('b'));
AutomatonSpecification clon = mini.clone();
assertEquals(mini.countStates(), clon.countStates());
assertEquals(mini.countTransitions(), clon.countTransitions());
AutomatonByStack mini2 = new AutomatonByStack(mini);
AutomatonByStack clon2 = new AutomatonByStack(clon);
assertEquals(clon2.accepts("ab"), mini2.accepts("ab"));
assertEquals(clon2.accepts("aa"), mini2.accepts("aa"));
assertEquals(clon2.accepts(""), mini2.accepts(""));
}
/**
* Testuje działanie metody clone(). Test 2.
*/
public final void testCloneMini2Automaton() {
AutomatonSpecification mini = new NaiveAutomatonSpecification();
State q0 = mini.addState();
State q1 = mini.addState();
mini.markAsInitial(q0);
mini.markAsFinal(q1);
mini.addTransition(q0, q1, new CharTransitionLabel('a'));
mini.addLoop(q1, new CharTransitionLabel('a'));
mini.addLoop(q1, new CharTransitionLabel('b'));
AutomatonSpecification clon = mini.clone();
assertEquals(mini.countStates(), clon.countStates());
assertEquals(mini.countTransitions(), clon.countTransitions());
AutomatonByStack mini2 = new AutomatonByStack(mini);
AutomatonByStack clon2 = new AutomatonByStack(clon);
assertEquals(clon2.accepts("a"), mini2.accepts("a"));
assertEquals(clon2.accepts("aa"), mini2.accepts("aa"));
assertEquals(clon2.accepts("aaa"), mini2.accepts("aaa"));
assertEquals(clon2.accepts("ab"), mini2.accepts("ab"));
assertEquals(clon2.accepts("aab"), mini2.accepts("aab"));
assertEquals(clon2.accepts("aba"), mini2.accepts("aba"));
assertEquals(clon2.accepts("ababa"), mini2.accepts("ababa"));
assertEquals(clon2.accepts(""), mini2.accepts(""));
assertEquals(clon2.accepts("b"), mini2.accepts("b"));
assertEquals(clon2.accepts("bbba"), mini2.accepts("bbba"));
assertEquals(clon2.accepts("cos"), mini2.accepts("cos"));
}
/**
* Testuje działanie metody clone(). Test 3.
*/
public final void testCloneMini3Automaton() {
AutomatonSpecification mini = new NaiveAutomatonSpecification();
State q0 = mini.addState();
State q1 = mini.addState();
State q2 = mini.addState();
State q3 = mini.addState();
mini.addTransition(q0, q1, new CharTransitionLabel('a'));
mini.addTransition(q1, q2, new CharTransitionLabel('b'));
mini.addTransition(q1, q3, new CharTransitionLabel('b'));
mini.markAsInitial(q0);
mini.markAsFinal(q2);
AutomatonSpecification clon = mini.clone();
assertEquals(mini.countStates(), clon.countStates());
assertEquals(mini.countTransitions(), clon.countTransitions());
AutomatonByStack mini2 = new AutomatonByStack(mini);
AutomatonByStack clon2 = new AutomatonByStack(clon);
assertEquals(clon2.accepts("ab"), mini2.accepts("ab"));
assertEquals(clon2.accepts("bb"), mini2.accepts("bb"));
}
/**
* Testuje działanie metody clone(). Test 4.
*/
public final void testCloneMini4Automaton() {
AutomatonSpecification mini = new NaiveAutomatonSpecification();
State q0 = mini.addState();
State q1 = mini.addState();
State q2 = mini.addState();
State q3 = mini.addState();
mini.addTransition(q0, q1, new CharTransitionLabel('a'));
mini.addTransition(q1, q0, new CharTransitionLabel('b'));
mini.addTransition(q1, q2, new CharTransitionLabel('c'));
mini.addTransition(q2, q3, new CharTransitionLabel('a'));
mini.addTransition(q3, q2, new CharTransitionLabel('b'));
mini.markAsInitial(q0);
mini.markAsFinal(q3);
AutomatonSpecification clon = mini.clone();
assertEquals(mini.countStates(), clon.countStates());
assertEquals(mini.countTransitions(), clon.countTransitions());
AutomatonByStack mini2 = new AutomatonByStack(mini);
AutomatonByStack clon2 = new AutomatonByStack(clon);
assertEquals(clon2.accepts("aca"), mini2.accepts("aca"));
assertEquals(clon2.accepts("bc"), mini2.accepts("bc"));
assertEquals(clon2.accepts("bbc"), mini2.accepts("bbc"));
assertEquals(clon2.accepts("acabababa"), mini2.accepts("acabababa"));
assertEquals(clon2.accepts(""), mini2.accepts(""));
assertEquals(clon2.accepts("cc"), mini2.accepts("cc"));
assertEquals(clon2.accepts("bca"), mini2.accepts("bca"));
assertEquals(clon2.accepts("acc"), mini2.accepts("acc"));
}
/**
* Prosty test metody getEpsilonClosure(State).
*/
public final void testSimpleGetEpsilonClosure() {
// Automat z tylko jednym stanem (początkowy i końcowy).
// Tylko jedne możliwe przejście (czytanie znaku pustego
// i wracanie na ten sam stan).
NaiveAutomatonSpecification automat = new NaiveAutomatonSpecification();
// Nowy automat ma już stan początkowy i ustawiamy przejście.
automat.addTransition(automat.getInitialState(),
automat.getInitialState(),
new EpsilonTransitionLabel());
// Zaznaczamy stan początkowy jako końcowy.
automat.markAsFinal(automat.getInitialState());
Set<State> zbior = new HashSet<State>();
zbior.add(automat.getInitialState());
assertEquals(zbior,
automat.getEpsilonClosure(automat.getInitialState()));
}
/**
* Trudniejszy test metody getEpsilonClosure(State).
*/
public final void testHardGetEpsilonClosure() {
// Prosty automat z czterema stanami.
NaiveAutomatonSpecification automat = new NaiveAutomatonSpecification();
State s0, s1, s2, s3;
s0 = automat.getInitialState();
s1 = automat.addState();
s2 = automat.addState();
s3 = automat.addState();
automat.markAsFinal(s3);
// Dodajmy jakieś "normalne" przejścia.
automat.addTransition(s0, s1, new CharTransitionLabel('a'));
automat.addTransition(s0, s2, new CharTransitionLabel('b'));
automat.addTransition(s1, s3, new CharTransitionLabel('a'));
automat.addTransition(s1, s3, new CharTransitionLabel('b'));
automat.addTransition(s2, s1, new CharTransitionLabel('b'));
// Dodajemy epsilon przejścia.
automat.addTransition(s2, s3, new EpsilonTransitionLabel());
automat.addTransition(s3, s1, new EpsilonTransitionLabel());
automat.addTransition(s3, s0, new EpsilonTransitionLabel());
automat.addTransition(s0, s3, new EpsilonTransitionLabel());
Set<State> zbior = new HashSet<State>();
zbior.add(s1);
assertEquals(zbior, automat.getEpsilonClosure(s1));
zbior = automat.getEpsilonClosure(s1);
zbior.add(s0);
zbior.add(s1);
zbior.add(s2);
zbior.add(s3);
assertEquals(zbior, automat.getEpsilonClosure(s2));
// Tu jest pętla.
zbior = new HashSet<State>();
zbior.add(s0);
zbior.add(s1);
zbior.add(s3);
assertEquals(zbior, automat.getEpsilonClosure(s3));
}
/**
* Testuje metodę isNotEmpty.
*/
public final void testIsNotEmpty() {
NaiveAutomatonSpecification spec = new NaiveAutomatonSpecification();
assertFalse(spec.isNotEmpty());
State s0 = spec.addState();
State s1 = spec.addState();
State s2 = spec.addState();
assertFalse(spec.isNotEmpty());
spec.markAsInitial(s0);
spec.markAsFinal(s2);
assertFalse(spec.isNotEmpty());
spec.addTransition(s0, s1, new CharTransitionLabel('a'));
spec.addTransition(s0, s2, new CharTransitionLabel('b'));
spec.addTransition(s1, s2, new CharTransitionLabel('c'));
assertTrue(spec.isNotEmpty());
}
/**
* Test metody getEpsilonClosureWithContext.
*/
public final void testGetEpsilonClosureWithContext() {
NaiveAutomatonSpecification spec = new NaiveAutomatonSpecification();
State q0 = spec.addState();
State q1 = spec.addState();
State q2 = spec.addState();
State q3 = spec.addState();
State q4 = spec.addState();
spec.addTransition(q0, q1, new EpsilonTransitionLabel());
spec.addTransition(q1, q2, new EpsilonTransitionLabel());
spec.addTransition(q0, q3, new EndOfTextOrLineTransitionLabel());
spec.addTransition(q2, q4, new EndOfTextOrLineTransitionLabel());
List<State> expectedList = new ArrayList<State>();
expectedList.addAll(spec.allStates());
assertEquals(expectedList.size(),
spec.getEpsilonClosureWithContext(q0, "s", 1).size());
assertFalse(expectedList.size()
== spec.getEpsilonClosureWithContext(q1, "s", 1).size());
}
//Testy do nierozwiazanego jeszcze zadania (#223).
/**
* Test metody makeAutomatonFromScheme.
*/
/*
public final void testmakeAutomatonFromSimpleScheme () {
AutomatonSpecification spec = new NaiveAutomatonSpecification();
NondeterministicAutomatonByThompsonApproach automaton =
NondeterministicAutomatonByThompsonApproach(spec.makeAutomatonFromScheme("abncm"));
assertTrue(automaton.accepts("abbccccccc"));
assertTrue(automaton.accepts("abbbbbbb"));
assertTrue(automaton.accepts("ac"));
assertTrue(automaton.accepts("ab"));
assertTrue(automaton.accepts("abbbbc"));
assertTrue(automaton.accepts("abbbbcccccccccc"));
assertFalse(automaton.accepts("aaaabbbbc"));
assertFalse(automaton.accepts("abc"));
assertFalse(automaton.accepts("abbbccc"));
assertFalse(automaton.accepts(""));
assertFalse(automaton.accepts("aaaabbbbcddd"));
assertFalse(automaton.accepts("aaccccbbbbb"));
assertFalse(automaton.accepts("abccd"));
}
*/
/**
* Test metody makeAutomatonFromScheme ciekawszego schematu.
*/
/*
public final void testmakeAutomatonFromScheme () {
AutomatonSpecification spec = new NaiveAutomatonSpecification();
NondeterministicAutomatonByThompsonApproach automaton =
NondeterministicAutomatonByThompsonApproach
(spec.makeAutomatonFromScheme("anbcdmefgz"));
assertTrue(automaton.accepts("bcdefgg"));
assertTrue(automaton.accepts("abcdefg"));
assertTrue(automaton.accepts("aaaabcdddefgg"));
assertTrue(automaton.accepts("aabcefg"));
assertTrue(automaton.accepts("aaa"));
assertTrue(automaton.accepts("ab"));
assertTrue(automaton.accepts("abbbbc"));
assertTrue(automaton.accepts("abbbbc"));
assertFalse(automaton.accepts(""));
assertFalse(automaton.accepts("bcdf"));
assertFalse(automaton.accepts("aabcddefggg"));
assertFalse(automaton.accepts("bcddefgg"));
}
*/
/**
* Test metody makeAutomatonFromScheme ciekawszego schematu.
*/
/*
public final void testmakeAutomatonFromScheme2 () {
AutomatonSpecification spec = new NaiveAutomatonSpecification();
NondeterministicAutomatonByThompsonApproach automaton =
NondeterministicAutomatonByThompsonApproach
(spec.makeAutomatonFromScheme("anbcdmeofgphirjsklt"));
assertTrue(automaton.accepts("abcddeeefgggghiiiiijjjjjjjkllllllllll"));
assertTrue(automaton.accepts("bcdddddddddeefggghiiiiijjjjklllllll"));
assertTrue(automaton.accepts("aaaaaaabcdeeefgghiiiijjjjjjjjjjjjjk"));
assertTrue(automaton.accepts("aaaabcdddeefhiiiiiiiiijkllllll"));
assertFalse(automaton.accepts(""));
assertFalse(automaton.accepts("abcdefghijkl"));
assertFalse(automaton.accepts("bcfhk"));
assertFalse(automaton.accepts("aabcccddeeefgghiiijjjjkll"));
}
*/
/**
* Test metody maxWordLength().
*/
public final void testMaxWordLength() {
NaiveAutomatonSpecification spec = new NaiveAutomatonSpecification();
//test 1 - brak stanow i przejsc
assertEquals(spec.maxWordLength(), -1);
//test 1.1 - brak przejsc 3 stany
State q0 = spec.addState();
State q1 = spec.addState();
State q2 = spec.addState();
spec.markAsInitial(q0);
spec.markAsFinal(q2);
assertEquals(spec.maxWordLength(), -1);
//test 2 - 3 stany 1 przejscie brak polaczenia z koncowym
spec.addTransition(q0, q1, new CharTransitionLabel('a'));
assertEquals(spec.maxWordLength(), -1);
//test2.1 - normalny na 3 stanach z pojedynczymi przejsciami
spec.addTransition(q1, q2, new CharTransitionLabel('b'));
assertEquals(spec.maxWordLength(), 2);
//test 3 - pętla w ramach jednego stanu.
NaiveAutomatonSpecification specLoop = new NaiveAutomatonSpecification();
State loop = specLoop.addState();
specLoop.markAsInitial(loop);
specLoop.markAsFinal(loop);
specLoop.addLoop(loop, new CharTransitionLabel('c'));
assertEquals(specLoop.maxWordLength(), -2);
//test 4 same epsilon przejścia
NaiveAutomatonSpecification spec2 = new NaiveAutomatonSpecification();
State q7 = spec2.addState();
State q8 = spec2.addState();
State q9 = spec2.addState();
spec2.markAsInitial(q7);
spec2.markAsFinal(q9);
spec2.addTransition(q7, q8, new EpsilonTransitionLabel());
spec2.addTransition(q8, q9, new EpsilonTransitionLabel());
assertEquals(spec2.maxWordLength(), 0);
//test 4.1 - 2 epsilon i 2 normalne
State q10 = spec2.addState();
State q11 = spec2.addState();
spec2.markAsFinal(q11);
spec2.addTransition(q9, q10, new CharTransitionLabel('a'));
spec2.addTransition(q10, q11, new CharTransitionLabel('b'));
assertEquals(spec2.maxWordLength(), 2);
//test 4.2 - droga z epsilon przejsciami wiedzie przez wiecej stanów
//wiec liczac epsilony jest dłuzsza.
State q12 = spec2.addState();
State q13 = spec2.addState();
spec2.addTransition(q9, q12, new EpsilonTransitionLabel());
spec2.addTransition(q12, q13, new EpsilonTransitionLabel());
spec2.addTransition(q13, q11, new EpsilonTransitionLabel());
assertEquals(spec2.maxWordLength(), 2);
//test 6 jedna z galezi automatu wysuwa się dalej niz stan koncowy.
NaiveAutomatonSpecification spec4 = new NaiveAutomatonSpecification();
State q17 = spec4.addState();
State q18 = spec4.addState();
State q19 = spec4.addState();
State q20 = spec4.addState();
State q21 = spec4.addState();
State q22 = spec4.addState();
spec4.markAsInitial(q17);
spec4.markAsFinal(q18);
spec4.addTransition(q17, q18, new CharTransitionLabel('a'));
spec4.addTransition(q17, q19, new CharTransitionLabel('b'));
spec4.addTransition(q19, q20, new CharTransitionLabel('a'));
spec4.addTransition(q20, q21, new CharTransitionLabel('b'));
spec4.addTransition(q21, q22, new CharTransitionLabel('a'));
assertEquals(spec4.maxWordLength(), 1);
}
/**
* Test metody testUnmark.
*/
public final void testUnmark() {
final AutomatonSpecification spec = new NaiveAutomatonSpecification();
//Test 1
State q0a = spec.addState();
State q1a = spec.addState();
spec.addTransition(q1a, q0a, new CharTransitionLabel(' '));
spec.markAsFinal(q1a);
spec.markAsInitial(q0a);
spec.unmarkAsFinalState(q1a);
assertFalse(spec.isFinal(q1a));
//test 2
State q0b = spec.addState();
State q1b = spec.addState();
spec.addTransition(q1b, q0b, new CharTransitionLabel(' '));
spec.markAsFinal(q0b);
spec.markAsInitial(q1b);
spec.unmarkAsFinalState(q1b);
assertTrue(spec.isFinal(q0b));
//test 3
State q0c = spec.addState();
State q1c = spec.addState();
State q2c = spec.addState();
State q3c = spec.addState();
State q4c = spec.addState();
State q5c = spec.addState();
spec.addTransition(q0c, q2c, new CharTransitionLabel('a'));
spec.addTransition(q3c, q4c, new CharTransitionLabel('a'));
spec.addTransition(q1c, q5c, new CharTransitionLabel('a'));
spec.markAsFinal(q5c);
spec.markAsInitial(q0c);
spec.unmarkAsFinalState(q5c);
assertFalse(spec.isFinal(q0c));
spec.markAsFinal(q1c);
spec.markAsInitial(q3c);
spec.unmarkAsFinalState(q3c);
assertTrue(spec.isFinal(q1c));
}
}