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