1 19 20 package org.netbeans.modules.junit; 21 22 import java.util.ArrayList ; 23 import java.util.EnumSet ; 24 import java.util.HashSet ; 25 import java.util.List ; 26 import java.util.Map ; 27 import java.util.Set ; 28 import javax.lang.model.element.Element; 29 import javax.lang.model.element.ExecutableElement; 30 import javax.lang.model.element.Modifier; 31 import javax.lang.model.element.NestingKind; 32 import javax.lang.model.element.TypeElement; 33 import javax.lang.model.util.ElementFilter; 34 import org.netbeans.api.java.source.CompilationInfo; 35 import org.netbeans.modules.junit.plugin.JUnitPlugin.CreateTestParam; 36 import static javax.lang.model.element.Modifier.ABSTRACT; 37 import static javax.lang.model.element.Modifier.PRIVATE; 38 import static javax.lang.model.element.Modifier.PROTECTED; 39 import static javax.lang.model.element.Modifier.PUBLIC; 40 import static javax.lang.model.element.Modifier.STATIC; 41 import static org.openide.NotifyDescriptor.WARNING_MESSAGE; 42 import static org.netbeans.modules.junit.TestCreator.ACCESS_MODIFIERS; 43 44 48 public final class TestGeneratorSetup implements TestabilityJudge { 49 50 51 52 static private final String JUNIT_SUPER_CLASS_NAME = "TestCase"; 53 static private final String JUNIT_FRAMEWORK_PACKAGE_NAME = "junit.framework"; 54 55 static private final String METHOD_NAME_SETUP = "setUp"; static private final String METHOD_NAME_TEARDOWN = "tearDown"; static private final String CLASS_COMMENT_LINE1 = "TestCreator.javaClass.addTestsHereComment.l1"; 58 static private final String CLASS_COMMENT_LINE2 = "TestCreator.javaClass.addTestsHereComment.l2"; 59 60 61 private boolean skipTestClasses = true; 62 63 private boolean skipPkgPrivateClasses = false; 64 65 private boolean skipAbstractClasses = false; 66 67 private boolean skipExceptionClasses = false; 68 72 private boolean generateSuiteClasses = true; 73 78 private Set <Modifier> methodAccessModifiers 79 = AbstractTestGenerator.createModifierSet(Modifier.PUBLIC, 80 Modifier.PROTECTED); 81 86 private boolean testPkgPrivateMethods = true; 87 93 private boolean generateDefMethodBody = true; 94 100 private boolean generateMethodJavadoc = true; 101 107 private boolean generateSourceCodeHints = true; 108 116 private boolean generateTestSetUp = true; 117 125 private boolean generateTestTearDown = true; 126 133 private boolean generateClassSetUp = true; 134 141 private boolean generateClassTearDown = true; 142 149 private boolean generateMainMethod = true; 150 151 152 153 160 public TestGeneratorSetup(boolean loadDefaults) { 161 if (loadDefaults) { 162 loadDefaults(); 163 } 164 } 165 166 169 public TestGeneratorSetup(Map <CreateTestParam, Object > params) { 170 final JUnitSettings settings = JUnitSettings.getDefault(); 171 172 skipTestClasses = !JUnitSettings.GENERATE_TESTS_FROM_TEST_CLASSES; 173 174 skipPkgPrivateClasses = !Boolean.TRUE.equals(params.get( 175 CreateTestParam.INC_PKG_PRIVATE_CLASS)); 176 skipAbstractClasses = !Boolean.TRUE.equals(params.get( 177 CreateTestParam.INC_ABSTRACT_CLASS)); 178 skipExceptionClasses = !Boolean.TRUE.equals(params.get( 179 CreateTestParam.INC_EXCEPTION_CLASS)); 180 generateSuiteClasses = Boolean.TRUE.equals(params.get( 181 CreateTestParam.INC_GENERATE_SUITE)); 182 183 methodAccessModifiers.clear(); 184 if (Boolean.TRUE.equals(params.get(CreateTestParam.INC_PUBLIC))) { 185 methodAccessModifiers.add(Modifier.PUBLIC); 186 } 187 if (Boolean.TRUE.equals(params.get(CreateTestParam.INC_PROTECTED))) { 188 methodAccessModifiers.add(Modifier.PROTECTED); 189 } 190 testPkgPrivateMethods = Boolean.TRUE.equals(params.get( 191 CreateTestParam.INC_PKG_PRIVATE)); 192 generateDefMethodBody = Boolean.TRUE.equals(params.get( 193 CreateTestParam.INC_METHOD_BODIES)); 194 generateMethodJavadoc = Boolean.TRUE.equals(params.get( 195 CreateTestParam.INC_JAVADOC)); 196 generateSourceCodeHints = Boolean.TRUE.equals(params.get( 197 CreateTestParam.INC_CODE_HINT)); 198 generateTestSetUp = Boolean.TRUE.equals(params.get( 199 CreateTestParam.INC_SETUP)); 200 generateTestTearDown = Boolean.TRUE.equals(params.get( 201 CreateTestParam.INC_TEAR_DOWN)); 202 203 generateMainMethod = settings.isGenerateMainMethod(); 204 } 205 206 207 210 private void loadDefaults() { 211 final JUnitSettings settings = JUnitSettings.getDefault(); 212 213 skipTestClasses = JUnitSettings.GENERATE_TESTS_FROM_TEST_CLASSES; 214 skipPkgPrivateClasses = !settings.isIncludePackagePrivateClasses(); 215 skipAbstractClasses = !settings.isGenerateAbstractImpl(); 216 skipExceptionClasses = !settings.isGenerateExceptionClasses(); 217 generateSuiteClasses = settings.isGenerateSuiteClasses(); 218 219 methodAccessModifiers.clear(); 220 if (settings.isMembersPublic()) { 221 methodAccessModifiers.add(Modifier.PUBLIC); 222 } 223 if (settings.isMembersProtected()) { 224 methodAccessModifiers.add(Modifier.PROTECTED); 225 } 226 testPkgPrivateMethods = settings.isMembersPackage(); 227 228 generateDefMethodBody = settings.isBodyContent(); 229 generateMethodJavadoc = settings.isJavaDoc(); 230 generateSourceCodeHints = settings.isBodyComments(); 231 generateTestSetUp = settings.isGenerateSetUp(); 232 generateTestTearDown = settings.isGenerateTearDown(); 233 generateMainMethod = settings.isGenerateMainMethod(); 234 } 235 236 244 public void setSkipTestClasses(boolean skip) { 245 this.skipTestClasses = skip; 246 } 247 248 250 public boolean isSkipTestClasses() { 251 return skipTestClasses; 252 } 253 254 262 public void setSkipPackagePrivateClasses(boolean skip) { 263 this.skipPkgPrivateClasses = skip; 264 } 265 266 268 public boolean isSkipPackagePrivateClasses() { 269 return skipPkgPrivateClasses; 270 } 271 272 280 public void setSkipAbstractClasses(boolean skip) { 281 this.skipAbstractClasses = skip; 282 } 283 284 286 public boolean isSkipAbstractClasses() { 287 return skipAbstractClasses; 288 } 289 290 298 public void setSkipExceptionClasses(boolean skip) { 299 this.skipExceptionClasses = skip; 300 } 301 302 304 public boolean isSkipExceptionClasses() { 305 return skipExceptionClasses; 306 } 307 308 315 public void setGenerateSuiteClasses(boolean generate) { 316 this.generateSuiteClasses = generate; 317 } 318 319 321 public boolean isGenerateSuiteClasses() { 322 return generateSuiteClasses; 323 } 324 325 332 public void setTestPublicMethods(boolean test) { 333 if (test) { 334 methodAccessModifiers.add(Modifier.PUBLIC); 335 } else { 336 methodAccessModifiers.remove(Modifier.PUBLIC); 337 } 338 } 339 340 342 public boolean isTestPublicMethods() { 343 return methodAccessModifiers.contains(Modifier.PUBLIC); 344 } 345 346 353 public void setTestProtectedMethods(boolean test) { 354 if (test) { 355 methodAccessModifiers.add(Modifier.PROTECTED); 356 } else { 357 methodAccessModifiers.remove(Modifier.PROTECTED); 358 } 359 } 360 361 363 public boolean isTestProtectedMethods() { 364 return methodAccessModifiers.contains(Modifier.PROTECTED); 365 } 366 367 374 public EnumSet <Modifier> getMethodAccessModifiers() { 375 return EnumSet.copyOf(methodAccessModifiers); 376 } 377 378 387 public void setTestPackagePrivateMethods(boolean test) { 388 this.testPkgPrivateMethods = test; 389 } 390 391 393 public boolean isTestPackagePrivateMethods() { 394 return testPkgPrivateMethods; 395 } 396 397 405 public void setGenerateDefMethodBody(boolean generate) { 406 this.generateDefMethodBody = generate; 407 } 408 409 411 public boolean isGenerateDefMethodBody() { 412 return generateDefMethodBody; 413 } 414 415 423 public void setGenerateMethodJavadoc(boolean generate) { 424 this.generateMethodJavadoc = generate; 425 } 426 427 429 public boolean isGenerateMethodJavadoc() { 430 return generateMethodJavadoc; 431 } 432 433 441 public void setGenerateMethodBodyComment(boolean generate) { 442 this.generateSourceCodeHints = generate; 443 } 444 445 447 public boolean isGenerateMethodBodyComment() { 448 return generateSourceCodeHints; 449 } 450 451 461 public void setGenerateSetUp(boolean generate) { 462 this.generateTestSetUp = generate; 463 } 464 465 467 public boolean isGenerateSetUp() { 468 return generateTestSetUp; 469 } 470 471 481 public void setGenerateTearDown(boolean generate) { 482 this.generateTestTearDown = generate; 483 } 484 485 487 public boolean isGenerateTearDown() { 488 return generateTestTearDown; 489 } 490 491 501 public void setGenerateBefore(boolean generate) { 502 setGenerateSetUp(generate); 503 } 504 505 507 public boolean isGenerateBefore() { 508 return isGenerateSetUp(); 509 } 510 511 521 public void setGenerateAfter(boolean generate) { 522 setGenerateTearDown(generate); 523 } 524 525 527 public boolean isGenerateAfter() { 528 return isGenerateTearDown(); 529 } 530 531 541 public void setGenerateBeforeClass(boolean generate) { 542 this.generateClassSetUp = generate; 543 } 544 545 547 public boolean isGenerateBeforeClass() { 548 return generateClassSetUp; 549 } 550 551 561 public void setGenerateAfterClass(boolean generate) { 562 this.generateClassTearDown = generate; 563 } 564 565 567 public boolean isGenerateAfterClass() { 568 return generateClassTearDown; 569 } 570 571 581 public void setGenerateMainMethod(boolean generate) { 582 this.generateMainMethod = generate; 583 } 584 585 587 public boolean isGenerateMainMethod() { 588 return generateMainMethod; 589 } 590 591 601 public TestabilityResult isClassTestable(CompilationInfo compInfo, 602 TypeElement classElem) { 603 assert classElem != null; 604 605 TestabilityResult result = isClassTestableSingle(compInfo, classElem); 606 607 if (result.isTestable()) { 608 return TestabilityResult.OK; 609 } 610 611 List <? extends Element> enclosedElems = classElem.getEnclosedElements(); 612 if (enclosedElems.isEmpty()) { 613 614 return result; 615 } 616 617 List <TypeElement> enclosedTypes = ElementFilter.typesIn(enclosedElems); 618 if (enclosedTypes.isEmpty()) { 619 620 return result; 621 } 622 623 624 List <TypeElement> stack 625 = new ArrayList <TypeElement>(Math.max(10, enclosedTypes.size())); 626 stack.addAll(enclosedTypes); 627 int stackSize = stack.size(); 628 629 Set <TypeElement> nonTestable = new HashSet <TypeElement>(64); 630 nonTestable.add(classElem); 631 632 do { 633 TypeElement classToCheck = stack.remove(--stackSize); 634 635 if (!TopClassFinder.isTestable(classElem)) { continue; 637 } 638 639 if (!nonTestable.add(classToCheck)) { 640 continue; } 642 643 TestabilityResult resultSingle 644 = isClassTestableSingle(compInfo, classToCheck); 645 if (resultSingle.isTestable()) { 646 return TestabilityResult.OK; 647 } else { 648 result = TestabilityResult.combine(result, resultSingle); 649 } 650 651 enclosedTypes = ElementFilter.typesIn(classToCheck.getEnclosedElements()); 652 if (!enclosedTypes.isEmpty()) { 653 stack.addAll(enclosedTypes); 654 stackSize = stack.size(); 655 } 656 } while (stackSize != 0); 657 658 659 return result; 660 } 661 662 669 private TestabilityResult isClassTestableSingle(CompilationInfo compInfo, 670 TypeElement classElem) { 671 assert classElem != null; 672 673 TestabilityResult result = TestabilityResult.OK; 674 675 679 680 Set <Modifier> modifiers = classElem.getModifiers(); 681 682 if (modifiers.contains(PRIVATE)) 683 result = TestabilityResult.combine(result, TestabilityResult.PRIVATE_CLASS); 684 if (isSkipTestClasses() && TestUtil.isClassImplementingTestInterface(compInfo, classElem)) 685 result = TestabilityResult.combine(result, TestabilityResult.TEST_CLASS); 686 if (isSkipPackagePrivateClasses() && (modifiers.isEmpty() || !EnumSet.copyOf(modifiers).removeAll(ACCESS_MODIFIERS))) 687 result = TestabilityResult.combine(result, TestabilityResult.PACKAGE_PRIVATE_CLASS); 688 if (isSkipAbstractClasses() && modifiers.contains(ABSTRACT)) 689 result = TestabilityResult.combine(result, TestabilityResult.ABSTRACT_CLASS); 690 if (!modifiers.contains(STATIC) && (classElem.getNestingKind() != NestingKind.TOP_LEVEL)) 691 result = TestabilityResult.combine(result, TestabilityResult.NONSTATIC_INNER_CLASS); 692 if (!hasTestableMethods(classElem)) 693 result = TestabilityResult.combine(result, TestabilityResult.NO_TESTEABLE_METHODS); 694 if (isSkipExceptionClasses() && TestUtil.isClassException(compInfo, classElem)) 695 result = TestabilityResult.combine(result, TestabilityResult.EXCEPTION_CLASS); 696 697 return result; 698 } 699 700 702 private boolean hasTestableMethods(TypeElement classElem) { 703 List <? extends Element> enclosedElems = classElem.getEnclosedElements(); 704 if (enclosedElems.isEmpty()) { 705 return false; 706 } 707 708 List <ExecutableElement> methods = ElementFilter.methodsIn(enclosedElems); 709 if (methods.isEmpty()) { 710 return false; 711 } 712 713 for (ExecutableElement method : methods) { 714 if (isMethodTestable(method)) { 715 return true; 716 } 717 } 718 719 return false; 720 } 721 722 732 public boolean isMethodTestable(ExecutableElement method) { 733 Set <Modifier> modifiers = method.getModifiers(); 734 735 if (modifiers.isEmpty()) { 736 740 return isTestPackagePrivateMethods(); 741 } else { 742 return (isTestPackagePrivateMethods() 743 && !EnumSet.copyOf(modifiers).removeAll(ACCESS_MODIFIERS)) 744 || EnumSet.copyOf(modifiers).removeAll(getMethodAccessModifiers()); 745 } 746 } 747 748 } 749 | Popular Tags |