001 /**
002 * Copyright 2013 The Kuali Foundation Licensed under the
003 * Educational Community License, Version 2.0 (the "License"); you may
004 * not use this file except in compliance with the License. You may
005 * obtain a copy of the License at
006 *
007 * http://www.osedu.org/licenses/ECL-2.0
008 *
009 * Unless required by applicable law or agreed to in writing,
010 * software distributed under the License is distributed on an "AS IS"
011 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
012 * or implied. See the License for the specific language governing
013 * permissions and limitations under the License.
014 *
015 * Created by Mezba Mahtab (mezba.mahtab@utoronto.ca) on 4/2/13
016 */
017 package org.kuali.student.mock.mojo;
018
019 import org.kuali.student.contract.model.MessageStructure;
020 import org.kuali.student.contract.model.Service;
021 import org.kuali.student.contract.model.ServiceContractModel;
022 import org.kuali.student.contract.model.ServiceMethod;
023 import org.kuali.student.contract.model.ServiceMethodError;
024 import org.kuali.student.contract.writer.service.GetterSetterNameCalculator;
025
026 import java.util.List;
027
028 /**
029 * This class will generate the extended class that does CRUD tests as
030 * part of the Conformance Tests for services. The generated class will
031 * complete the base class and is meant to be generated once and then
032 * edited (and mantained) by developers.
033 *
034 * @author Mezba Mahtab (mezba.mahtab@utoronto.ca)
035 */
036 public class ConformanceTestExtendedCrudClassServiceWriter extends ConformanceTestBaseCrudClassServiceWriter {
037
038 ////////////////////////////
039 // CONSTRUCTOR
040 ////////////////////////////
041
042 public ConformanceTestExtendedCrudClassServiceWriter (ServiceContractModel model,
043 String directory,
044 String rootPackage,
045 String servKey,
046 List<ServiceMethod> methods,
047 boolean isR1) {
048 super(model, directory, rootPackage, servKey, methods, isR1, calcPackage(servKey, rootPackage), calcClassName(servKey));
049 }
050
051 //////////////////////////
052 // FUNCTIONALS
053 //////////////////////////
054
055 /**
056 * Given the service key (name), returns a calculated class name for the conformance tester.
057 */
058 public static String calcClassName(String servKey) {
059 return "Test" + GetterSetterNameCalculator.calcInitUpper(fixServKey(servKey) + "ServiceImplConformanceExtendedCrud");
060 }
061
062 /**
063 * Write out the entire file
064 */
065 public void write() {
066 // begin file
067 indentPrintln("@RunWith(SpringJUnit4ClassRunner.class)");
068 indentPrintln("@ContextConfiguration(locations = {\"classpath:" + servKey + "-test-with-mock-context.xml\"})");
069 indentPrint("public class " + calcClassName(servKey));
070 println(" extends " + super.calcClassName(servKey) + " ");
071 Service serv = finder.findService(servKey);
072 setPackageName(serv.getImplProject() + ".impl"); // change the package name
073 importsAdd(serv.getImplProject() + "." + serv.getName()); // import for the service
074 doTestImportsAdd();
075 openBrace();
076
077 indentPrintln("");
078
079 // print out list of methods for DTO fields per DTO that need to be completed
080 indentPrintDecoratedComment("DTO FIELD SPECIFIC METHODS", H1_COMMENT_CHAR, H1_COMMENT_MARK_LENGTH*2);
081 indentPrintln("");
082
083 // for each DTO, write the DOT field management methods that were left abstract in base class
084 for (String dtoObjectName : calcNamesOfDTOsWithCrudManagedByService()) {
085 indentPrintln("// ****************************************************");
086 indentPrintln("// " + dtoObjectName + "Info");
087 indentPrintln("// ****************************************************");
088 indentPrintln("");
089
090 // get the message structures of the dto
091 List<MessageStructure> messageStructures = finder.findMessageStructures(dtoObjectName + "Info");
092
093 writetestCrudXXX_setDTOFieldsForTestCreate(dtoObjectName, messageStructures);
094 writetestCrudXXX_testDTOFieldsForTestCreateUpdate(dtoObjectName, messageStructures);
095 writetestCrudXXX_setDTOFieldsForTestUpdate(dtoObjectName, messageStructures);
096 writetestCrudXXX_testDTOFieldsForTestReadAfterUpdate(dtoObjectName, messageStructures);
097 writetestCrudXXX_setDTOFieldsForTestReadAfterUpdate(dtoObjectName, messageStructures);
098 indentPrintln("");
099 }
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 }