Skip to content

Commit

Permalink
Introduce Environment.matchesProfiles() for profile expressions
Browse files Browse the repository at this point in the history
Environment.acceptsProfiles(String...) was deprecated in 5.1 in
conjunction with gh-17063 which introduced a new
acceptsProfiles(Profiles) method to replace it. The deprecated method
only supports OR semantics; whereas, the new method supports profile
expressions. Thus, the goal was to encourage people to use the more
powerful profile expressions instead of the limited OR support with
profile names.

However, there are use cases where it is difficult (if not impossible)
to provide a Profiles instance, and there are use cases where it is
simply preferable to provide profile expressions directly as strings.

To address these issues, this commit introduces a new matchesProfiles()
method in Environment that accepts a var-args list of profile
expressions.

See gh-30206
Closes gh-30226
  • Loading branch information
sbrannen committed Apr 25, 2023
1 parent 2194487 commit 08fe123
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
*
* @author Chris Beams
* @author Phillip Webb
* @author Sam Brannen
* @since 3.1
* @see PropertyResolver
* @see EnvironmentCapable
Expand Down Expand Up @@ -109,20 +110,42 @@ public interface Environment extends PropertyResolver {
* whitespace only
* @see #getActiveProfiles
* @see #getDefaultProfiles
* @see #matchesProfiles(String...)
* @see #acceptsProfiles(Profiles)
* @deprecated as of 5.1 in favor of {@link #acceptsProfiles(Profiles)}
* @deprecated as of 5.1 in favor of {@link #acceptsProfiles(Profiles)} or
* {@link #matchesProfiles(String...)}
*/
@Deprecated
boolean acceptsProfiles(String... profiles);

/**
* Determine whether one of the given profile expressions matches the
* {@linkplain #getActiveProfiles() active profiles} — or in the case
* of no explicit active profiles, whether one of the given profile expressions
* matches the {@linkplain #getDefaultProfiles() default profiles}.
* <p>Profile expressions allow for complex, boolean profile logic to be
* expressed &mdash; for example {@code "p1 & p2"}, {@code "(p1 & p2) | p3"},
* etc. See {@link Profiles#of(String...)} for details on the supported
* expression syntax.
* <p>This method is a convenient shortcut for
* {@code env.acceptsProfiles(Profiles.of(profileExpressions))}.
* @since 5.3.28
* @see Profiles#of(String...)
* @see #acceptsProfiles(Profiles)
*/
default boolean matchesProfiles(String... profileExpressions) {
return acceptsProfiles(Profiles.of(profileExpressions));
}

/**
* Determine whether the given {@link Profiles} predicate matches the
* {@linkplain #getActiveProfiles() active profiles} &mdash; or in the case
* of no explicit active profiles, whether the given {@code Profiles} predicate
* matches the {@linkplain #getDefaultProfiles() default profiles}.
* <p>If you wish to check a single profile expression, consider using
* {@link #acceptsProfiles(String)} instead.
* <p>If you wish provide profile expressions directly as strings, use
* {@link #matchesProfiles(String...)} instead.
* @since 5.1
* @see #matchesProfiles(String...)
* @see Profiles#of(String...)
*/
boolean acceptsProfiles(Profiles profiles);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -541,4 +541,116 @@ void withProfileExpression() {

}

@Nested
class MatchesProfilesTests {

@Test
@SuppressWarnings("deprecation")
void withEmptyArgumentList() {
assertThatIllegalArgumentException().isThrownBy(environment::matchesProfiles);
}

@Test
@SuppressWarnings("deprecation")
void withNullArgumentList() {
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles((String[]) null));
}

@Test
@SuppressWarnings("deprecation")
void withNullArgument() {
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles((String) null));
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1", null));
}

@Test
@SuppressWarnings("deprecation")
void withEmptyArgument() {
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles(""));
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1", ""));
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1", " "));
}

@Test
@SuppressWarnings("deprecation")
void withInvalidNotOperator() {
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1", "!"));
}

@Test
@SuppressWarnings("deprecation")
void withInvalidCompoundExpressionGrouping() {
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1 | p2 & p3"));
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1 & p2 | p3"));
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1 & (p2 | p3) | p4"));
}

@Test
@SuppressWarnings("deprecation")
void activeProfileSetProgrammatically() {
assertThat(environment.matchesProfiles("p1", "p2")).isFalse();

environment.setActiveProfiles("p1");
assertThat(environment.matchesProfiles("p1", "p2")).isTrue();

environment.setActiveProfiles("p2");
assertThat(environment.matchesProfiles("p1", "p2")).isTrue();

environment.setActiveProfiles("p1", "p2");
assertThat(environment.matchesProfiles("p1", "p2")).isTrue();
}

@Test
@SuppressWarnings("deprecation")
void activeProfileSetViaProperty() {
assertThat(environment.matchesProfiles("p1")).isFalse();

environment.getPropertySources().addFirst(new MockPropertySource().withProperty(ACTIVE_PROFILES_PROPERTY_NAME, "p1"));
assertThat(environment.matchesProfiles("p1")).isTrue();
}

@Test
@SuppressWarnings("deprecation")
void defaultProfile() {
assertThat(environment.matchesProfiles("pd")).isFalse();

environment.setDefaultProfiles("pd");
assertThat(environment.matchesProfiles("pd")).isTrue();

environment.setActiveProfiles("p1");
assertThat(environment.matchesProfiles("pd")).isFalse();
assertThat(environment.matchesProfiles("p1")).isTrue();
}

@Test
@SuppressWarnings("deprecation")
void withNotOperator() {
assertThat(environment.matchesProfiles("p1")).isFalse();
assertThat(environment.matchesProfiles("!p1")).isTrue();

environment.addActiveProfile("p1");
assertThat(environment.matchesProfiles("p1")).isTrue();
assertThat(environment.matchesProfiles("!p1")).isFalse();
}

@Test
void withProfileExpressions() {
assertThat(environment.matchesProfiles("p1 & p2")).isFalse();

environment.addActiveProfile("p1");
assertThat(environment.matchesProfiles("p1 | p2")).isTrue();
assertThat(environment.matchesProfiles("p1 & p2")).isFalse();

environment.addActiveProfile("p2");
assertThat(environment.matchesProfiles("p1 & p2")).isTrue();
assertThat(environment.matchesProfiles("p1 | p2")).isTrue();
assertThat(environment.matchesProfiles("foo | p1", "p2")).isTrue();
assertThat(environment.matchesProfiles("foo | p2", "p1")).isTrue();
assertThat(environment.matchesProfiles("foo | (p2 & p1)")).isTrue();
assertThat(environment.matchesProfiles("p2 & (foo | p1)")).isTrue();
assertThat(environment.matchesProfiles("foo", "(p2 & p1)")).isTrue();
}

}

}

0 comments on commit 08fe123

Please sign in to comment.