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

com.google.common.truth.FloatSubject Maven / Gradle / Ivy

There is a newer version: 1.4.4
Show newest version
/*
 * Copyright (c) 2014 Google, Inc.
 *
 * 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 com.google.common.truth;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.Float.floatToIntBits;

import javax.annotation.CheckReturnValue;
import javax.annotation.Nullable;

/**
 * Propositions for {@link Float} subjects.
 *
 * @author Kurt Alfred Kluever
 */
@CheckReturnValue
public final class FloatSubject extends ComparableSubject {
  private static final int NEG_ZERO_BITS = floatToIntBits(-0.0f);

  FloatSubject(FailureStrategy failureStrategy, @Nullable Float subject) {
    super(failureStrategy, subject);
  }

  /**
   * A partially specified proposition about an approximate relationship to a {@code float}
   * subject using a tolerance.
   */
  public abstract class TolerantFloatComparison {

    // Prevent subclassing outside of this class
    private TolerantFloatComparison() {}

    /**
     * Fails if the subject was expected to be within the tolerance of the given value but was not
     * or if it was expected not to be within the tolerance but was. The expectation,
     * subject, and tolerance are all specified earlier in the fluent call chain.
     */
    public abstract void of(float expectedFloat);

    /**
     * @throws UnsupportedOperationException always
     * @deprecated {@link Object#equals(Object)} is not supported on TolerantFloatComparison
     *     If you meant to compare floats, use {@link #of(float)} instead.
     */
    @Deprecated
    @Override
    public boolean equals(@Nullable Object o) {
      throw new UnsupportedOperationException(
          "If you meant to compare floats, use .of(float) instead.");
    }

    /**
     * @throws UnsupportedOperationException always
     * @deprecated {@link Object#hashCode()} is not supported on TolerantFloatComparison
     */
    @Deprecated
    @Override
    public int hashCode() {
      throw new UnsupportedOperationException("Subject.hashCode() is not supported.");
    }
  }

  /**
   * Prepares for a check that the subject is a finite number within the given tolerance of an
   * expected value that will be provided in the next call in the fluent chain.
   *
   * 

You can use a tolerance of {@code 0.0f} to assert the exact equality of finite floats. This * is appropriate when the contract of the code under test guarantees this, e.g. by specifying * that a return value is copied unchanged from the input, by specifying an exact constant value * to be returned, or by specifying an exact sequence of arithmetic operations to be followed. * *

The check will fail if either the subject or the object is * {@link Float#POSITIVE_INFINITY}, {@link Float#NEGATIVE_INFINITY}, or {@link Float#NaN}. To * check for those values, use {@link #isPositiveInfinity}, {@link isNegativeInfinity}, or * {@link isNaN}. * * @param tolerance an inclusive upper bound on the difference between the subject and object * allowed by the check, which must be a non-negative finite value, i.e. not * {@link Float#NaN}, {@link Float#POSITIVE_INFINITY}, or negative, including {@code -0.0f} */ public TolerantFloatComparison isWithin(final float tolerance) { return new TolerantFloatComparison() { @Override public void of(float expected) { Float actual = getSubject(); checkNotNull( actual, "actual value cannot be null. tolerance=%s expected=%s", tolerance, expected); checkTolerance(tolerance); if (!MathUtil.equals(actual, expected, tolerance)) { failWithRawMessage( "%s and <%s> should have been finite values within <%s> of each other", getDisplaySubject(), expected, tolerance); } } }; } /** * Prepares for a check that the subject is a finite number not within the given tolerance of an * expected value that will be provided in the next call in the fluent chain. * *

You can use a tolerance of {@code 0.0f} to assert the exact inequality of finite floats. * *

The check will fail if either the subject or the object is * {@link Float#POSITIVE_INFINITY}, {@link Float#NEGATIVE_INFINITY}, or {@link Float#NaN}. * See {@link #isFinite} and {@link #isNotNaN}, or use {@link #isIn} with a suitable * {@link com.google.common.collect.Range Range}. * * @param tolerance an exclusive lower bound on the difference between the subject and object * allowed by the check, which must be a non-negative finite value, i.e. not * {@code Float.NaN}, {@code Float.POSITIVE_INFINITY}, or negative, including {@code -0.0f} */ public TolerantFloatComparison isNotWithin(final float tolerance) { return new TolerantFloatComparison() { @Override public void of(float expected) { Float actual = getSubject(); checkNotNull( actual, "actual value cannot be null. tolerance=%s expected=%s", tolerance, expected); checkTolerance(tolerance); if (!MathUtil.notEquals(actual, expected, tolerance)) { failWithRawMessage( "%s and <%s> should have been finite values not within <%s> of each other", getDisplaySubject(), expected, tolerance); } } }; } /** * @deprecated Use {@link #isWithin} instead. Float comparison should always have a tolerance. */ @Deprecated public final void isEqualTo(@Nullable Float other) { super.isEqualTo(other); } /** * @deprecated Use {@link #isNotWithin} instead. Float comparison should always have a tolerance. */ @Deprecated public final void isNotEqualTo(@Nullable Float other) { super.isNotEqualTo(other); } /** * @deprecated Use {@link #isWithin} instead. Float comparison should always have a tolerance. */ @Deprecated public final void isEquivalentAccordingToCompareTo(Float other) { super.isEquivalentAccordingToCompareTo(other); } /** * Ensures that the given tolerance is a non-negative finite value, i.e. not {@code Float.NaN}, * {@code Float.POSITIVE_INFINITY}, or negative, including {@code -0.0f}. */ static void checkTolerance(float tolerance) { checkArgument(!Float.isNaN(tolerance), "tolerance cannot be NaN"); checkArgument(tolerance >= 0.0f, "tolerance (%s) cannot be negative", tolerance); checkArgument( floatToIntBits(tolerance) != NEG_ZERO_BITS, "tolerance (%s) cannot be negative", tolerance); checkArgument(tolerance != Float.POSITIVE_INFINITY, "tolerance cannot be POSITIVE_INFINITY"); } /** * Asserts that the subject is {@link Float#POSITIVE_INFINITY}. */ public final void isPositiveInfinity() { super.isEqualTo(Float.POSITIVE_INFINITY); } /** * Asserts that the subject is {@link Float#NEGATIVE_INFINITY}. */ public final void isNegativeInfinity() { super.isEqualTo(Float.NEGATIVE_INFINITY); } /** * Asserts that the subject is {@link Float#NaN}. */ public final void isNaN() { super.isEqualTo(Float.NaN); } /** * Asserts that the subject is finite, i.e. not {@link Float#POSITIVE_INFINITY}, * {@link Float#NEGATIVE_INFINITY}, or {@link Float#NaN}. */ public final void isFinite() { if (getSubject() == null || getSubject().isNaN() || getSubject().isInfinite()) { failWithRawMessage("%s should have been finite", getDisplaySubject()); } } /** * Asserts that the subject is not {@link Float#NaN} (but it may be * {@link Float#POSITIVE_INFINITY} or {@link Float#NEGATIVE_INFINITY}). */ public final void isNotNaN() { if (getSubject() == null || getSubject().isNaN()) { failWithRawMessage("%s should not have been NaN", getDisplaySubject()); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy