001 /** 002 * Copyright 2004-2014 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 }