1   /*
2    * Copyright (C) 2006  Tom Gibara
3    *
4    * This library is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Lesser General Public
6    * License as published by the Free Software Foundation; either
7    * version 2.1 of the License, or (at your option) any later version.
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   * Lesser General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this library; if not, write to the Free Software
16   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17   */
18  
19  package com.tomgibara.pronto.state;
20  
21  import static com.tomgibara.pronto.state.PathType.strictlyUniqueStates;
22  import static com.tomgibara.pronto.state.PathType.uniqueStates;
23  import static com.tomgibara.pronto.state.PathType.uniqueTransitions;
24  
25  import java.util.Collections;
26  import java.util.List;
27  import java.util.Set;
28  
29  import com.tomgibara.pronto.state.StateGraph;
30  import com.tomgibara.pronto.state.StateTransition;
31  
32  import junit.framework.TestCase;
33  
34  public class StateGraphTest extends TestCase {
35  
36      public void testSeparateITStates() {
37          StateGraph<String, Integer> graph = TestUtil.makeGraph("A->B;C->D;E->F");
38          assertEquals(TestUtil.stateSet("A;C;E"), graph.getInitialStates());
39          assertEquals(TestUtil.stateSet("B;D;F"), graph.getTerminalStates());
40      }
41  
42      public void testJoinedITStates() {
43          StateGraph<String, Integer> graph = TestUtil.makeGraph("A->B;B->C;C->D");
44          assertEquals(TestUtil.stateSet("A"), graph.getInitialStates());
45          assertEquals(TestUtil.stateSet("D"), graph.getTerminalStates());
46      }
47  
48      public void testSeparatePaths() {
49          StateGraph<String, Integer> graph = TestUtil.makeGraph("A->B;C->D;E->F");
50          Set<List<StateTransition<String, Integer>>> paths = graph.getMultiPaths(graph.getInitialStates(), graph.getTerminalStates(), uniqueTransitions);
51          testSequential(paths);
52          assertEquals(3, paths.size());
53      }
54  
55      public void testJoinedPaths() {
56          StateGraph<String, Integer> graph = TestUtil.makeGraph("A->B;B->C;C->D");
57          Set<List<StateTransition<String, Integer>>> paths = graph.getMultiPaths(graph.getInitialStates(), graph.getTerminalStates(), uniqueTransitions);
58          testSequential(paths);
59          assertEquals(1, paths.size());
60      }
61  
62      public void testForkedPaths() {
63          StateGraph<String, Integer> graph = TestUtil.makeGraph("A->D;B->D;C->D;D->E;E->F;E->G;E->H");
64          Set<List<StateTransition<String, Integer>>> paths = graph.getMultiPaths(graph.getInitialStates(), graph.getTerminalStates(), uniqueTransitions);
65          testSequential(paths);
66          testEnds(paths, graph);
67          assertEquals(9, paths.size());
68      }
69  
70      public void testUniqueStatePath() {
71          StateGraph<String, Integer> graph = TestUtil.makeGraph("A->B;B->C;C->B;B->D");
72          Set<List<StateTransition<String, Integer>>> utPaths = graph.getPaths("B", "D", uniqueTransitions);
73          Set<List<StateTransition<String, Integer>>> usPaths = graph.getPaths("B", "D", uniqueStates);
74          Set<List<StateTransition<String, Integer>>> susPaths = graph.getPaths("B", "D", strictlyUniqueStates);
75          testSequential(utPaths);
76          testSequential(usPaths);
77          testSequential(susPaths);
78          assertEquals(2, utPaths.size());
79          assertEquals(2, usPaths.size());
80          assertEquals(1, susPaths.size());
81      }
82      
83      private void testSequential(Set<List<StateTransition<String, Integer>>> paths) {
84          for (List<StateTransition<String, Integer>> path : paths) {
85              StateTransition<String, Integer> previous = null;
86              for (StateTransition<String, Integer> transition : path) {
87                  if (previous != null) {
88                      if (!previous.getTarget().equals(transition.getSource())) {
89                          throw new IllegalArgumentException(path.toString());
90                      }
91                  }
92                  previous = transition;
93              }
94          }
95      }
96  
97      private void testEnds(Set<List<StateTransition<String, Integer>>> paths, StateGraph<String, Integer> graph) {
98          Set<String> initialStates = graph.getInitialStates();
99          Set<String> terminalStates = graph.getTerminalStates();
100         for (List<StateTransition<String, Integer>> path : paths) {
101             String initial = path.get(0).getSource();
102             String terminal = path.get(path.size() - 1).getTarget();
103             if (!initialStates.contains(initial)) throw new IllegalArgumentException("State " + initial + " not in "
104                     + initialStates);
105             if (!terminalStates.contains(terminal)) throw new IllegalArgumentException("State " + terminal + " not in "
106                     + terminalStates);
107         }
108     }
109 
110 }