View Javadoc

1   /**
2    * Copyright 2013 The Kuali Foundation Licensed under the
3    * Educational Community License, Version 2.0 (the "License"); you may
4    * not use this file except in compliance with the License. You may
5    * obtain a copy of the License at
6    *
7    * http://www.osedu.org/licenses/ECL-2.0
8    *
9    * Unless required by applicable law or agreed to in writing,
10   * software distributed under the License is distributed on an "AS IS"
11   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing
13   * permissions and limitations under the License.
14   *
15   * Created by Mezba Mahtab (mezba.mahtab@utoronto.ca) on 4/2/13
16   */
17  package org.kuali.student.mock.mojo;
18  
19  import org.kuali.student.contract.model.MessageStructure;
20  import org.kuali.student.contract.model.Service;
21  import org.kuali.student.contract.model.ServiceContractModel;
22  import org.kuali.student.contract.model.ServiceMethod;
23  import org.kuali.student.contract.model.ServiceMethodError;
24  import org.kuali.student.contract.writer.service.GetterSetterNameCalculator;
25  
26  import java.util.List;
27  
28  /**
29   * This class will generate the extended class that does CRUD tests as
30   * part of the Conformance Tests for services. The generated class will
31   * complete the base class and is meant to be generated once and then
32   * edited (and mantained) by developers.
33   *
34   * @author Mezba Mahtab (mezba.mahtab@utoronto.ca)
35   */
36  public class ConformanceTestExtendedCrudClassServiceWriter extends ConformanceTestBaseCrudClassServiceWriter {
37  
38      ////////////////////////////
39      // CONSTRUCTOR
40      ////////////////////////////
41  
42      public ConformanceTestExtendedCrudClassServiceWriter (ServiceContractModel model,
43                                                            String directory,
44                                                            String rootPackage,
45                                                            String servKey,
46                                                            List<ServiceMethod> methods,
47                                                            boolean isR1) {
48          super(model, directory, rootPackage, servKey, methods, isR1, calcPackage(servKey, rootPackage), calcClassName(servKey));
49      }
50  
51      //////////////////////////
52      // FUNCTIONALS
53      //////////////////////////
54  
55      /**
56       * Given the service key (name), returns a calculated class name for the conformance tester.
57       */
58      public static String calcClassName(String servKey) {
59          return "Test" + GetterSetterNameCalculator.calcInitUpper(fixServKey(servKey) + "ServiceImplConformanceExtendedCrud");
60      }
61  
62      /**
63       * Write out the entire file
64       */
65      public void write() {
66          // begin file
67          indentPrintln("@RunWith(SpringJUnit4ClassRunner.class)");
68          indentPrintln("@ContextConfiguration(locations = {\"classpath:" + servKey + "-test-with-mock-context.xml\"})");
69          indentPrint("public class " + calcClassName(servKey));
70          println(" extends " + super.calcClassName(servKey) + " ");
71          Service serv = finder.findService(servKey);
72          setPackageName(serv.getImplProject() + ".impl"); // change the package name
73          importsAdd(serv.getImplProject() + "." + serv.getName()); // import for the service
74          doTestImportsAdd();
75          openBrace();
76  
77          indentPrintln("");
78  
79          // print out list of methods for DTO fields per DTO that need to be completed
80          indentPrintDecoratedComment("DTO FIELD SPECIFIC METHODS", H1_COMMENT_CHAR, H1_COMMENT_MARK_LENGTH*2);
81          indentPrintln("");
82  
83          // for each DTO, write the DOT field management methods that were left abstract in base class
84          for (String dtoObjectName : calcNamesOfDTOsWithCrudManagedByService()) {
85              indentPrintln("// ****************************************************");
86              indentPrintln("//           " + dtoObjectName + "Info");
87              indentPrintln("// ****************************************************");
88              indentPrintln("");
89  
90              // get the message structures of the dto
91              List<MessageStructure> messageStructures = finder.findMessageStructures(dtoObjectName + "Info");
92  
93              writetestCrudXXX_setDTOFieldsForTestCreate(dtoObjectName, messageStructures);
94              writetestCrudXXX_testDTOFieldsForTestCreateUpdate(dtoObjectName, messageStructures);
95              writetestCrudXXX_setDTOFieldsForTestUpdate(dtoObjectName, messageStructures);
96              writetestCrudXXX_testDTOFieldsForTestReadAfterUpdate(dtoObjectName, messageStructures);
97              writetestCrudXXX_setDTOFieldsForTestReadAfterUpdate(dtoObjectName, messageStructures);
98              indentPrintln("");
99          }
100 
101         // print out list of service operations that are not tested as abstract test methods
102         indentPrintDecoratedComment("SERVICE OPS NOT TESTED IN BASE TEST CLASS", H1_COMMENT_CHAR, H1_COMMENT_MARK_LENGTH*2);
103         indentPrintln("");
104 
105         // for each method, create an abstract method to test that and print it out
106         for (ServiceMethod method: methods) {
107             if (!isServiceMethodTestedAsPartofCrudInBaseConformanceTest (method)) {
108                 indentPrintln("/* Method Name: " + method.getName() + " */");
109                 indentPrintln("@Test");
110                 indentPrintln("public void test_" + method.getName() + "() ");
111                 if (method.getErrors().size()>0) {
112                     indentPrint("throws ");
113                     String comma = "";
114                     for (ServiceMethodError error: method.getErrors()) {
115                         indentPrint(comma + error.getClassName().trim());
116                         comma = ",";
117                     }
118                 }
119                 openBrace();
120                 closeBrace();
121                 indentPrintln("");
122             }
123         }
124 
125 
126 
127         // end file print out
128         closeBrace ();
129         println ("");
130 
131         // close and print file
132         this.writeJavaClassAndImportsOutToFile();
133         this.getOut().close();
134     }
135 
136     /**
137      * Writes the section to set fields specific to this dto for testCreate section.
138      */
139     public void writetestCrudXXX_setDTOFieldsForTestCreate(String dtoObjectName, List<MessageStructure> messageStructures) {
140         indentPrintln("/*");
141         incrementIndent();
142         indentPrintln("A method to set the fields for a " + dtoObjectName  + " in a 'test create' section prior to calling the 'create' operation.");
143         decrementIndent();
144         indentPrintln("*/");
145         indentPrintln("public void testCrud" + dtoObjectName + "_setDTOFieldsForTestCreate(" + dtoObjectName + "Info expected) ");
146         openBrace();
147         for (MessageStructure ms: messageStructures) {
148             if (ms.getShortName().equals("id")) continue;
149             if (ms.getShortName().equals("meta")) continue;
150             if (ms.getShortName().equals("attributes")) continue;
151             if (ms.getType().equals("String")) {
152                 indentPrintln("expected." + new GetterSetterNameCalculator (ms, this, model).calcSetter() + "(\"" + ms.getShortName()+ "01\");");
153             }
154             else if (ms.getShortName().equals("descr")) {
155                 indentPrintln("expected.setDescr(RichTextHelper.buildRichTextInfo(\"descr01\", \"descr01\"));");
156             }
157             else {
158                 indentPrintln("//TODO *TYPE = " + ms.getType() + "* expected." + new GetterSetterNameCalculator (ms, this, model).calcSetter() + "(\"" + ms.getShortName()+ "01\");");
159             }
160         }
161         closeBrace();
162         indentPrintln("");
163     }
164 
165     /**
166      * Writes the section to test fields specific to this dto for testCreate and testUpdate sections.
167      */
168     public void writetestCrudXXX_testDTOFieldsForTestCreateUpdate(String dtoObjectName, List<MessageStructure> messageStructures) {
169         indentPrintln("/*");
170         incrementIndent();
171         indentPrintln("A method to test the fields for a " + dtoObjectName  + ". This is called after:");
172         indentPrintln("- creating a DTO, where actual is the DTO returned by the create operation, and expected is the dto passed in to the create operation");
173         indentPrintln("- reading a DTO after creating it, and actual is the read DTO, and expected is the dto that was created");
174         indentPrintln("- updating a DTO, where actual is DTO returned by the update operation, and expected is the dto that was passed in to the update operation");
175         decrementIndent();
176         indentPrintln("*/");
177         indentPrintln("public void testCrud" + dtoObjectName + "_testDTOFieldsForTestCreateUpdate(" + dtoObjectName + "Info expected, " + dtoObjectName + "Info actual) ");
178         openBrace();
179         for (MessageStructure ms: messageStructures) {
180             if (ms.getShortName().equals("id")) continue;
181             if (ms.getShortName().equals("meta")) continue;
182             if (ms.getShortName().equals("attributes")) continue;
183             if (ms.getType().equals("String")) {
184                 indentPrintln("assertEquals (expected." + new GetterSetterNameCalculator (ms, this, model).calcGetter() + "(), actual." + new GetterSetterNameCalculator (ms, this, model).calcGetter() + "());");
185             }
186             else if (ms.getShortName().equals("descr")) {
187                 indentPrintln("new RichTextTester().check(expected.getDescr(), actual.getDescr());");
188             }
189             else {
190                 indentPrintln("//TODO *TYPE = " + ms.getType() + "* assertEquals (expected." + new GetterSetterNameCalculator (ms, this, model).calcGetter() + "(), actual." + new GetterSetterNameCalculator (ms, this, model).calcGetter() + "());");
191             }
192         }
193         closeBrace();
194         indentPrintln("");
195     }
196 
197 
198     /**
199      * Writes the section to set fields specific to this dto for testUpdate sections.
200      */
201     public void writetestCrudXXX_setDTOFieldsForTestUpdate(String dtoObjectName, List<MessageStructure> messageStructures) {
202         indentPrintln("/*");
203         incrementIndent();
204         indentPrintln("A method to set the fields for a " + dtoObjectName + " in a 'test update' section prior to calling the 'update' operation.");
205         decrementIndent();
206         indentPrintln("*/");
207         indentPrintln("public void testCrud" + dtoObjectName + "_setDTOFieldsForTestUpdate(" + dtoObjectName + "Info expected) ");
208         openBrace();
209         for (MessageStructure ms: messageStructures) {
210             if (ms.getShortName().equals("id")) continue;
211             if (ms.getShortName().equals("meta")) continue;
212             if (ms.getShortName().equals("attributes")) continue;
213             if (ms.getType().equals("String")) {
214                 indentPrintln("expected." + new GetterSetterNameCalculator (ms, this, model).calcSetter() + "(\"" + ms.getShortName()+ "_Updated\");");
215             }
216             else if (ms.getShortName().equals("descr")) {
217                 indentPrintln("expected.setDescr(RichTextHelper.buildRichTextInfo(\"descr_Updated\", \"descr_Updated\"));");
218             }
219             else {
220                 indentPrintln("//TODO *TYPE = " + ms.getType() + "* expected." + new GetterSetterNameCalculator (ms, this, model).calcSetter() + "(\"" + ms.getShortName()+ "_Updated\");");
221             }
222         }
223         closeBrace();
224         indentPrintln("");
225     }
226 
227     /**
228      * Writes the section to test fields specific to this dto for testReadAfterUpdate sections.
229      */
230     public void writetestCrudXXX_testDTOFieldsForTestReadAfterUpdate(String dtoObjectName, List<MessageStructure> messageStructures) {
231         indentPrintln("/*");
232         incrementIndent();
233         indentPrintln("A method to test the fields for a " + dtoObjectName  + " after an update operation, followed by a read operation,");
234         indentPrintln("where actual is the DTO returned by the read operation, and expected is the dto returned by the update operation.");
235         decrementIndent();
236         indentPrintln("*/");
237         indentPrintln("public void testCrud" + dtoObjectName + "_testDTOFieldsForTestReadAfterUpdate(" + dtoObjectName + "Info expected, " + dtoObjectName + "Info actual) ");
238         openBrace();
239         for (MessageStructure ms: messageStructures) {
240             if (ms.getShortName().equals("meta")) continue;
241             if (ms.getShortName().equals("attributes")) continue;
242             if (ms.getType().equals("String")) {
243                 indentPrintln("assertEquals (expected." + new GetterSetterNameCalculator (ms, this, model).calcGetter() + "(), actual." + new GetterSetterNameCalculator (ms, this, model).calcGetter() + "());");
244             }
245             else if (ms.getShortName().equals("descr")) {
246                 indentPrintln("new RichTextTester().check(expected.getDescr(), actual.getDescr());");
247             }
248             else {
249                 indentPrintln("//TODO *TYPE = " + ms.getType() + "* assertEquals (expected." + new GetterSetterNameCalculator (ms, this, model).calcGetter() + "(), actual." + new GetterSetterNameCalculator (ms, this, model).calcGetter() + "());");
250             }
251         }
252         closeBrace();
253         indentPrintln("");
254     }
255 
256     /**
257      * Writes the section to set fields specific to this dto for testReadAfterUpdate sections.
258      */
259     public void writetestCrudXXX_setDTOFieldsForTestReadAfterUpdate(String dtoObjectName, List<MessageStructure> messageStructures) {
260         indentPrintln("/*");
261         incrementIndent();
262         indentPrintln("A method to set the fields for a " + dtoObjectName  + " in the 'test read after update' section.");
263         indentPrintln("This dto is another (second) dto object being created for other tests.");
264         decrementIndent();
265         indentPrintln("*/");
266         indentPrintln("public void testCrud" + dtoObjectName + "_setDTOFieldsForTestReadAfterUpdate(" + dtoObjectName + "Info expected) ");
267         openBrace();
268         for (MessageStructure ms: messageStructures) {
269             if (ms.getShortName().equals("id")) continue;
270             if (ms.getShortName().equals("typeKey")) continue;
271             if (ms.getShortName().equals("stateKey")) continue;
272             if (ms.getShortName().equals("meta")) continue;
273             if (ms.getShortName().equals("descr")) continue;
274             if (ms.getShortName().equals("attributes")) continue;
275             if (ms.getType().equals("String")) {
276                 indentPrintln("expected." + new GetterSetterNameCalculator (ms, this, model).calcSetter() + "(\"" + ms.getShortName()+ "_Updated\");");
277             } else {
278                 indentPrintln("//TODO *TYPE = " + ms.getType() + "* expected." + new GetterSetterNameCalculator (ms, this, model).calcSetter() + "(\"" + ms.getShortName()+ "_Updated\");");
279             }
280         }
281         closeBrace();
282         indentPrintln("");
283     }
284 
285 }