All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mutabilitydetector.unittesting.AllowedReason Maven / Gradle / Ivy

There is a newer version: 0.10.6
Show newest version
package org.mutabilitydetector.unittesting;

/*
 * #%L
 * MutabilityDetector
 * %%
 * Copyright (C) 2008 - 2014 Graham Allan
 * %%
 * 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.
 * #L%
 */



import static com.google.common.collect.ImmutableSet.copyOf;
import static com.google.common.collect.Iterables.transform;
import static java.util.Arrays.asList;
import static org.mutabilitydetector.locations.Dotted.CLASS_TO_DOTTED;
import static org.mutabilitydetector.locations.Dotted.dotted;
import static org.mutabilitydetector.locations.Dotted.fromClass;

import org.hamcrest.Matcher;
import org.mutabilitydetector.MutableReasonDetail;
import org.mutabilitydetector.unittesting.matchers.reasons.AllowingForSubclassing;
import org.mutabilitydetector.unittesting.matchers.reasons.AllowingNonFinalFields;
import org.mutabilitydetector.unittesting.matchers.reasons.FieldAssumptions;
import org.mutabilitydetector.unittesting.matchers.reasons.NoReasonsAllowed;
import org.mutabilitydetector.unittesting.matchers.reasons.ProvidedOtherClass;

import com.google.common.collect.ImmutableSet;

/**
 * Provides ways to suppress false positives generated by Mutability Detector.
 * 

* Regretfully, Mutability Detector may produce false positives, which cause * your unit tests to fail, even though your class is immutable. In order to get * around this fault in Mutability Detector, you can provide an "allowed reason" * for mutability. This is preferable to deleting the test, or marking it as * ignored, as it allows checking for all other violations except those you have * explicitly sanctioned. *

* All types returned from the static methods on AllowedReason are * implementations of Hamcrest {@link Matcher}, generic on the type * {@link MutableReasonDetail}. *

* For more information on configuring a mutability assertion, see * {@link MutabilityAssert}. * * @see MutabilityAssert * @see MutableReasonDetail * * @see ProvidedOtherClass * @see AllowingForSubclassing * @see AllowingNonFinalFields * @see FieldAssumptions * @see NoReasonsAllowed * */ public final class AllowedReason { private AllowedReason() { } /** * Please see the JavaDoc listed with {@link MutabilityAssert} for an * introduction on using this method. * * @see MutabilityAssert */ public static ProvidedOtherClass provided(String dottedClassName) { return ProvidedOtherClass.provided(dotted(dottedClassName)); } /** * Please see the JavaDoc listed with {@link MutabilityAssert} for an * introduction on using this method. * * @see MutabilityAssert */ public static ProvidedOtherClass provided(Class clazz) { return ProvidedOtherClass.provided(fromClass(clazz)); } /** * Please see the JavaDoc listed with {@link MutabilityAssert} for an * introduction on using this method. * * @see MutabilityAssert */ public static ProvidedOtherClass provided(Class... classes) { return ProvidedOtherClass.provided(transform(asList(classes), CLASS_TO_DOTTED)); } /** * Please see the JavaDoc listed with {@link MutabilityAssert} for an * introduction on using this method. * * @see MutabilityAssert */ public static AllowingForSubclassing allowingForSubclassing() { return new AllowingForSubclassing(); } /** * Insists that non-final fields are acceptable. *

* Please see the JavaDoc listed with {@link MutabilityAssert} for an * introduction on using this method. *

* Example usage: *


     * @Immutable
     * public final class HasNonFinalField {
     *   private int someValue;
     *
     *   public HasNonFinalField(int value) {
     *     this.someValue = value;
     *   }
     *
     *   // may have getter methods, but definitely no setter methods or reassignments.
     * }
     *
     *  // a warning will be raised because field 'someValue' is not declared final
     *  assertInstancesOf(HasNonFinalField.class, areImmutable());
     *
     *  // use AllowingNonFinalFields to permit this
     *  // must be used if matching result with areEffectivelyImmutable()
     *  assertInstancesOf(UsesInternalMapForCaching.class,
     *                    areImmutable(),
     *                    allowingNonFinalFields());
     * 
*

* Must be used if matching with {@link MutabilityMatchers#areEffectivelyImmutable()}. *

* @see MutabilityAssert */ public static AllowingNonFinalFields allowingNonFinalFields() { return new AllowingNonFinalFields(); } /** * Allowed reasons for mutability warnings related to fields. *

* Please see the JavaDoc listed with {@link MutabilityAssert} for an * introduction on using this method. *

* Several warnings raised by Mutability Detector relate to the definition, or * the use, of a field in a class. For example: the definition of a field may * include declaring that the type of the field is mutable; or the use of a * field may include reassigning it outwith the constructor. * {@link FieldAssumptions} provides several methods which allow this category * of reasons. *

* Reasons are allowed by matching the field by it's name and then * matching the reasons that particular field causes mutability. *

* Example usage: * *


     * @Immutable
     * public final class UsesInternalMapForCaching {
     *   private final Map internalCache = new HashMap();
     *   // ... constructor, and methods which mutate the map for caching
     * }
     *
     *  // a warning will be raised because field 'internalCache' is a mutable type.
     *  assertInstancesOf(UsesInternalMapForCaching.class, areImmutable());
     *
     *  // use FieldAssumptions to insist the usage is safe
     *  assertInstancesOf(UsesInternalMapForCaching.class,
     *                    areImmutable(),
     *                    assumingFields("internalCache").areModifiedAsPartOfAnUnobservableCachingStrategy());
     * 
*

* This method is also available in Iterable$lt;String> form {@link #assumingFields(Iterable))}. * * * @see MutabilityAssert */ public static FieldAssumptions assumingFields(String firstFieldName, String... otherFieldNames) { return FieldAssumptions.named(ImmutableSet.builder().add(firstFieldName).add(otherFieldNames).build()); } /** * Allowed reasons for mutability warnings related to fields. *

* Please see the JavaDoc listed with {@link MutabilityAssert} for an * introduction on using this method. *

* Several warnings raised by Mutability Detector relate to the definition, or * the use, of a field in a class. For example: the definition of a field may * include declaring that the type of the field is mutable; or the use of a * field may include reassigning it outwith the constructor. * {@link FieldAssumptions} provides several methods which allow this category * of reasons. *

* Reasons are allowed by matching the field by it's name and then * matching the reasons that particular field causes mutability. *

* Example usage: * *


     * @Immutable
     * public final class UsesInternalMapForCaching {
     *   private final Map internalCache = new HashMap();
     *   // ... constructor, and methods which mutate the map for caching
     * }
     *
     *  // a warning will be raised because field 'internalCache' is a mutable type.
     *  assertImmutable(UsesInternalMapForCaching.class, areImmutable());
     *
     *  // use FieldAssumptions to insist the usage is safe
     *  assertImmutable(UsesInternalMapForCaching.class,
     *                  areImmutable(),
     *                  assumingFields(Arrays.asList("internalCache")).areModifiedAsPartOfAnUnobservableCachingStrategy());
     * 
*

* This method is also available in varargs form {@link #assumingFields(String, String...)}. * * * @see MutabilityAssert */ public static FieldAssumptions assumingFields(Iterable named) { return FieldAssumptions.named(copyOf(named)); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy