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 @DisabledIf} is used to signal that the annotated test class or test
031 * method is <em>disabled</em> and should not 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 disabled 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 @DisabledOnMac} 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 @}DisabledIf(
047 *     expression = "#{systemProperties['os.name'].toLowerCase().contains('mac')}",
048 *     reason = "Disabled on Mac OS"
049 * )
050 * public {@literal @}interface DisabledOnMac {}
051 * </pre>
052 *
053 * @author Sam Brannen
054 * @author Tadaya Tsuyukubo
055 * @since 5.0
056 * @see SpringExtension
057 * @see EnabledIf
058 * @see org.junit.jupiter.api.Disabled
059 */
060@Target({ElementType.TYPE, ElementType.METHOD})
061@Retention(RetentionPolicy.RUNTIME)
062@Documented
063@ExtendWith(DisabledIfCondition.class)
064public @interface DisabledIf {
065
066        /**
067         * Alias for {@link #expression}; only intended to be used if {@link #reason}
068         * and {@link #loadContext} are not specified.
069         *
070         * @see #expression
071         */
072        @AliasFor("expression")
073        String value() default "";
074
075        /**
076         * The expression that will be evaluated to determine if the annotated test
077         * class or test method is <em>disabled</em>.
078         *
079         * <p>If the expression evaluates to {@link Boolean#TRUE} or a {@link String}
080         * equal to {@code "true"} (ignoring case), the test will be disabled.
081         *
082         * <p>Expressions can be any of the following.
083         *
084         * <ul>
085         * <li>Spring Expression Language (SpEL) expression &mdash; for example:
086         * <pre style="code">@DisabledIf("#{systemProperties['os.name'].toLowerCase().contains('mac')}")</pre>
087         * <li>Placeholder for a property available in the Spring
088         * {@link org.springframework.core.env.Environment Environment} &mdash; for example:
089         * <pre style="code">@DisabledIf("${smoke.tests.disabled}")</pre>
090         * <li>Text literal &mdash; for example:
091         * <pre style="code">@DisabledIf("true")</pre>
092         * </ul>
093         *
094         * <p>Note, however, that a <em>text literal</em> which is not the result of
095         * dynamic resolution of a property placeholder is of zero practical value
096         * since {@code @DisabledIf("true")} is equivalent to {@code @Disabled}
097         * and {@code @DisabledIf("false")} is logically meaningless.
098         *
099         * @see #reason
100         * @see #loadContext
101         * @see #value
102         */
103        @AliasFor("value")
104        String expression() default "";
105
106        /**
107         * The reason this test is disabled.
108         *
109         * @see #expression
110         */
111        String reason() default "";
112
113        /**
114         * Whether the {@code ApplicationContext} associated with the current test
115         * should be eagerly loaded in order to evaluate the {@link #expression}.
116         *
117         * <p>Defaults to {@code false} so that test application contexts are not
118         * eagerly loaded unnecessarily. If an expression is based solely on system
119         * properties or environment variables or does not interact with beans in
120         * the test's application context, there is no need to load the context
121         * prematurely since doing so would be a waste of time if the test ends up
122         * being disabled.
123         *
124         * @see #expression
125         */
126        boolean loadContext() default false;
127
128}