/* * Strongback * Copyright 2015, Strongback and individual contributors by the @authors tag. * See the COPYRIGHT.txt in the distribution for a full listing of individual * contributors. * * Licensed under the MIT License; you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://opensource.org/licenses/MIT * 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.strongback.mock; import static org.fest.assertions.Assertions.assertThat; import java.util.function.DoubleConsumer; import java.util.function.DoubleSupplier; import org.fest.assertions.Delta; import org.junit.Before; import org.junit.Test; import org.strongback.components.Zeroable; /** * A base class for tests of mock components that have double getters and setters. * * @author Randall Hauch */ public abstract class AbstractDoubleMockTest { protected static double[] TEST_VALUES = { 0.01, 1.0, 0.0000001, 2.000001, 5.5, 0.99999, -1.0, -0.01, -0.000001, -2.00001, -5.5 }; protected static double TEST_VALUE = TEST_VALUES[0]; protected static Delta NEAR_ZERO = Delta.delta(0.0000000000000001d); protected static Delta NOMINAL_TOLERANCE = Delta.delta(0.00001d); private DoubleConsumer setter; private DoubleSupplier getter; private Zeroable zeroable; /** * Initialize the test with the mock class's setter and getter methods. This should be called within the {@link Before} * method of the subclass. * * @param setter the method that sets the double value; may not be null * @param getter the method that gets the double value; may not be null */ protected void initialize(DoubleConsumer setter, DoubleSupplier getter) { this.setter = setter; this.getter = getter; this.zeroable = null; } /** * Initialize the test with the {@link Zeroable} mock class's setter and getter methods. This should be called within the * {@link Before} method of the subclass. * * @param setter the method that sets the double value; may not be null * @param getter the method that gets the double value; may not be null * @param zeroable the {@link Zeroable} reference; may be null if the component is not {@link Zeroable} */ protected void initialize(DoubleConsumer setter, DoubleSupplier getter, Zeroable zeroable) { this.setter = setter; this.getter = getter; this.zeroable = zeroable; } @Test public void shouldAllowSettingAndReadingValues() { for (double value : TEST_VALUES) { assertSetAndGet(value); } } @Test public void shouldGetLastSetValue() { // Call the setter multiple times ... double lastValue = Double.NaN; for (double value : TEST_VALUES) { setter.accept(value); lastValue = value; } // And calling get once should return the last value that was set ... assertThat(getter.getAsDouble()).isEqualTo(lastValue, NOMINAL_TOLERANCE); } @Test public void shouldZeroWhenValueIsZero() { if (zeroable == null) return; setter.accept(0.0); zeroable.zero(); assertThat(getter.getAsDouble()).isEqualTo(0.0,NEAR_ZERO); } @Test public void shouldZeroWhenValueIsNonZero() { if (zeroable == null) return; for (double value : TEST_VALUES) { assertSetAndZeroAndGet(value); } } protected void assertSetAndGet(double value) { assertSetAndGet(value, NOMINAL_TOLERANCE); } protected void assertSetAndGet(double value, Delta tolerance) { setter.accept(value); double actual = getter.getAsDouble(); assertThat(actual).isEqualTo(value, tolerance); } protected void assertSetAndZeroAndGet(double value) { // reset to 0 value and zero ... setter.accept(0.0); zeroable.zero(); assertThat(getter.getAsDouble()).isEqualTo(0.0, NEAR_ZERO); // Set a non-zero value ... setter.accept(value); zeroable.zero(); // Check that the value is now zero ... double actual = getter.getAsDouble(); assertThat(actual).isEqualTo(0.0, NOMINAL_TOLERANCE); // Set the value to multiples of the original ... for (int i = 2; i != 6; ++i) { double nonZeroed = value * i; setter.accept(nonZeroed); // Check that the difference is properly adjusted (even for negative values) ... actual = getter.getAsDouble(); assertThat(actual).isEqualTo(nonZeroed - value, NOMINAL_TOLERANCE); } // Set the value to negative multiples of the original ... for (int i = 2; i != 6; ++i) { double nonZeroed = -value * i; setter.accept(nonZeroed); // Check that the difference is properly adjusted (even for negative values) ... actual = getter.getAsDouble(); assertThat(actual).isEqualTo(nonZeroed - value, NOMINAL_TOLERANCE); } } }