[SPR-8549] ContextCache is now keyed by MergedContextConfiguration instead of String; MergedContextConfiguration now implements custom hashCode() and equals() methods and no longer generates a context cache key.

This commit is contained in:
Sam Brannen 2011-07-20 22:06:05 +00:00
parent 2d7af57149
commit 8224af1938
4 changed files with 369 additions and 61 deletions

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,7 +16,6 @@
package org.springframework.test.context; package org.springframework.test.context;
import java.io.Serializable;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -29,8 +28,8 @@ import org.springframework.util.Assert;
* Cache for Spring {@link ApplicationContext ApplicationContexts} * Cache for Spring {@link ApplicationContext ApplicationContexts}
* in a test environment. * in a test environment.
* *
* <p>Maintains a cache of {@link ApplicationContext contexts} by * <p>Maintains a cache of {@link ApplicationContext contexts} keyed by
* {@link Serializable serializable} key. This has significant performance * {@link MergedContextConfiguration} instances. This has significant performance
* benefits if initializing the context would take time. While initializing a * 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 * Spring context itself is very quick, some beans in a context, such as a
* {@link org.springframework.orm.hibernate3.LocalSessionFactoryBean LocalSessionFactoryBean} * {@link org.springframework.orm.hibernate3.LocalSessionFactoryBean LocalSessionFactoryBean}
@ -46,7 +45,7 @@ class ContextCache {
/** /**
* Map of context keys to Spring ApplicationContext instances. * Map of context keys to Spring ApplicationContext instances.
*/ */
private final Map<String, ApplicationContext> contextKeyToContextMap = new ConcurrentHashMap<String, ApplicationContext>(); private final Map<MergedContextConfiguration, ApplicationContext> contextMap = new ConcurrentHashMap<MergedContextConfiguration, ApplicationContext>();
private int hitCount; private int hitCount;
@ -57,7 +56,7 @@ class ContextCache {
* Clears all contexts from the cache. * Clears all contexts from the cache.
*/ */
void clear() { 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. * Return whether there is a cached context for the given key.
* @param key the context key (never <code>null</code>) * @param key the context key (never <code>null</code>)
*/ */
boolean contains(String key) { boolean contains(MergedContextConfiguration key) {
Assert.notNull(key, "Key must not be null"); 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 <code>null</code> if not found in the cache. * or <code>null</code> if not found in the cache.
* @see #remove * @see #remove
*/ */
ApplicationContext get(String key) { ApplicationContext get(MergedContextConfiguration key) {
Assert.notNull(key, "Key must not be null"); Assert.notNull(key, "Key must not be null");
ApplicationContext context = this.contextKeyToContextMap.get(key); ApplicationContext context = this.contextMap.get(key);
if (context == null) { if (context == null) {
incrementMissCount(); incrementMissCount();
} }
@ -137,10 +136,10 @@ class ContextCache {
* @param key the context key (never <code>null</code>) * @param key the context key (never <code>null</code>)
* @param context the ApplicationContext instance (never <code>null</code>) * @param context the ApplicationContext instance (never <code>null</code>)
*/ */
void put(String key, ApplicationContext context) { void put(MergedContextConfiguration key, ApplicationContext context) {
Assert.notNull(key, "Key must not be null"); Assert.notNull(key, "Key must not be null");
Assert.notNull(context, "ApplicationContext 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 <code>null</code> if not found in the cache. * or <code>null</code> if not found in the cache.
* @see #setDirty * @see #setDirty
*/ */
ApplicationContext remove(String key) { ApplicationContext remove(MergedContextConfiguration key) {
return this.contextKeyToContextMap.remove(key); return this.contextMap.remove(key);
} }
/** /**
@ -165,7 +164,7 @@ class ContextCache {
* @param key the context key (never <code>null</code>) * @param key the context key (never <code>null</code>)
* @see #remove * @see #remove
*/ */
void setDirty(String key) { void setDirty(MergedContextConfiguration key) {
Assert.notNull(key, "Key must not be null"); Assert.notNull(key, "Key must not be null");
ApplicationContext context = remove(key); ApplicationContext context = remove(key);
if (context instanceof ConfigurableApplicationContext) { if (context instanceof ConfigurableApplicationContext) {
@ -179,7 +178,7 @@ class ContextCache {
* <tt>Integer.MAX_VALUE</tt>. * <tt>Integer.MAX_VALUE</tt>.
*/ */
int size() { int size() {
return this.contextKeyToContextMap.size(); return this.contextMap.size();
} }
/** /**

View File

@ -16,6 +16,7 @@
package org.springframework.test.context; package org.springframework.test.context;
import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
@ -25,7 +26,7 @@ import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
* <code>MergedContextConfiguration</code> encapsulates the <em>merged</em> * {@code MergedContextConfiguration} encapsulates the <em>merged</em>
* context configuration declared on a test class and all of its superclasses * context configuration declared on a test class and all of its superclasses
* via {@link ContextConfiguration @ContextConfiguration} and * via {@link ContextConfiguration @ContextConfiguration} and
* {@link ActiveProfiles @ActiveProfiles}. * {@link ActiveProfiles @ActiveProfiles}.
@ -37,9 +38,14 @@ import org.springframework.util.StringUtils;
* {@link ActiveProfiles#inheritProfiles inheritProfiles} flags in * {@link ActiveProfiles#inheritProfiles inheritProfiles} flags in
* {@code @ContextConfiguration} and {@code @ActiveProfiles}, respectively. * {@code @ContextConfiguration} and {@code @ActiveProfiles}, respectively.
* *
* <p>A {@link SmartContextLoader} uses <code>MergedContextConfiguration</code> * <p>A {@link SmartContextLoader} uses {@code MergedContextConfiguration}
* to load an {@link org.springframework.context.ApplicationContext ApplicationContext}. * to load an {@link org.springframework.context.ApplicationContext ApplicationContext}.
* *
* <p>{@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 * @author Sam Brannen
* @since 3.1 * @since 3.1
* @see ContextConfiguration * @see ContextConfiguration
@ -47,23 +53,19 @@ import org.springframework.util.StringUtils;
* @see ContextConfigurationAttributes * @see ContextConfigurationAttributes
* @see SmartContextLoader#loadContext(MergedContextConfiguration) * @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 String[] EMPTY_STRING_ARRAY = new String[0];
private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0]; private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
private final Class<?> testClass; private final Class<?> testClass;
private final String[] locations; private final String[] locations;
private final Class<?>[] classes; private final Class<?>[] classes;
private final String[] activeProfiles; private final String[] activeProfiles;
private final ContextLoader contextLoader; private final ContextLoader contextLoader;
private final String contextKey;
private static String[] processLocations(String[] locations) { private static String[] processLocations(String[] locations) {
return locations == null ? EMPTY_STRING_ARRAY : 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 &quot;null&quot; if the supplied loaded is <code>null</code>.
*/ */
private static String nullSafeToString(ContextLoader contextLoader) { private static String nullSafeToString(ContextLoader contextLoader) {
return contextLoader == null ? "null" : contextLoader.getClass().getName(); return contextLoader == null ? "null" : contextLoader.getClass().getName();
} }
/** /**
* Generate a context <em>key</em> from the supplied values. * Create a new {@code MergedContextConfiguration} instance for the
*/
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 <code>MergedContextConfiguration</code> instance for the
* supplied {@link Class test class}, resource locations, configuration * supplied {@link Class test class}, resource locations, configuration
* classes, active profiles, and {@link ContextLoader}. * classes, active profiles, and {@link ContextLoader}.
* <p>If a <code>null</code> value is supplied for <code>locations</code>, * <p>If a <code>null</code> value is supplied for <code>locations</code>,
@ -128,12 +117,11 @@ public class MergedContextConfiguration {
this.classes = processClasses(classes); this.classes = processClasses(classes);
this.activeProfiles = processActiveProfiles(activeProfiles); this.activeProfiles = processActiveProfiles(activeProfiles);
this.contextLoader = contextLoader; this.contextLoader = contextLoader;
this.contextKey = generateContextKey(this.locations, this.classes, this.activeProfiles, this.contextLoader);
} }
/** /**
* Get the {@link Class test class} associated with this * Get the {@link Class test class} associated with this
* <code>MergedContextConfiguration</code>. * {@code MergedContextConfiguration}.
*/ */
public Class<?> getTestClass() { public Class<?> getTestClass() {
return testClass; return testClass;
@ -172,20 +160,59 @@ public class MergedContextConfiguration {
} }
/** /**
* Get the unique context key for all properties of this * Generate a unique hash code for all properties of this
* <code>MergedContextConfiguration</code> excluding the * {@code MergedContextConfiguration} excluding the
* {@link #getTestClass() test class}. * {@link #getTestClass() test class}.
* <p>Intended to be used for caching an
* {@link org.springframework.context.ApplicationContext ApplicationContext}
* that was loaded using properties of this <code>MergedContextConfiguration</code>.
*/ */
public String getContextKey() { @Override
return contextKey; 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;
} }
/** /**
* Provide a String representation of the test class, merged context * TODO Document equals() implementation.
* configuration, and context key. *
* @see java.lang.Object#equals(java.lang.Object)
*/
@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 {@link #getTestClass() test class},
* {@link #getLocations() locations}, {@link #getClasses() configuration classes},
* {@link #getActiveProfiles() active profiles}, and the name of the
* {@link #getContextLoader() ContextLoader}.
*/ */
@Override @Override
public String toString() { public String toString() {
@ -195,7 +222,6 @@ public class MergedContextConfiguration {
.append("classes", ObjectUtils.nullSafeToString(classes))// .append("classes", ObjectUtils.nullSafeToString(classes))//
.append("activeProfiles", ObjectUtils.nullSafeToString(activeProfiles))// .append("activeProfiles", ObjectUtils.nullSafeToString(activeProfiles))//
.append("contextLoader", nullSafeToString(contextLoader))// .append("contextLoader", nullSafeToString(contextLoader))//
.append("contextKey", contextKey)//
.toString(); .toString();
} }

View File

@ -61,6 +61,7 @@ public class TestContext extends AttributeAccessorSupport {
this(testClass, contextCache, null); this(testClass, contextCache, null);
} }
// TODO Update regarding default --> DelegatingSmartContextLoader
/** /**
* Construct a new test context for the supplied {@link Class test class} * Construct a new test context for the supplied {@link Class test class}
* and {@link ContextCache context cache} and parse the corresponding * and {@link ContextCache context cache} and parse the corresponding
@ -141,18 +142,17 @@ public class TestContext extends AttributeAccessorSupport {
* application context * application context
*/ */
public ApplicationContext getApplicationContext() { public ApplicationContext getApplicationContext() {
String contextKey = mergedContextConfiguration.getContextKey();
synchronized (contextCache) { synchronized (contextCache) {
ApplicationContext context = contextCache.get(contextKey); ApplicationContext context = contextCache.get(mergedContextConfiguration);
if (context == null) { if (context == null) {
try { try {
context = loadApplicationContext(); context = loadApplicationContext();
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug(String.format( logger.debug(String.format(
"Storing ApplicationContext for test class [%s] in cache under key [%s].", testClass, "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) { catch (Exception ex) {
throw new IllegalStateException("Failed to load ApplicationContext", ex); throw new IllegalStateException("Failed to load ApplicationContext", ex);
@ -162,7 +162,7 @@ public class TestContext extends AttributeAccessorSupport {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug(String.format( logger.debug(String.format(
"Retrieved ApplicationContext for test class [%s] from cache with key [%s].", testClass, "Retrieved ApplicationContext for test class [%s] from cache with key [%s].", testClass,
contextKey)); mergedContextConfiguration));
} }
} }
return context; return context;
@ -217,7 +217,7 @@ public class TestContext extends AttributeAccessorSupport {
*/ */
public void markApplicationContextDirty() { public void markApplicationContextDirty() {
synchronized (contextCache) { synchronized (contextCache) {
contextCache.setDirty(mergedContextConfiguration.getContextKey()); contextCache.setDirty(mergedContextConfiguration);
} }
} }

View File

@ -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));
}
}