001/* 002 * Copyright 2002-2019 the original author or authors. 003 * 004 * Licensed under the Apache 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 * https://www.apache.org/licenses/LICENSE-2.0 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 017package org.springframework.test.context.junit.jupiter; 018 019import java.lang.annotation.Documented; 020import java.lang.annotation.ElementType; 021import java.lang.annotation.Retention; 022import java.lang.annotation.RetentionPolicy; 023import java.lang.annotation.Target; 024 025import org.junit.jupiter.api.extension.ExtendWith; 026 027import org.springframework.core.annotation.AliasFor; 028 029/** 030 * {@code @EnabledIf} is used to signal that the annotated test class or test 031 * method is <em>enabled</em> and should be executed if the supplied 032 * {@link #expression} evaluates to {@code true}. 033 * 034 * <p>When applied at the class level, all test methods within that class 035 * are automatically enabled by default as well. 036 * 037 * <p>For basic examples, see the Javadoc for {@link #expression}. 038 * 039 * <p>This annotation may be used as a <em>meta-annotation</em> to create 040 * custom <em>composed annotations</em>. For example, a custom 041 * {@code @EnabledOnMac} annotation can be created as follows. 042 * 043 * <pre style="code"> 044 * {@literal @}Target({ElementType.TYPE, ElementType.METHOD}) 045 * {@literal @}Retention(RetentionPolicy.RUNTIME) 046 * {@literal @}EnabledIf( 047 * expression = "#{systemProperties['os.name'].toLowerCase().contains('mac')}", 048 * reason = "Enabled on Mac OS" 049 * ) 050 * public {@literal @}interface EnabledOnMac {} 051 * </pre> 052 * 053 * @author Sam Brannen 054 * @since 5.0 055 * @see SpringExtension 056 * @see DisabledIf 057 * @see org.junit.jupiter.api.Disabled 058 */ 059@Target({ElementType.TYPE, ElementType.METHOD}) 060@Retention(RetentionPolicy.RUNTIME) 061@Documented 062@ExtendWith(EnabledIfCondition.class) 063public @interface EnabledIf { 064 065 /** 066 * Alias for {@link #expression}; only intended to be used if {@link #reason} 067 * and {@link #loadContext} are not specified. 068 * 069 * @see #expression 070 */ 071 @AliasFor("expression") 072 String value() default ""; 073 074 /** 075 * The expression that will be evaluated to determine if the annotated test 076 * class or test method is <em>enabled</em>. 077 * 078 * <p>If the expression evaluates to {@link Boolean#TRUE} or a {@link String} 079 * equal to {@code "true"} (ignoring case), the test will be enabled. 080 * 081 * <p>Expressions can be any of the following. 082 * 083 * <ul> 084 * <li>Spring Expression Language (SpEL) expression — for example: 085 * <pre style="code">@EnabledIf("#{systemProperties['os.name'].toLowerCase().contains('mac')}")</pre> 086 * <li>Placeholder for a property available in the Spring 087 * {@link org.springframework.core.env.Environment Environment} — for example: 088 * <pre style="code">@EnabledIf("${smoke.tests.enabled}")</pre> 089 * <li>Text literal — for example: 090 * <pre style="code">@EnabledIf("true")</pre> 091 * </ul> 092 * 093 * <p>Note, however, that a <em>text literal</em> which is not the result of 094 * dynamic resolution of a property placeholder is of zero practical value 095 * since {@code @EnabledIf("false")} is equivalent to {@code @Disabled} 096 * and {@code @EnabledIf("true")} is logically meaningless. 097 * 098 * @see #reason 099 * @see #loadContext 100 * @see #value 101 */ 102 @AliasFor("value") 103 String expression() default ""; 104 105 /** 106 * The reason this test is enabled. 107 * 108 * @see #expression 109 */ 110 String reason() default ""; 111 112 /** 113 * Whether the {@code ApplicationContext} associated with the current test 114 * should be eagerly loaded in order to evaluate the {@link #expression}. 115 * 116 * <p>Defaults to {@code false} so that test application contexts are not 117 * eagerly loaded unnecessarily. If an expression is based solely on system 118 * properties or environment variables or does not interact with beans in 119 * the test's application context, there is no need to load the context 120 * prematurely since doing so would be a waste of time if the test ends up 121 * being disabled. 122 * 123 * @see #expression 124 */ 125 boolean loadContext() default false; 126 127}