From f79cb42c448dcdc735ceb9d38d781249d32db3a9 Mon Sep 17 00:00:00 2001 From: hneemann Date: Thu, 22 Nov 2018 21:52:27 +0100 Subject: [PATCH] added some test cases --- src/main/java/de/neemann/digital/fsm/FSM.java | 12 +- .../digital/fsm/TransitionTableCreator.java | 18 +-- .../de/neemann/digital/fsm/gui/FSMDialog.java | 16 +++ .../java/de/neemann/digital/fsm/FSMTest.java | 22 ---- .../fsm/TransitionTableCreatorTest.java | 116 ++++++++++++++++++ 5 files changed, 150 insertions(+), 34 deletions(-) delete mode 100644 src/test/java/de/neemann/digital/fsm/FSMTest.java create mode 100644 src/test/java/de/neemann/digital/fsm/TransitionTableCreatorTest.java diff --git a/src/main/java/de/neemann/digital/fsm/FSM.java b/src/main/java/de/neemann/digital/fsm/FSM.java index 9d335679d..dca79324c 100644 --- a/src/main/java/de/neemann/digital/fsm/FSM.java +++ b/src/main/java/de/neemann/digital/fsm/FSM.java @@ -121,12 +121,11 @@ public class FSM { * * @return this for chained calls */ - public FSM calculateForces() { + private void calculateForces() { for (State s : states) s.calcExpansionForce(states); for (Transition t : transitions) t.calcForce(states, transitions); - return this; } /** @@ -195,7 +194,7 @@ public class FSM { * @throws FinitStateMachineException FinitStateMachineException */ public TruthTable createTruthTable() throws ExpressionException, FinitStateMachineException { - return new TransitionTableCreator(states, transitions).create(); + return new TransitionTableCreator(this).create(); } /** @@ -223,4 +222,11 @@ public class FSM { for (State s : states) s.toRaster(); } + + /** + * @return the transitions + */ + public List getTransitions() { + return transitions; + } } diff --git a/src/main/java/de/neemann/digital/fsm/TransitionTableCreator.java b/src/main/java/de/neemann/digital/fsm/TransitionTableCreator.java index efcc43138..14fb416a2 100644 --- a/src/main/java/de/neemann/digital/fsm/TransitionTableCreator.java +++ b/src/main/java/de/neemann/digital/fsm/TransitionTableCreator.java @@ -14,14 +14,15 @@ import de.neemann.digital.lang.Lang; import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.TreeSet; /** * Creates a transition table from given states and transitions */ public class TransitionTableCreator { - private final ArrayList states; - private final ArrayList transitions; + private final List states; + private final List transitions; private TruthTable truthTable; private int rowsPerState; private ArrayList inVars; @@ -31,12 +32,11 @@ public class TransitionTableCreator { /** * Creates a new instance * - * @param states the states - * @param transitions the transitions + * @param fsm the fsm */ - public TransitionTableCreator(ArrayList states, ArrayList transitions) { - this.states = states; - this.transitions = transitions; + public TransitionTableCreator(FSM fsm) { + this.states = fsm.getStates(); + this.transitions = fsm.getTransitions(); } /** @@ -52,13 +52,13 @@ public class TransitionTableCreator { // create state variables ArrayList vars = new ArrayList<>(); for (int i = stateBits - 1; i >= 0; i--) - vars.add(new Variable("Q^" + i + "_n")); + vars.add(new Variable("Q" + i + "_n")); truthTable = new TruthTable(vars); // create the next state result variables for (int i = stateBits - 1; i >= 0; i--) - truthTable.addResult("Q^" + i + "_n+1"); + truthTable.addResult("Q" + i + "_n+1"); // add the output variables TreeSet results = new TreeSet<>(); diff --git a/src/main/java/de/neemann/digital/fsm/gui/FSMDialog.java b/src/main/java/de/neemann/digital/fsm/gui/FSMDialog.java index 7871efbb1..027e04db2 100644 --- a/src/main/java/de/neemann/digital/fsm/gui/FSMDialog.java +++ b/src/main/java/de/neemann/digital/fsm/gui/FSMDialog.java @@ -31,6 +31,22 @@ public class FSMDialog extends JDialog { private final ElementLibrary library; private boolean moveStates = false; + /** + * Use only for tests! + * + * @param givenFsm the fsm to visualize + */ + public FSMDialog(FSM givenFsm) { + this(null, givenFsm, createLibrary()); + } + + private static ElementLibrary createLibrary() { + ElementLibrary library = new ElementLibrary(); + new ShapeFactory(library); + return library; + } + + /** * Creates a new instance * diff --git a/src/test/java/de/neemann/digital/fsm/FSMTest.java b/src/test/java/de/neemann/digital/fsm/FSMTest.java deleted file mode 100644 index 2977d1ae4..000000000 --- a/src/test/java/de/neemann/digital/fsm/FSMTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package de.neemann.digital.fsm; - -import de.neemann.digital.draw.graphics.VectorFloat; -import junit.framework.TestCase; - -public class FSMTest extends TestCase { - - public void testSimple() throws FinitStateMachineException { - FSM fsm = new FSM() - .add(new State("0").setPosition(new VectorFloat(-1,0))) - .add(new State("1").setPosition(new VectorFloat(0,1))) - .add(new State("2").setPosition(new VectorFloat(1,0))) - .add(new State("3").setPosition(new VectorFloat(0,-1))) - .transition("0", "1", null) - .transition("1", "2", null) - .transition("2", "3", null) - .transition("3", "0", null); - - fsm.calculateForces(); - } - -} \ No newline at end of file diff --git a/src/test/java/de/neemann/digital/fsm/TransitionTableCreatorTest.java b/src/test/java/de/neemann/digital/fsm/TransitionTableCreatorTest.java new file mode 100644 index 000000000..9a8f7e7cd --- /dev/null +++ b/src/test/java/de/neemann/digital/fsm/TransitionTableCreatorTest.java @@ -0,0 +1,116 @@ +package de.neemann.digital.fsm; + +import de.neemann.digital.analyse.MinimizerQuineMcCluskey; +import de.neemann.digital.analyse.TruthTable; +import de.neemann.digital.analyse.expression.ExpressionException; +import de.neemann.digital.analyse.expression.format.FormatterException; +import de.neemann.digital.gui.components.table.ExpressionListenerStore; +import junit.framework.TestCase; + +import static de.neemann.digital.analyse.expression.Variable.v; + +public class TransitionTableCreatorTest extends TestCase { + + public void testBlink() throws ExpressionException, FinitStateMachineException, FormatterException { + State a = new State("a"); + State b = new State("b"); + FSM fsm = new FSM(a, b) + .transition(a, b, null) + .transition(b, a, null); + TruthTable tt = new TransitionTableCreator(fsm).create(); + assertEquals(2, tt.getRows()); + assertEquals(1, tt.getResultCount()); + + final ExpressionListenerStore el = new ExpressionListenerStore(null); + new MinimizerQuineMcCluskey().minimize(tt.getVars(), tt.getResult(0), "Y", el); + + assertEquals(1, el.getResults().size()); + assertEquals("not(Q0_n)", el.getFirst().toString()); + } + + public void testBlinkOnOff() throws ExpressionException, FinitStateMachineException, FormatterException { + State a = new State("a"); + State b = new State("b"); + FSM fsm = new FSM(a, b) + .transition(a, b, v("Run")) + .transition(b, a, v("Run")); + TruthTable tt = new TransitionTableCreator(fsm).create(); + assertEquals(4, tt.getRows()); + assertEquals(1, tt.getResultCount()); + + final ExpressionListenerStore el = new ExpressionListenerStore(null); + new MinimizerQuineMcCluskey().minimize(tt.getVars(), tt.getResult(0), "Y", el); + + assertEquals(1, el.getResults().size()); + assertEquals("or(and(not(Q0_n),Run),and(Q0_n,not(Run)))", el.getFirst().toString()); + } + + public void testBlinkResult() throws ExpressionException, FinitStateMachineException, FormatterException { + State a = new State("a").val("y",0); + State b = new State("b").val("y",1); + FSM fsm = new FSM(a, b) + .transition(a, b, null) + .transition(b, a, null); + TruthTable tt = new TransitionTableCreator(fsm).create(); + assertEquals(2, tt.getRows()); + assertEquals(2, tt.getResultCount()); + + ExpressionListenerStore el = new ExpressionListenerStore(null); + new MinimizerQuineMcCluskey().minimize(tt.getVars(), tt.getResult(0), "Y", el); + + assertEquals(1, el.getResults().size()); + assertEquals("not(Q0_n)", el.getFirst().toString()); + + el = new ExpressionListenerStore(null); + new MinimizerQuineMcCluskey().minimize(tt.getVars(), tt.getResult(1), "Y", el); + + assertEquals(1, el.getResults().size()); + assertEquals("Q0_n", el.getFirst().toString()); + } + + public void testBlinkNotDeterministic() throws ExpressionException { + State a = new State("a"); + State b = new State("b"); + State c = new State("c"); + FSM fsm = new FSM(a, b, c) + .transition(a, b, v("Run")) + .transition(a, c, v("Run")); + try { + new TransitionTableCreator(fsm).create(); + fail(); + } catch (FinitStateMachineException e) { + assertTrue(true); + } + } + + public void testBlinkNotUnique() throws ExpressionException { + State a = new State("a"); + State b = new State("b").setNumber(1); + State c = new State("c").setNumber(1); + FSM fsm = new FSM(a, b, c) + .transition(a, b, v("Run")) + .transition(b, c, v("Run")); + try { + new TransitionTableCreator(fsm).create(); + fail(); + } catch (FinitStateMachineException e) { + assertTrue(true); + } + } + + public void testBlinkNoInitialState() throws ExpressionException { + State a = new State("a").setNumber(1); + State b = new State("b").setNumber(2); + State c = new State("c").setNumber(3); + FSM fsm = new FSM(a, b, c) + .transition(a, b, v("Run")) + .transition(b, c, v("Run")); + try { + new TransitionTableCreator(fsm).create(); + fail(); + } catch (FinitStateMachineException e) { + assertTrue(true); + } + } + +} \ No newline at end of file