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