1   package org.apache.torque.engine.database.model;
2   
3   /*
4    * Copyright 2001-2005 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License")
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import java.util.ArrayList;
20  import java.util.Arrays;
21  import java.util.List;
22  
23  import org.apache.torque.engine.EngineException;
24  
25  import junit.framework.TestCase;
26  
27  /***
28   * <p>Unit tests for class <code>NameFactory</code> and known
29   * <code>NameGenerator</code> implementations.</p>
30   *
31   * <p>To add more tests, add entries to the <code>ALGORITHMS</code>,
32   * <code>INPUTS</code>, and <code>OUTPUTS</code> arrays, and code to
33   * the <code>makeInputs()</code> method.</p>
34   *
35   * <p>This test assumes that it's being run using the MySQL database
36   * adapter, <code>DBMM</code>.  MySQL has a column length limit of 64
37   * characters.</p>
38   *
39   * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
40   * @version $Id: NameFactoryTest.java 239626 2005-08-24 12:19:51Z henning $
41   */
42  public class NameFactoryTest extends TestCase
43  {
44  
45      /*** The database to mimic in generating the SQL. */
46      private static final String DATABASE_TYPE = "mysql";
47  
48      /***
49       * The list of known name generation algorithms, specified as the
50       * fully qualified class names to <code>NameGenerator</code>
51       * implementations.
52       */
53      private static final String[] ALGORITHMS =
54          { NameFactory.CONSTRAINT_GENERATOR, NameFactory.JAVA_GENERATOR };
55  
56      /***
57       * Two dimensional arrays of inputs for each algorithm.
58       */
59      private static final Object[][][] INPUTS =
60          { { { makeString(61), "I", new Integer(1)}, {
61                  makeString(61), "I", new Integer(2)
62                  }, {
63                  makeString(65), "I", new Integer(3)
64                  }, {
65                  makeString(4), "FK", new Integer(1)
66                  }, {
67                  makeString(5), "FK", new Integer(2)
68                  }
69          }, {
70              {
71                  "MY_USER",
72                          NameGenerator.CONV_METHOD_UNDERSCORE }, {
73                  "MY_USER",
74                          NameGenerator.CONV_METHOD_UNDERSCORE_OMIT_SCHEMA }, {
75                  "MY_USER",
76                          NameGenerator.CONV_METHOD_JAVANAME }, {
77                  "MY_USER",
78                          NameGenerator.CONV_METHOD_NOCHANGE }, {
79                  "MY_SCHEMA.MY_USER",
80                          NameGenerator.CONV_METHOD_UNDERSCORE }, {
81                  "MY_SCHEMA.MY_USER",
82                          NameGenerator.CONV_METHOD_UNDERSCORE_OMIT_SCHEMA }, {
83                  "MY_SCHEMA.MY_USER",
84                          NameGenerator.CONV_METHOD_JAVANAME } , {
85                  "MY_SCHEMA.MY_USER",
86                          NameGenerator.CONV_METHOD_NOCHANGE }
87          }
88      };
89  
90      /***
91       * Given the known inputs, the expected name outputs.
92       */
93      private static final String[][] OUTPUTS =
94          {
95              {
96                  makeString(60) + "_I_1",
97                  makeString(60) + "_I_2",
98                  makeString(60) + "_I_3",
99                  makeString(4) + "_FK_1",
100                 makeString(5) + "_FK_2" },
101             {
102                 "MyUser",
103                 "MyUser",
104                 "MYUSER",
105                 "MY_USER",
106                 "MySchemaMyUser",
107                 "MyUser",
108                 "MYSCHEMAMYUSER",
109                 "MY_SCHEMA.MY_USER"
110             }
111     };
112 
113     /***
114      * Used as an input.
115      */
116     private Database database;
117 
118     /***
119      * Creates a new instance.
120      *
121      * @param name the name of the test to run
122      */
123     public NameFactoryTest(String name)
124     {
125         super(name);
126     }
127 
128     /***
129      * Creates a string of the specified length consisting entirely of
130      * the character <code>A</code>.  Useful for simulating table
131      * names, etc.
132      *
133      * @param len the number of characters to include in the string
134      * @return a string of length <code>len</code> with every character an 'A'
135      */
136     private static final String makeString(int len)
137     {
138         StringBuffer buf = new StringBuffer();
139         for (int i = 0; i < len; i++)
140         {
141             buf.append('A');
142         }
143         return buf.toString();
144     }
145 
146     /*** Sets up the Torque model. */
147     public void setUp()
148     {
149         database = new Database(DATABASE_TYPE);
150         database.setDatabaseType(DATABASE_TYPE);
151     }
152 
153     /***
154      * @throws Exception on fail
155      */
156     public void testNames() throws Exception
157     {
158         for (int algoIndex = 0; algoIndex < ALGORITHMS.length; algoIndex++)
159         {
160             String algo = ALGORITHMS[algoIndex];
161             Object[][] algoInputs = INPUTS[algoIndex];
162             for (int i = 0; i < algoInputs.length; i++)
163             {
164                 List inputs = makeInputs(algo, algoInputs[i]);
165                 String generated = NameFactory.generateName(algo, inputs);
166                 String expected = OUTPUTS[algoIndex][i];
167                 assertEquals(
168                     "Algorithm " + algo + " failed to generate an unique name",
169                     generated,
170                     expected);
171             }
172         }
173     }
174 
175     /***
176      * @throws Exception on fail
177      */
178     public void testException() throws Exception
179     {
180         try
181         {
182             NameFactory.generateName("non.existing.class", new ArrayList());
183             assertTrue("Expected an EngineException", false);
184         }
185         catch (EngineException ex)
186         {
187         }
188     }
189 
190     /***
191      * Creates the list of arguments to pass to the specified type of
192      * <code>NameGenerator</code> implementation.
193      *
194      * @param algo The class name of the <code>NameGenerator</code> to
195      * create an argument list for.
196      * @param inputs The (possibly partial) list inputs from which to
197      * generate the final list.
198      * @return the list of arguments to pass to the <code>NameGenerator</code>
199      */
200     private final List makeInputs(String algo, Object[] inputs)
201     {
202         List list = null;
203         if (NameFactory.CONSTRAINT_GENERATOR.equals(algo))
204         {
205             list = new ArrayList(inputs.length + 1);
206             list.add(0, database);
207             list.addAll(Arrays.asList(inputs));
208         }
209         else if (NameFactory.JAVA_GENERATOR.equals(algo))
210         {
211             list = Arrays.asList(inputs);
212         }
213         return list;
214     }
215 
216 }