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 }