/* * * * Copyright 2010, Unitils.org * * * * 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.unitils.reflectionassert.comparator.impl; import org.unitils.reflectionassert.ReflectionComparator; import org.unitils.reflectionassert.comparator.Comparator; import org.unitils.reflectionassert.difference.Difference; /** * A comparator that compares primitive types by value and not by type. * You can for example compare a double with an integer value. * * @author Tim Ducheyne * @author Filip Neven */ public class LenientNumberComparator implements Comparator { /** * Returns true if both objects are not null and instances of Number or Character. * * @param left The left object * @param right The right object * @return True for Numbers and Charaters */ public boolean canCompare(Object left, Object right) { if (left == null || right == null) { return false; } if ((left instanceof Character || left instanceof Number) && (right instanceof Character || right instanceof Number)) { return true; } return false; } /** * Compares the two values by converting them to a double and comparing these double values. * * @param left The left Number or Character, not null * @param right The right Number or Character, not null * @param onlyFirstDifference True if only the first difference should be returned * @param reflectionComparator The root comparator for inner comparisons, not null * @return A difference if the values are different, null otherwise */ public Difference compare(Object left, Object right, boolean onlyFirstDifference, ReflectionComparator reflectionComparator) { // check if right and left have same number value (including NaN and Infinity) final String differenceMessage = "Different primitive values"; if (left instanceof Long && right instanceof Long) { if (!((Long) left).equals(((Long) right))) { return new Difference(differenceMessage, left, right); } } Double leftDouble = getDoubleValue(left); Double rightDouble = getDoubleValue(right); if (!leftDouble.equals(rightDouble)) { return new Difference(differenceMessage, left, right); } return null; } /** * Gets the double value for the given left Character or Number instance. * * @param object the Character or Number, not null * @return the value as a Double (this way NaN and infinity can be compared) */ private Double getDoubleValue(Object object) { if (object instanceof Number) { return ((Number) object).doubleValue(); } return (double) ((Character) object).charValue(); } }