diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/ContextCache.java b/org.springframework.test/src/main/java/org/springframework/test/context/ContextCache.java index 581ee58824a..9997433d0ca 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/ContextCache.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/ContextCache.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2011 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. @@ -16,7 +16,6 @@ package org.springframework.test.context; -import java.io.Serializable; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -29,8 +28,8 @@ import org.springframework.util.Assert; * Cache for Spring {@link ApplicationContext ApplicationContexts} * in a test environment. * - *

Maintains a cache of {@link ApplicationContext contexts} by - * {@link Serializable serializable} key. This has significant performance + *

Maintains a cache of {@link ApplicationContext contexts} keyed by + * {@link MergedContextConfiguration} instances. This has significant performance * benefits if initializing the context would take time. While initializing a * Spring context itself is very quick, some beans in a context, such as a * {@link org.springframework.orm.hibernate3.LocalSessionFactoryBean LocalSessionFactoryBean} @@ -46,7 +45,7 @@ class ContextCache { /** * Map of context keys to Spring ApplicationContext instances. */ - private final Map contextKeyToContextMap = new ConcurrentHashMap(); + private final Map contextMap = new ConcurrentHashMap(); private int hitCount; @@ -57,7 +56,7 @@ class ContextCache { * Clears all contexts from the cache. */ void clear() { - this.contextKeyToContextMap.clear(); + this.contextMap.clear(); } /** @@ -73,9 +72,9 @@ class ContextCache { * Return whether there is a cached context for the given key. * @param key the context key (never null) */ - boolean contains(String key) { + boolean contains(MergedContextConfiguration key) { Assert.notNull(key, "Key must not be null"); - return this.contextKeyToContextMap.containsKey(key); + return this.contextMap.containsKey(key); } /** @@ -87,9 +86,9 @@ class ContextCache { * or null if not found in the cache. * @see #remove */ - ApplicationContext get(String key) { + ApplicationContext get(MergedContextConfiguration key) { Assert.notNull(key, "Key must not be null"); - ApplicationContext context = this.contextKeyToContextMap.get(key); + ApplicationContext context = this.contextMap.get(key); if (context == null) { incrementMissCount(); } @@ -137,10 +136,10 @@ class ContextCache { * @param key the context key (never null) * @param context the ApplicationContext instance (never null) */ - void put(String key, ApplicationContext context) { + void put(MergedContextConfiguration key, ApplicationContext context) { Assert.notNull(key, "Key must not be null"); Assert.notNull(context, "ApplicationContext must not be null"); - this.contextKeyToContextMap.put(key, context); + this.contextMap.put(key, context); } /** @@ -150,8 +149,8 @@ class ContextCache { * or null if not found in the cache. * @see #setDirty */ - ApplicationContext remove(String key) { - return this.contextKeyToContextMap.remove(key); + ApplicationContext remove(MergedContextConfiguration key) { + return this.contextMap.remove(key); } /** @@ -165,7 +164,7 @@ class ContextCache { * @param key the context key (never null) * @see #remove */ - void setDirty(String key) { + void setDirty(MergedContextConfiguration key) { Assert.notNull(key, "Key must not be null"); ApplicationContext context = remove(key); if (context instanceof ConfigurableApplicationContext) { @@ -179,7 +178,7 @@ class ContextCache { * Integer.MAX_VALUE. */ int size() { - return this.contextKeyToContextMap.size(); + return this.contextMap.size(); } /** diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java b/org.springframework.test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java index c64efab2f23..10d04c7e7d1 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java @@ -16,6 +16,7 @@ package org.springframework.test.context; +import java.io.Serializable; import java.util.Arrays; import java.util.SortedSet; import java.util.TreeSet; @@ -25,7 +26,7 @@ import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; /** - * MergedContextConfiguration encapsulates the merged + * {@code MergedContextConfiguration} encapsulates the merged * context configuration declared on a test class and all of its superclasses * via {@link ContextConfiguration @ContextConfiguration} and * {@link ActiveProfiles @ActiveProfiles}. @@ -37,9 +38,14 @@ import org.springframework.util.StringUtils; * {@link ActiveProfiles#inheritProfiles inheritProfiles} flags in * {@code @ContextConfiguration} and {@code @ActiveProfiles}, respectively. * - *

A {@link SmartContextLoader} uses MergedContextConfiguration + *

A {@link SmartContextLoader} uses {@code MergedContextConfiguration} * to load an {@link org.springframework.context.ApplicationContext ApplicationContext}. * + *

{@code MergedContextConfiguration} is also used by the {@link TestContext} + * as the context cache key for caching an + * {@link org.springframework.context.ApplicationContext ApplicationContext} + * that was loaded using properties of this {@code MergedContextConfiguration}. + * * @author Sam Brannen * @since 3.1 * @see ContextConfiguration @@ -47,23 +53,19 @@ import org.springframework.util.StringUtils; * @see ContextConfigurationAttributes * @see SmartContextLoader#loadContext(MergedContextConfiguration) */ -public class MergedContextConfiguration { +public class MergedContextConfiguration implements Serializable { + + private static final long serialVersionUID = -3290560718464957422L; private static final String[] EMPTY_STRING_ARRAY = new String[0]; private static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; private final Class testClass; - private final String[] locations; - private final Class[] classes; - private final String[] activeProfiles; - private final ContextLoader contextLoader; - private final String contextKey; - private static String[] processLocations(String[] locations) { return locations == null ? EMPTY_STRING_ARRAY : locations; @@ -86,29 +88,16 @@ public class MergedContextConfiguration { } /** - * Generate a null-safe {@link String} representation of the supplied {@link ContextLoader}. + * Generate a null-safe {@link String} representation of the supplied + * {@link ContextLoader} based solely on the fully qualified name of the + * loader or "null" if the supplied loaded is null. */ private static String nullSafeToString(ContextLoader contextLoader) { return contextLoader == null ? "null" : contextLoader.getClass().getName(); } /** - * Generate a context key from the supplied values. - */ - private static String generateContextKey(String[] locations, Class[] classes, String[] activeProfiles, - ContextLoader contextLoader) { - - String locationsKey = ObjectUtils.nullSafeToString(locations); - String classesKey = ObjectUtils.nullSafeToString(classes); - String activeProfilesKey = ObjectUtils.nullSafeToString(activeProfiles); - String contextLoaderKey = nullSafeToString(contextLoader); - - return String.format("locations = %s, classes = %s, activeProfiles = %s, contextLoader = %s", locationsKey, - classesKey, activeProfilesKey, contextLoaderKey); - } - - /** - * Create a new MergedContextConfiguration instance for the + * Create a new {@code MergedContextConfiguration} instance for the * supplied {@link Class test class}, resource locations, configuration * classes, active profiles, and {@link ContextLoader}. *

If a null value is supplied for locations, @@ -128,12 +117,11 @@ public class MergedContextConfiguration { this.classes = processClasses(classes); this.activeProfiles = processActiveProfiles(activeProfiles); this.contextLoader = contextLoader; - this.contextKey = generateContextKey(this.locations, this.classes, this.activeProfiles, this.contextLoader); } /** * Get the {@link Class test class} associated with this - * MergedContextConfiguration. + * {@code MergedContextConfiguration}. */ public Class getTestClass() { return testClass; @@ -172,20 +160,59 @@ public class MergedContextConfiguration { } /** - * Get the unique context key for all properties of this - * MergedContextConfiguration excluding the - * {@link #getTestClass() test class}. - *

Intended to be used for caching an - * {@link org.springframework.context.ApplicationContext ApplicationContext} - * that was loaded using properties of this MergedContextConfiguration. + * Generate a unique hash code for all properties of this + * {@code MergedContextConfiguration} excluding the + * {@link #getTestClass() test class}. + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(locations); + result = prime * result + Arrays.hashCode(classes); + result = prime * result + Arrays.hashCode(activeProfiles); + result = prime * result + nullSafeToString(contextLoader).hashCode(); + return result; + } + + /** + * TODO Document equals() implementation. + * + * @see java.lang.Object#equals(java.lang.Object) */ - public String getContextKey() { - return contextKey; + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + if (!(obj instanceof MergedContextConfiguration)) { + return false; + } + + final MergedContextConfiguration that = (MergedContextConfiguration) obj; + + if (!Arrays.equals(this.locations, that.locations)) { + return false; + } + if (!Arrays.equals(this.classes, that.classes)) { + return false; + } + if (!Arrays.equals(this.activeProfiles, that.activeProfiles)) { + return false; + } + if (!nullSafeToString(this.contextLoader).equals(nullSafeToString(that.contextLoader))) { + return false; + } + + return true; } /** - * Provide a String representation of the test class, merged context - * configuration, and context key. + * Provide a String representation of the {@link #getTestClass() test class}, + * {@link #getLocations() locations}, {@link #getClasses() configuration classes}, + * {@link #getActiveProfiles() active profiles}, and the name of the + * {@link #getContextLoader() ContextLoader}. */ @Override public String toString() { @@ -195,7 +222,6 @@ public class MergedContextConfiguration { .append("classes", ObjectUtils.nullSafeToString(classes))// .append("activeProfiles", ObjectUtils.nullSafeToString(activeProfiles))// .append("contextLoader", nullSafeToString(contextLoader))// - .append("contextKey", contextKey)// .toString(); } diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/TestContext.java b/org.springframework.test/src/main/java/org/springframework/test/context/TestContext.java index 0d3704ed288..5e734bba8e9 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/TestContext.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/TestContext.java @@ -61,6 +61,7 @@ public class TestContext extends AttributeAccessorSupport { this(testClass, contextCache, null); } + // TODO Update regarding default --> DelegatingSmartContextLoader /** * Construct a new test context for the supplied {@link Class test class} * and {@link ContextCache context cache} and parse the corresponding @@ -141,18 +142,17 @@ public class TestContext extends AttributeAccessorSupport { * application context */ public ApplicationContext getApplicationContext() { - String contextKey = mergedContextConfiguration.getContextKey(); synchronized (contextCache) { - ApplicationContext context = contextCache.get(contextKey); + ApplicationContext context = contextCache.get(mergedContextConfiguration); if (context == null) { try { context = loadApplicationContext(); if (logger.isDebugEnabled()) { logger.debug(String.format( "Storing ApplicationContext for test class [%s] in cache under key [%s].", testClass, - contextKey)); + mergedContextConfiguration)); } - contextCache.put(contextKey, context); + contextCache.put(mergedContextConfiguration, context); } catch (Exception ex) { throw new IllegalStateException("Failed to load ApplicationContext", ex); @@ -162,7 +162,7 @@ public class TestContext extends AttributeAccessorSupport { if (logger.isDebugEnabled()) { logger.debug(String.format( "Retrieved ApplicationContext for test class [%s] from cache with key [%s].", testClass, - contextKey)); + mergedContextConfiguration)); } } return context; @@ -217,7 +217,7 @@ public class TestContext extends AttributeAccessorSupport { */ public void markApplicationContextDirty() { synchronized (contextCache) { - contextCache.setDirty(mergedContextConfiguration.getContextKey()); + contextCache.setDirty(mergedContextConfiguration); } } diff --git a/org.springframework.test/src/test/java/org/springframework/test/context/MergedContextConfigurationTests.java b/org.springframework.test/src/test/java/org/springframework/test/context/MergedContextConfigurationTests.java new file mode 100644 index 00000000000..cccd28541c3 --- /dev/null +++ b/org.springframework.test/src/test/java/org/springframework/test/context/MergedContextConfigurationTests.java @@ -0,0 +1,283 @@ +/* + * Copyright 2002-2011 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.context; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.springframework.test.context.support.AnnotationConfigContextLoader; +import org.springframework.test.context.support.GenericXmlContextLoader; + +/** + * Unit tests for {@link MergedContextConfiguration}. + * + * @author Sam Brannen + * @since 3.1 + */ +public class MergedContextConfigurationTests { + + private static final String[] EMPTY_STRING_ARRAY = new String[0]; + private static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; + + private final GenericXmlContextLoader loader = new GenericXmlContextLoader(); + + + @Test + public void hashCodeWithNulls() { + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(null, null, null, null, null); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(null, null, null, null, null); + assertEquals(mergedConfig1.hashCode(), mergedConfig2.hashCode()); + } + + @Test + public void hashCodeWithNullArrays() { + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), null, null, null, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), null, null, null, loader); + assertEquals(mergedConfig1.hashCode(), mergedConfig2.hashCode()); + } + + @Test + public void hashCodeWithEmptyArrays() { + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, loader); + assertEquals(mergedConfig1.hashCode(), mergedConfig2.hashCode()); + } + + @Test + public void hashCodeWithEmptyArraysAndDifferentLoaders() { + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, new AnnotationConfigContextLoader()); + assertFalse(mergedConfig1.hashCode() == mergedConfig2.hashCode()); + } + + @Test + public void hashCodeWithSameLocations() { + String[] locations = new String[] { "foo", "bar}" }; + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), locations, + EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), locations, + EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, loader); + assertEquals(mergedConfig1.hashCode(), mergedConfig2.hashCode()); + } + + @Test + public void hashCodeWithDifferentLocations() { + String[] locations1 = new String[] { "foo", "bar}" }; + String[] locations2 = new String[] { "baz", "quux}" }; + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), locations1, + EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), locations2, + EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, loader); + assertFalse(mergedConfig1.hashCode() == mergedConfig2.hashCode()); + } + + @Test + public void hashCodeWithSameConfigClasses() { + Class[] classes = new Class[] { String.class, Integer.class }; + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + classes, EMPTY_STRING_ARRAY, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + classes, EMPTY_STRING_ARRAY, loader); + assertEquals(mergedConfig1.hashCode(), mergedConfig2.hashCode()); + } + + @Test + public void hashCodeWithDifferentConfigClasses() { + Class[] classes1 = new Class[] { String.class, Integer.class }; + Class[] classes2 = new Class[] { Boolean.class, Number.class }; + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + classes1, EMPTY_STRING_ARRAY, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + classes2, EMPTY_STRING_ARRAY, loader); + assertFalse(mergedConfig1.hashCode() == mergedConfig2.hashCode()); + } + + @Test + public void hashCodeWithSameProfiles() { + String[] activeProfiles = new String[] { "catbert", "dogbert" }; + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, activeProfiles, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, activeProfiles, loader); + assertEquals(mergedConfig1.hashCode(), mergedConfig2.hashCode()); + } + + @Test + public void hashCodeWithSameProfilesReversed() { + String[] activeProfiles1 = new String[] { "catbert", "dogbert" }; + String[] activeProfiles2 = new String[] { "dogbert", "catbert" }; + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, activeProfiles1, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, activeProfiles2, loader); + assertEquals(mergedConfig1.hashCode(), mergedConfig2.hashCode()); + } + + @Test + public void hashCodeWithSameDuplicateProfiles() { + String[] activeProfiles1 = new String[] { "catbert", "dogbert" }; + String[] activeProfiles2 = new String[] { "catbert", "dogbert", "catbert", "dogbert", "catbert" }; + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, activeProfiles1, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, activeProfiles2, loader); + assertEquals(mergedConfig1.hashCode(), mergedConfig2.hashCode()); + } + + @Test + public void hashCodeWithDifferentProfiles() { + String[] activeProfiles1 = new String[] { "catbert", "dogbert" }; + String[] activeProfiles2 = new String[] { "X", "Y" }; + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, activeProfiles1, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, activeProfiles2, loader); + assertFalse(mergedConfig1.hashCode() == mergedConfig2.hashCode()); + } + + @Test + public void equalsBasics() { + MergedContextConfiguration mergedConfig = new MergedContextConfiguration(null, null, null, null, null); + assertTrue(mergedConfig.equals(mergedConfig)); + assertFalse(mergedConfig.equals(null)); + assertFalse(mergedConfig.equals(new Integer(1))); + } + + @Test + public void equalsWithNulls() { + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(null, null, null, null, null); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(null, null, null, null, null); + assertEquals(mergedConfig1, mergedConfig2); + } + + @Test + public void equalsWithNullArrays() { + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), null, null, null, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), null, null, null, loader); + assertEquals(mergedConfig1, mergedConfig2); + } + + @Test + public void equalsWithEmptyArrays() { + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, loader); + assertEquals(mergedConfig1, mergedConfig2); + } + + @Test + public void equalsWithEmptyArraysAndDifferentLoaders() { + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, new AnnotationConfigContextLoader()); + assertFalse(mergedConfig1.equals(mergedConfig2)); + } + + @Test + public void equalsWithSameLocations() { + String[] locations = new String[] { "foo", "bar}" }; + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), locations, + EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), locations, + EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, loader); + assertEquals(mergedConfig1, mergedConfig2); + } + + @Test + public void equalsWithDifferentLocations() { + String[] locations1 = new String[] { "foo", "bar}" }; + String[] locations2 = new String[] { "baz", "quux}" }; + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), locations1, + EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), locations2, + EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, loader); + assertFalse(mergedConfig1.equals(mergedConfig2)); + } + + @Test + public void equalsWithSameConfigClasses() { + Class[] classes = new Class[] { String.class, Integer.class }; + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + classes, EMPTY_STRING_ARRAY, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + classes, EMPTY_STRING_ARRAY, loader); + assertEquals(mergedConfig1, mergedConfig2); + } + + @Test + public void equalsWithDifferentConfigClasses() { + Class[] classes1 = new Class[] { String.class, Integer.class }; + Class[] classes2 = new Class[] { Boolean.class, Number.class }; + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + classes1, EMPTY_STRING_ARRAY, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + classes2, EMPTY_STRING_ARRAY, loader); + assertFalse(mergedConfig1.equals(mergedConfig2)); + } + + @Test + public void equalsWithSameProfiles() { + String[] activeProfiles = new String[] { "catbert", "dogbert" }; + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, activeProfiles, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, activeProfiles, loader); + assertEquals(mergedConfig1, mergedConfig2); + } + + @Test + public void equalsWithSameProfilesReversed() { + String[] activeProfiles1 = new String[] { "catbert", "dogbert" }; + String[] activeProfiles2 = new String[] { "dogbert", "catbert" }; + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, activeProfiles1, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, activeProfiles2, loader); + assertEquals(mergedConfig1, mergedConfig2); + } + + @Test + public void equalsWithSameDuplicateProfiles() { + String[] activeProfiles1 = new String[] { "catbert", "dogbert" }; + String[] activeProfiles2 = new String[] { "catbert", "dogbert", "catbert", "dogbert", "catbert" }; + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, activeProfiles1, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, activeProfiles2, loader); + assertEquals(mergedConfig1, mergedConfig2); + } + + @Test + public void equalsWithDifferentProfiles() { + String[] activeProfiles1 = new String[] { "catbert", "dogbert" }; + String[] activeProfiles2 = new String[] { "X", "Y" }; + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, activeProfiles1, loader); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, activeProfiles2, loader); + assertFalse(mergedConfig1.equals(mergedConfig2)); + } + +}