1. 02 7月, 2015 1 次提交
    • S
      Introduce DirtiesContextBeforeModesTestExecutionListener · 0aac02d6
      Sam Brannen 提交于
      SPR-12429 introduced various `BEFORE_*` modes in `@DirtiesContext`. To
      support these new modes, `DirtiesContextTestExecutionListener` (DCTEL)
      was updated to support both `BEFORE_*` and `AFTER_*` modes. However,
      there is a problem with having DCTEL support `BEFORE_*` modes since it
      is typically configured to execute after the
      `DependencyInjectionTestExecutionListener` (DITEL), and this leads to
      several undesired side effects:
      
       - The test's `ApplicationContext` is closed by DCTEL *after*
         dependencies have been injected into the test instance.
      
       - Injected dependencies may therefore attempt to interact with an
         `ApplicationContext` that is no longer _active_.
      
       - If a test has its `ApplicationContext` injected as a dependency,
         interaction with the context will likely fail since the context has
         been closed.
      
       - Any `TestExecutionListeners` registered after DCTEL will get a _new_
         `ApplicationContext` if they invoke `getApplicationContext()` on the
         `TestContext`.
      
      This commit fixes these issues by introducing a new
      `DirtiesContextBeforeModesTestExecutionListener` (DCBMTEL) that is
      registered by default before DITEL. The previous support for `BEFORE_*`
      modes has been moved from DCTEL to DCBMTEL. In addition, an
      `AbstractDirtiesContextTestExecutionListener` has been extracted from
      DCTEL in order to avoid code duplication.
      
      Issue: SPR-13180
      0aac02d6
  2. 24 6月, 2015 1 次提交
    • S
      Support inlined SQL statements in @Sql · 10a691bd
      Sam Brannen 提交于
      Prior to this commit, it was only possible to declare SQL statements
      via @Sql within external script resources (i.e., classpath or file
      system resources); however, many developers have inquired about the
      ability to inline SQL statements with @Sql analogous to the support for
      inlined properties in @TestPropertySource.
      
      This commit introduces support for declaring _inlined SQL statements_
      in `@Sql` via a new `statements` attribute. Inlined statements are
      executed after statements in scripts.
      
      Issue: SPR-13159
      10a691bd
  3. 21 6月, 2015 1 次提交
    • S
      Synthesize annotation from defaults · d0c0d9fc
      Sam Brannen 提交于
      This commit introduces a convenience method in AnnotationUtils for
      synthesizing an annotation from its default attribute values.
      
      TransactionalTestExecutionListener has been refactored to invoke this
      new convenience method.
      
      Issue: SPR-13087
      d0c0d9fc
  4. 20 6月, 2015 2 次提交
    • S
      Polishing · 27d1ce84
      Sam Brannen 提交于
      27d1ce84
    • S
      Honor contract of @Repeatable in AnnotationUtils · fb83e83e
      Sam Brannen 提交于
      Prior to this commit, the implementation of getRepeatableAnnotation()
      in Spring's AnnotationUtils complied neither with the contract of
      getAnnotationsByType() nor with the contract of
      getDeclaredAnnotationsByType() as defined in AnnotatedElement in Java 8.
      
      Specifically, unexpected results can be encountered when using Spring's
      support for @Repeatable annotations: either annotations show up in the
      returned set in the wrong order, or annotations are returned in the set
      that should not even be found based on the semantics of @Repeatable.
      
      This commit remedies this problem by deprecating the existing
      getRepeatableAnnotation() methods and replacing them with new
      getRepeatableAnnotations() and getDeclaredRepeatableAnnotations()
      methods that comply with the contracts of Java's getAnnotationsByType()
      and getDeclaredAnnotationsByType(), respectively.
      
      Issue: SPR-13068
      fb83e83e
  5. 19 6月, 2015 1 次提交
    • S
      Synthesize annotation from map w/ minimal attributes · ece12f9d
      Sam Brannen 提交于
      The initial support for synthesizing an annotation from a Map (or
      AnnotationAttributes) introduced in SPR-13067 required that the map
      contain key-value pairs for every attribute defined by the supplied
      annotationType. However, there are use cases that would benefit from
      being able to supply a reduced set of attributes and still have the
      annotation synthesized properly.
      
      This commit refines the validation mechanism in
      MapAnnotationAttributeExtractor so that a reduced set of attributes may
      be supplied. Specifically, if an attribute is missing in the supplied
      map the attribute will be set either to value of its alias (if an alias
      value configured via @AliasFor exists) or to the value of the
      attribute's default value (if defined), and otherwise an exception will
      be thrown.
      
      Furthermore, TransactionalTestExecutionListener has been refactored to
      take advantage of this new feature by synthesizing an instance of
      @TransactionConfiguration solely from the default values of its
      declared attributes.
      
      Issue: SPR-13087
      ece12f9d
  6. 15 6月, 2015 1 次提交
    • S
      Retain order of active profiles in the TCF · 68a70437
      Sam Brannen 提交于
      Ever since @ActiveProfiles was introduced, the declared active profiles
      for integration tests have been sorted in order to support unique cache
      key generation; however, there are use cases for which the original
      ordering should be retained.
      
      For example, Spring Boot's ConfigFileApplicationListener loads
      configuration files for active profiles in the order returned by
      Environment.getActiveProfiles(), with the assumption that the ordering
      matches the order in which the developer declared the active profiles.
      
      This commit maintains the uniqueness of active profiles declared via
      @ActiveProfiles but no longer sorts them.
      
      Issue: SPR-12492
      68a70437
  7. 14 6月, 2015 2 次提交
    • S
      Polish Javadoc for @TransactionConfiguration · ea9d7aa3
      Sam Brannen 提交于
      ea9d7aa3
    • S
      Revise method and parameter names in annotation support · 32c17bf5
      Sam Brannen 提交于
      In AnnotatedElementUtils, all methods pertaining to merging annotation
      attributes have been renamed to "getMerged*()" and "findMerged*()"
      accordingly. Existing methods such as getAnnotationAttributes(..) have
      been deprecated in favor of the more descriptive "merged" variants.
      This aligns the naming conventions in AnnotatedElementUtils with those
      already present in AnnotationReadingVisitorUtils.
      
      The use of "annotationType" as a variable name for the fully qualified
      class name of an annotation type has been replaced with
      "annotationName" in order to improve the readability and intent of the
      code base.
      
      In MetaAnnotationUtils.AnnotationDescriptor, getMergedAnnotation() has
      been renamed to synthesizeAnnotation(), and the method is now
      overridden in UntypedAnnotationDescriptor to always throw an
      UnsupportedOperationException in order to avoid potential run-time
      ClassCastExceptions.
      
      Issue: SPR-11511
      32c17bf5
  8. 29 5月, 2015 1 次提交
    • S
      Synthesize annotation from a map of attributes · e30c9b2e
      Sam Brannen 提交于
      Spring Framework 4.2 RC1 introduced support for synthesizing an
      annotation from an existing annotation in order to provide additional
      functionality above and beyond that provided by Java. Specifically,
      such synthesized annotations provide support for @AliasFor semantics.
      As luck would have it, the same principle can be used to synthesize an
      annotation from any map of attributes, and in particular, from an
      instance of AnnotationAttributes.
      
      The following highlight the major changes in this commit toward
      achieving this goal.
      
      - Introduced AnnotationAttributeExtractor abstraction and refactored
        SynthesizedAnnotationInvocationHandler to delegate to an
        AnnotationAttributeExtractor.
      
      - Extracted code from SynthesizedAnnotationInvocationHandler into new
        AbstractAliasAwareAnnotationAttributeExtractor and
        DefaultAnnotationAttributeExtractor implementation classes.
      
      - Introduced MapAnnotationAttributeExtractor for synthesizing an
        annotation that is backed by a map or AnnotationAttributes instance.
      
      - Introduced a variant of synthesizeAnnotation() in AnnotationUtils
        that accepts a map.
      
      - Introduced findAnnotation(*) methods in AnnotatedElementUtils that
        synthesize merged AnnotationAttributes back into an annotation of the
        target type.
      
      The following classes have been refactored to use the new support for
      synthesizing AnnotationAttributes back into an annotation.
      
      - ApplicationListenerMethodAdapter
      - TestAnnotationUtils
      - AbstractTestContextBootstrapper
      - ActiveProfilesUtils
      - ContextLoaderUtils
      - DefaultActiveProfilesResolver
      - DirtiesContextTestExecutionListener
      - TestPropertySourceAttributes
      - TestPropertySourceUtils
      - TransactionalTestExecutionListener
      - MetaAnnotationUtils
      - MvcUriComponentsBuilder
      - RequestMappingHandlerMapping
      
      In addition, this commit also includes changes to ensure that arrays
      returned by synthesized annotations are properly cloned first.
      
      Issue: SPR-13067
      e30c9b2e
  9. 22 5月, 2015 1 次提交
    • S
      Support annotation attribute aliases and overrides via @AliasFor · ca66e076
      Sam Brannen 提交于
      This commit introduces first-class support for aliases for annotation
      attributes. Specifically, this commit introduces a new @AliasFor
      annotation that can be used to declare a pair of aliased attributes
      within a single annotation or an alias from an attribute in a custom
      composed annotation to an attribute in a meta-annotation.
      
      To support @AliasFor within annotation instances, AnnotationUtils has
      been overhauled to "synthesize" any annotations returned by "get" and
      "find" searches. A SynthesizedAnnotation is an annotation that is
      wrapped in a JDK dynamic proxy which provides run-time support for
      @AliasFor semantics. SynthesizedAnnotationInvocationHandler is the
      actual handler behind the proxy.
      
      In addition, the contract for @AliasFor is fully validated, and an
      AnnotationConfigurationException is thrown in case invalid
      configuration is detected.
      
      For example, @ContextConfiguration from the spring-test module is now
      declared as follows:
      
          public @interface ContextConfiguration {
      
              @AliasFor(attribute = "locations")
              String[] value() default {};
      
              @AliasFor(attribute = "value")
              String[] locations() default {};
      
              // ...
          }
      
      The following annotations and their related support classes have been
      modified to use @AliasFor.
      
      - @ManagedResource
      - @ContextConfiguration
      - @ActiveProfiles
      - @TestExecutionListeners
      - @TestPropertySource
      - @Sql
      - @ControllerAdvice
      - @RequestMapping
      
      Similarly, support for AnnotationAttributes has been reworked to
      support @AliasFor as well. This allows for fine-grained control over
      exactly which attributes are overridden within an annotation hierarchy.
      In fact, it is now possible to declare an alias for the 'value'
      attribute of a meta-annotation.
      
      For example, given the revised declaration of @ContextConfiguration
      above, one can now develop a composed annotation with a custom
      attribute override as follows.
      
          @ContextConfiguration
          public @interface MyTestConfig {
      
              @AliasFor(
                 annotation = ContextConfiguration.class,
                 attribute = "locations"
              )
              String[] xmlFiles();
      
              // ...
          }
      
      Consequently, the following are functionally equivalent.
      
      - @MyTestConfig(xmlFiles = "test.xml")
      - @ContextConfiguration("test.xml")
      - @ContextConfiguration(locations = "test.xml").
      
      Issue: SPR-11512, SPR-11513
      ca66e076
  10. 20 5月, 2015 1 次提交
  11. 19 5月, 2015 1 次提交
  12. 18 5月, 2015 2 次提交
  13. 17 5月, 2015 2 次提交
    • S
      Introduce TestContextManager cache in SpringClassRule · 973582e7
      Sam Brannen 提交于
      In order to simplify configuration of the SpringMethodRule and to ensure
      that the correct TestContextManager is always retrieved for the
      currently executing test class, this commit introduces a static
      TestContextManager cache in SpringClassRule.
      
      In addition, since it is not foreseen that SpringClassRule and
      SpringMethodRule should be able to be subclassed, their internal methods
      are now private instead of protected.
      
      Issue: SPR-7731
      973582e7
    • S
      Introduce JUnit Rule alternative to SpringJUnit4ClassRunner · d1b1c4f8
      Sam Brannen 提交于
      Since Spring Framework 2.5, support for integrating the Spring
      TestContext Framework (TCF) into JUnit 4 based tests has been provided
      via the SpringJUnit4ClassRunner, but this approach precludes the
      ability for tests to be run with alternative runners like JUnit's
      Parameterized or third-party runners such as the MockitoJUnitRunner.
      
      This commit remedies this situation by introducing @ClassRule and @Rule
      based alternatives to the SpringJUnit4ClassRunner. These rules are
      independent of any Runner and can therefore be combined with
      alternative runners.
      
      Due to the limitations of JUnit's implementation of rules, as of JUnit
      4.12 it is currently impossible to create a single rule that can be
      applied both at the class level and at the method level (with access to
      the test instance). Consequently, this commit introduces the following
      two rules that must be used together.
      
       - SpringClassRule: a JUnit TestRule that provides the class-level
         functionality of the TCF to JUnit-based tests
      
       - SpringMethodRule: a JUnit MethodRule that provides the
         instance-level and method-level functionality of the TCF to
         JUnit-based tests
      
      In addition, this commit also introduces the following new JUnit
      Statements for use with rules:
      
       - RunPrepareTestInstanceCallbacks
      
       - ProfileValueChecker
      
      Issue: SPR-7731
      d1b1c4f8
  14. 14 5月, 2015 1 次提交
  15. 12 5月, 2015 1 次提交
  16. 11 5月, 2015 1 次提交
  17. 26 4月, 2015 1 次提交
    • S
      Fail if multiple @BootstrapWith's are present · e85e9768
      Sam Brannen 提交于
      Prior to this commit it was possible for two @BootstrapWith annotations
      to be 'present' on a test class -- for example, via competing custom
      composed annotations. However, only one of the annotations will ever be
      used to bootstrap the TestContext Framework. Thus, in such scenarios
      one of the annotations will be silently ignored.
      
      This commit introduces a check for such scenarios. BootstrapUtils'
      resolveTestContextBootstrapper() method now throws an
      IllegalStateException if more than one @BootstrapWith annotation is
      'present' on a given test class.
      
      Issue: SPR-12602
      e85e9768
  18. 21 4月, 2015 1 次提交
  19. 20 4月, 2015 6 次提交
    • S
      Polish Javadoc for ContextCache · e829b2aa
      Sam Brannen 提交于
      e829b2aa
    • S
      Ensure that contexts loaded by the TCF are active · 93f403cb
      Sam Brannen 提交于
      This commit adds an assertion to DefaultTestContext's
      getApplicationContext() method to ensure that a context loaded by the
      Spring TestContext Framework (TCF) or retrieved from the ContextCache
      is still active. This extra check helps to avoid situations where
      developers manually close a cached context instead of relying on the
      @DirtiesContext support.
      
      Issue: SPR-12932
      93f403cb
    • S
      Use ConcurrentHashMaps in DefaultContextCache · d66d1605
      Sam Brannen 提交于
      The changes made in 0cb22fc8 would
      result in contexts not being properly closed if evicted from the
      ConcurrentReferenceHashMap by the Garbage Collector.
      
      This commit reverts those changes and returns to using standard
      ConcurrentHashMaps for the time being.
      
      Issue: SPR-7687
      d66d1605
    • S
      Introduce TestContextManager(TestContextBootstrapper) constructor · c52a0ccd
      Sam Brannen 提交于
      Issue: SPR-12683
      c52a0ccd
    • S
      Improve extensibility of TestContext bootstrapping & context caching · 129488cb
      Sam Brannen 提交于
       - DefaultBootstrapContext and DefaultCacheAwareContextLoaderDelegate
         are now public classes in the 'support' subpackage.
      
       - Introduced getCacheAwareContextLoaderDelegate() in
         AbstractTestContextBootstrapper as an extension point for configuring
         custom ContextCache support.
      
       - Introduced reflection-based createBootstrapContext() utility method
         in BootstrapUtils; TestContextManager now delegates to BootstrapUtils
         in order to avoid package cycles.
      
       - Introduced logStatistics() method in the ContextCache API and defined
         statistics logging category as a constant.
      
       - DefaultCacheAwareContextLoaderDelegate now delegates to
         ContextCache.logStatistics().
      
      Issue: SPR-12683
      129488cb
    • S
      Convert ContextCache to interface with default implementation · e6c24f71
      Sam Brannen 提交于
       - ContextCache is now a public interface.
      
       - Introduced public DefaultContextCache implementation in the 'support'
         subpackage.
      
      Issue: SPR-12683
      e6c24f71
  20. 19 4月, 2015 5 次提交
  21. 18 4月, 2015 2 次提交
    • S
      Use SoftReferences for context caching in the TCF · 0cb22fc8
      Sam Brannen 提交于
      Prior to this commit, the ContextCache in the Spring TestContext
      Framework (TCF) cached ApplicationContexts in a ConcurrentHashMap using
      strong references. This practice can occasionally lead to
      OutOfMemoryErrors when running a large number of tests in a test suite
      with varying context configuration since the context cache becomes
      overpopulated over time.
      
      This commit addresses this issue by using Spring's
      ConcurrentReferenceHashMap which uses SoftReferences for both the keys
      (i.e., MergedContextConfiguration instances) and values (i.e.,
      ApplicationContexts) stored in the map that backs the ContextCache.
      
      Issue: SPR-7687
      0cb22fc8
    • S
      Introduce reset() method in ContextCache · 2a4f4cd2
      Sam Brannen 提交于
      2a4f4cd2
  22. 15 4月, 2015 1 次提交
    • S
      Make AbsTstCtxBootstrapper.resolveContextLoader protected · c006b74e
      Sam Brannen 提交于
      This commit increases the extensibility of
      AbstractTestContextBootstrapper by making the resolveContextLoader()
      and resolveExplicitContextLoaderClass() methods protected instead of
      private.
      
      Furthermore, resolveContextLoader() now throws an IllegalStateException
      if getDefaultContextLoaderClass() returns null.
      
      Issue: SPR-12682
      c006b74e
  23. 23 3月, 2015 2 次提交
    • S
      Introduce BEFORE METHOD/CLASS modes in @DirtiesContext · e086a637
      Sam Brannen 提交于
      Prior to this commit, @DirtiesContext could only be used to close a
      test ApplicationContext after an entire test class or after a test
      method; however, there are some use cases for which it would be
      beneficial to close a test ApplicationContext before a given test class
      or test method -- for example, if some rogue (i.e., yet to be
      determined) test within a large test suite has corrupted the original
      configuration for the ApplicationContext.
      
      This commit provides a solution to such testing challenges by
      introducing the following modes for @DirtiesContext.
      
       - MethodMode.BEFORE_METHOD: configured via the new methodMode attribute
      
       - ClassMode.BEFORE_CLASS and ClassMode.BEFORE_EACH_TEST_METHOD: both
         configured via the existing classMode attribute
      
      Issue: SPR-12429
      e086a637
    • S
      Polish Javadoc for TestContext · 6028a644
      Sam Brannen 提交于
      6028a644
  24. 01 3月, 2015 2 次提交
    • S
      Simplify Groovy ContextLoaders in the TCF · e24a7ded
      Sam Brannen 提交于
      This commit simplifies the implementations of loadBeanDefinitions() in
      GenericGroovyXmlContextLoader and GenericGroovyXmlWebContextLoader.
      
      Due to the recent bug fix for GroovyBeanDefinitionReader regarding full
      support for XML config files, these Groovy context loaders can now
      simply use a GroovyBeanDefinitionReader instead of a
      GroovyBeanDefinitionReader plus an XmlBeanDefinitionReader.
      
      Issue: SPR-12769
      e24a7ded
    • S
      Support XML config fully in web integration tests · 2ba1151b
      Sam Brannen 提交于
      Prior to this commit, it was impossible to use all features of XML
      configuration (e.g., the <qualifier> tag) in web-based integration
      tests (loaded using @WebAppConfiguration, @ContextConfiguration, etc.)
      if the Groovy library was on the classpath. The reason is that the
      GroovyBeanDefinitionReader used internally by
      GenericGroovyXmlWebContextLoader disables XML validation for its
      internal XmlBeanDefinitionReader, and this prevents some XML
      configuration features from working properly. For example, the default
      value for the 'type' attribute (defined in the spring-beans XSD) of the
      <qualifier> tag gets ignored, resulting in an exception when the
      application context is loaded.
      
      This commit addresses this issue by refactoring the implementation of
      loadBeanDefinitions() in GenericGroovyXmlWebContextLoader to use an
      XmlBeanDefinitionReader or GroovyBeanDefinitionReader depending on the
      file extension of the resource location from which bean definitions
      should be loaded. This aligns the functionality of
      GenericGroovyXmlWebContextLoader with the existing functionality of
      GenericGroovyXmlContextLoader.
      
      Issue: SPR-12768
      2ba1151b