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

jasima.core.util.ExperimentTest Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2010-2015 Torsten Hildebrandt and jasima contributors
 *
 * This file is part of jasima, v1.2.
 *
 * jasima is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * jasima is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with jasima.  If not, see .
 *******************************************************************************/
package jasima.core.util;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.number.IsCloseTo.closeTo;
import static org.junit.matchers.JUnitMatchers.hasItem;
import jasima.core.experiment.Experiment;
import jasima.core.statistics.SummaryStat;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.junit.Rule;
import org.junit.rules.ErrorCollector;

/**
 * Utility class that can be used as a base class for JUnit tests which check
 * for many results of an {@link Experiment} at once. Deriving a new test class
 * from {@code ExperimentTest} and calling {@link #checkResults(Map, Map)} many
 * results of an experiment can be validated with a single method call.
 * 
 * @author Torsten Hildebrandt , 2012-08-08
 * @version 
 *          "$Id: ExperimentTest.java 550 2015-01-23 15:07:23Z [email protected] $"
 */
public class ExperimentTest {

	@Rule
	public ErrorCollector errorCollector = new ErrorCollector();

	public static final double EPS = 1e-6d;

	/**
	 * Checks whether key sets of actual and expected results are the same.
	 * 
	 * @param resActual
	 * @param resExpected
	 */
	public void checkKeySets(Map resActual,
			Map resExpected) {
		Set keysAct = new HashSet(resActual.keySet());
		Set keysExp = new HashSet(resExpected.keySet());

		HashSet all = new HashSet();
		all.addAll(keysAct);
		all.addAll(keysExp);

		HashSet onlyExp = new HashSet(all);
		onlyExp.removeAll(keysAct);

		HashSet onlyAct = new HashSet(all);
		onlyAct.removeAll(keysExp);
		errorCollector.checkThat("key sets should be equal.\n"
				+ "keys missing in actual result map: " + onlyExp + ";\n"
				+ "keys only in actual result map: " + onlyAct, keysAct,
				is(keysExp));
	}

	/**
	 * Checks if all keys in resExpected are also present in
	 * resActual and have the same values. Additional keys in
	 * resActual as well as the key "runTime" are
	 * ignored.
	 * 
	 * @param resActual
	 * @param resExpected
	 */
	public void checkResults(Map resActual,
			Map resExpected) {
		for (String name : resExpected.keySet()) {
			if (Experiment.RUNTIME.equals(name)
					|| name.endsWith("." + Experiment.RUNTIME))
				continue;
			errorCollector.checkThat(name, resActual.keySet(), hasItem(name));

			Object expected = resExpected.get(name);
			Object actual = resActual.get(name);
			if (actual == null)
				continue;

			name = "result entry '" + name + "'";

			if (expected instanceof SummaryStat) {
				checkValueStat(name, (SummaryStat) expected,
						(SummaryStat) actual);
			} else if (expected instanceof Double) {
				Double exp = (Double) expected;
				Double act = (Double) actual;
				checkDouble(name, act, exp);
			} else if (expected instanceof Float) {
				Float exp = (Float) expected;
				Float act = (Float) actual;
				Double e = exp == null ? null : exp.doubleValue();
				Double a = act == null ? null : act.doubleValue();
				errorCollector.checkThat(name, a, closeTo(e, EPS));
			} else
				errorCollector.checkThat(name, actual, is(expected));
		}
	}

	private void checkDouble(String name, double act, double exp) {
		if (Double.compare(exp, act) != 0) {
			errorCollector.checkThat(name, act, closeTo(exp, EPS));
		}
	}

	public void checkValueStat(String name, SummaryStat exp, SummaryStat act) {
		errorCollector.checkThat(name + " (numObs)", act.numObs(),
				is(exp.numObs()));
		checkDouble(name + " (weightSum)", act.weightSum(), exp.weightSum());
		checkDouble(name + " (mean)", act.mean(), exp.mean());
		checkDouble(name + " (min)", act.min(), exp.min());
		checkDouble(name + " (max)", act.max(), exp.max());
		checkDouble(name + " (stdDev)", act.stdDev(), exp.stdDev());
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy