Make Profiles created via Profiles.of() comparable

Prior to this commit, a Profiles instance created via Profiles.of() was
not considered equivalent to another Profiles instance created via
Profiles.of() with the exact same expressions. This makes it difficult
to mock invocations of Environment#acceptsProfiles(Profiles) -- for
example, when using a mocking library such as Mockito.

This commit makes Profiles instances created via Profiles.of()
"comparable" by implementing equals() and hashCode() in ParsedProfiles.

Note, however, that equivalence is only guaranteed if the exact same
profile expression strings are supplied to Profiles.of(). In other
words, Profiles.of("A & B", "C | D") is equivalent to
Profiles.of("A & B", "C | D") and Profiles.of("C | D", "A & B"), but
Profiles.of("X & Y") is not equivalent to Profiles.of("X&Y") or
Profiles.of("Y & X").

Closes gh-25340
This commit is contained in:
Sam Brannen
2020-07-07 11:49:40 +02:00
parent 8734c64b75
commit 2c9e794676
3 changed files with 107 additions and 14 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -288,10 +288,72 @@ class ProfilesTests {
@Test
void sensibleToString() {
assertThat(Profiles.of("spring & framework", "java | kotlin").toString()).isEqualTo("spring & framework or java | kotlin");
assertThat(Profiles.of("spring")).hasToString("spring");
assertThat(Profiles.of("(spring & framework) | (spring & java)")).hasToString("(spring & framework) | (spring & java)");
assertThat(Profiles.of("(spring&framework)|(spring&java)")).hasToString("(spring&framework)|(spring&java)");
assertThat(Profiles.of("spring & framework", "java | kotlin")).hasToString("spring & framework or java | kotlin");
assertThat(Profiles.of("java | kotlin", "spring & framework")).hasToString("java | kotlin or spring & framework");
}
private void assertMalformed(Supplier<Profiles> supplier) {
@Test
void sensibleEquals() {
assertEqual("(spring & framework) | (spring & java)");
assertEqual("(spring&framework)|(spring&java)");
assertEqual("spring & framework", "java | kotlin");
// Ensure order of individual expressions does not affect equals().
String expression1 = "A | B";
String expression2 = "C & (D | E)";
Profiles profiles1 = Profiles.of(expression1, expression2);
Profiles profiles2 = Profiles.of(expression2, expression1);
assertThat(profiles1).isEqualTo(profiles2);
assertThat(profiles2).isEqualTo(profiles1);
}
private void assertEqual(String... expressions) {
Profiles profiles1 = Profiles.of(expressions);
Profiles profiles2 = Profiles.of(expressions);
assertThat(profiles1).isEqualTo(profiles2);
assertThat(profiles2).isEqualTo(profiles1);
}
@Test
void sensibleHashCode() {
assertHashCode("(spring & framework) | (spring & java)");
assertHashCode("(spring&framework)|(spring&java)");
assertHashCode("spring & framework", "java | kotlin");
// Ensure order of individual expressions does not affect hashCode().
String expression1 = "A | B";
String expression2 = "C & (D | E)";
Profiles profiles1 = Profiles.of(expression1, expression2);
Profiles profiles2 = Profiles.of(expression2, expression1);
assertThat(profiles1).hasSameHashCodeAs(profiles2);
}
private void assertHashCode(String... expressions) {
Profiles profiles1 = Profiles.of(expressions);
Profiles profiles2 = Profiles.of(expressions);
assertThat(profiles1).hasSameHashCodeAs(profiles2);
}
@Test
void equalsAndHashCodeAreNotBasedOnLogicalStructureOfNodesWithinExpressionTree() {
Profiles profiles1 = Profiles.of("A | B");
Profiles profiles2 = Profiles.of("B | A");
assertThat(profiles1.matches(activeProfiles("A"))).isTrue();
assertThat(profiles1.matches(activeProfiles("B"))).isTrue();
assertThat(profiles2.matches(activeProfiles("A"))).isTrue();
assertThat(profiles2.matches(activeProfiles("B"))).isTrue();
assertThat(profiles1).isNotEqualTo(profiles2);
assertThat(profiles2).isNotEqualTo(profiles1);
assertThat(profiles1.hashCode()).isNotEqualTo(profiles2.hashCode());
}
private static void assertMalformed(Supplier<Profiles> supplier) {
assertThatIllegalArgumentException().isThrownBy(
supplier::get)
.withMessageContaining("Malformed");