1   package uba.db.sql.language;
2   
3   import java.util.ArrayList;
4   import java.util.Iterator;
5   import java.util.List;
6   
7   import junit.framework.TestCase;
8   
9   import org.apache.commons.collections.CollectionUtils;
10  import org.apache.commons.collections.TransformerUtils;
11  
12  import uba.db.sql.parser.SQLParser;
13  
14  /***
15   * Test para el comportamiento default de
16   * {@link uba.db.sql.language.VisitorBehavior}. Aunque las clase
17   * {@link uba.db.sql.language.VisitorBehavior} es abstracta, este test utiliza
18   * {@link uba.db.sql.language.VisitCollector} para chequear el comportamiento
19   * default.
20   * 
21   * @version $Revision: 1.4 $
22   */
23  public class VisitorBehaviorTest extends TestCase {
24      private VisitCollector visitCollector;
25  
26      /***
27       * @see junit.framework.TestCase#setUp()
28       */
29      protected void setUp() throws Exception {
30          super.setUp();
31          visitCollector = new VisitCollector();
32      }
33  
34      /***
35       * Test: al visitar un select se deben visitar cada una de sus partes.
36       */
37      public void testVisitSelect() throws Exception {
38          // en lugar de crear los objetos de las sentencias a mano uso el parser
39          Select select = (Select) new SQLParser()
40                  .parse("select a, b from T1, T2 where T1.a='hola' and "
41                          + "T1.b>T2.b or d >= 10 and a IN (1, b, 3)");
42  
43          select.accept(visitCollector);
44  
45          // para simplificar el test se usa el toString de cada uno de los
46          // objetos visitados, lo malo es que si cambia el toString el test
47          // falla, lo
48          // bueno es que mato dos pajaros de un tiro: test de visitor y de
49          // toString
50          List collectedObjectsAsString = collectedObjectsAsString();
51  
52          List expected = new ArrayList();
53          expected
54                  .add("SELECT a, b FROM T1, T2 WHERE (T1.a = 'hola' AND ((T1.b > T2.b OR d >= 10) AND a IN (1, b, 3)))");
55          expected.add("a, b");
56          expected.add("a");
57          expected.add("a");
58          expected.add("b");
59          expected.add("b");
60          expected.add("T1, T2");
61          expected.add("T1");
62          expected.add("T1");
63          expected.add("T2");
64          expected.add("T2");
65          expected.add("(T1.a = 'hola' AND ((T1.b > T2.b OR d >= 10) AND a IN (1, b, 3)))");
66          expected.add("T1.a = 'hola'");
67          expected.add("T1.a = 'hola'");
68          expected.add("T1.a");
69          expected.add("'hola'");
70          expected.add("((T1.b > T2.b OR d >= 10) AND a IN (1, b, 3))");
71          expected.add("(T1.b > T2.b OR d >= 10)");
72          expected.add("T1.b > T2.b");
73          expected.add("T1.b > T2.b");
74          expected.add("T1.b");
75          expected.add("T2.b");
76          expected.add("d >= 10");
77          expected.add("d >= 10");
78          expected.add("d");
79          expected.add("10");
80          expected.add("a IN (1, b, 3)");
81          expected.add("a");
82          expected.add("1, b, 3");
83          expected.add("1");
84          expected.add("b");
85          expected.add("3");
86  
87          assertEquals(expected.size(), collectedObjectsAsString.size());
88  
89          // no use equals, por que cuando el test falla es muy dificil buscar
90          // donde fallo
91          Iterator expectedIter = expected.iterator();
92          Iterator resultIter = collectedObjectsAsString.iterator();
93          while (expectedIter.hasNext()) {
94              assertEquals(expectedIter.next(), resultIter.next());
95          }
96      }
97  
98      private List collectedObjectsAsString() {
99          return (List) CollectionUtils.collect(visitCollector.visitedObjects(),
100                                               TransformerUtils.stringValueTransformer());
101     }
102 
103     /***
104      * Test: al visitar un select se deben visitar cada una de sus partes. (caso
105      * sin criterio de seleccion).
106      */
107     public void testVisitSelectWithNullCriteria() throws Exception {
108         Select select = (Select) new SQLParser().parse("select * from T1");
109 
110         select.accept(visitCollector);
111         List collectedObjectsAsString = collectedObjectsAsString();
112         List expected = new ArrayList();
113         expected.add("SELECT * FROM T1");
114         expected.add("*");
115         expected.add("T1");
116         expected.add("T1");
117 
118         assertEquals(expected, collectedObjectsAsString);
119     }
120 
121     /***
122      * Test: al visitar un select se deben visitar cada una de sus partes. (caso
123      * criterio de seleccion con comparaciones por menor).
124      */
125     public void testVisitSelectWithLessComparisons() throws Exception {
126         Select select = (Select) new SQLParser()
127                 .parse("select * from T1 where a < b and c <= d");
128 
129         select.accept(visitCollector);
130         List collectedObjectsAsString = collectedObjectsAsString();
131         List expected = new ArrayList();
132         expected.add("SELECT * FROM T1 WHERE (a < b AND c <= d)");
133         expected.add("*");
134         expected.add("T1");
135         expected.add("T1");
136         expected.add("(a < b AND c <= d)");
137         expected.add("a < b");
138         expected.add("a < b");
139         expected.add("a");
140         expected.add("b");
141         expected.add("c <= d");
142         expected.add("c <= d");
143         expected.add("c");
144         expected.add("d");
145 
146         assertEquals(expected, collectedObjectsAsString);
147     }
148 
149     /***
150      * Test: verifica que {@link VisitCollector} descienda de
151      * {@link VisitorBehavior}.
152      */
153     public void testVisitCollectorExtendsVisitorBehavior() throws Exception {
154         assertEquals(VisitorBehavior.class, visitCollector.getClass().getSuperclass());
155     }
156 
157     /***
158      * Test: visita una sentencia de insert y todas sus partes.
159      */
160     public void testVisitInsert() throws Exception {
161         Insert insert = (Insert) new SQLParser().parse("insert into T values (1, 'a')");
162 
163         insert.accept(visitCollector);
164         List collectedObjectsAsString = collectedObjectsAsString();
165         List expected = new ArrayList();
166         expected.add("INSERT INTO T VALUES (1, 'a')");
167         expected.add("T");
168         expected.add("1, 'a'");
169         expected.add("1");
170         expected.add("'a'");
171 
172         assertEquals(expected, collectedObjectsAsString);
173     }
174 
175     /***
176      * Test: visita una sentencia de create table y todas sus partes.
177      */
178     public void testCreateTableInsert() throws Exception {
179         CreateTable createTable = (CreateTable) new SQLParser()
180                 .parse("create table prueba (id INTEGER)");
181 
182         createTable.accept(visitCollector);
183         List collectedObjectsAsString = collectedObjectsAsString();
184         List expected = new ArrayList();
185         expected.add("CREATE TABLE prueba (id INTEGER)");
186         expected.add("prueba");
187         expected.add("id INTEGER");
188 
189         assertEquals(expected, collectedObjectsAsString);
190     }
191 }