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

org.ligoj.bootstrap.model.AbstractBusinessEntityTest Maven / Gradle / Ivy

There is a newer version: 3.1.22
Show newest version
/*
 * Licensed under MIT (https://github.com/ligoj/ligoj/blob/master/LICENSE)
 */
package org.ligoj.bootstrap.model;

import java.lang.reflect.Modifier;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.junit.jupiter.api.Assertions;
import org.mockito.Mockito;

import jodd.bean.BeanUtil;

/**
 * Test business keyed entities basic ORM operations : hash code and equals.
 */
public abstract class AbstractBusinessEntityTest {

	/**
	 * Bean utility.
	 */
	private static final BeanUtil BEAN_UTIL = BeanUtil.declaredSilent;

	/**
	 * Test equals and hash code operation with all possible combinations
	 *
	 * @param modelClass the entity to test.
	 * @param  The type of the entity to test.
	 * @throws ReflectiveOperationException Due to reflection.
	 */
	protected  void testEqualsAndHash(final Class modelClass) throws ReflectiveOperationException {
		testEqualsAndHash(modelClass, "id");
	}

	/**
	 * Test equals and hash code operation with all possible combinations
	 *
	 * @param modelClass   the entity to test.
	 * @param idProperties the list of business key parts.
	 * @param           The type of the entity to test.
	 * @throws ReflectiveOperationException due to reflection.
	 */
	protected  void testEqualsAndHash(final Class modelClass, final String... idProperties)
			throws ReflectiveOperationException {
		final var systemUser = modelClass.getDeclaredConstructor().newInstance();
		final var systemUser2 = modelClass.getDeclaredConstructor().newInstance();
		Assertions.assertFalse(systemUser.equals(null)); // NOPMD NOSONAR -- for coverage
		Assertions.assertEquals(systemUser, systemUser);
		Assertions.assertEquals(systemUser, systemUser2);
		Assertions.assertFalse(systemUser.equals(1));
		Assertions.assertNotSame(0, systemUser.hashCode());

		// Get all identifier combinations
		final var combinations = combinations(idProperties);

		// For each, compute equality and hash code
		testCombinations(modelClass, combinations);

		// Test inheritance "canEqual" if available (as Scala)
		final var mockCanEqual = Mockito.mock(modelClass);
		systemUser.equals(mockCanEqual);
	}

	private  void setValues(final T beanValued, final List combination) {
		for (final var propertyString : combination) {
			BEAN_UTIL.setProperty(beanValued, propertyString, 1);
		}
	}

	private  void testCombinations(final Class modelClass, final List> combinations)
			throws ReflectiveOperationException {
		for (final var combination : combinations) {
			final var beanValued = modelClass.getDeclaredConstructor().newInstance();
			setValues(beanValued, combination);
			testCombinations(modelClass, combinations, combination, beanValued);
			Assertions.assertNotSame(0, beanValued.hashCode());
		}
	}

	/**
	 * Test the given combinations.
	 */
	private  void testCombinations(final Class modelClass, final List> combinations,
			final List combination, final T beanValued) throws ReflectiveOperationException {
		for (final var properties : combinations) {
			testCombination(modelClass, combination, beanValued, properties);
		}
	}

	/**
	 * Test the given combination.
	 */
	private  void testCombination(final Class modelClass, final List combination, final T beanValued,
			final List properties) throws ReflectiveOperationException {
		final var beanValued2 = modelClass.getDeclaredConstructor().newInstance();
		setValues(beanValued2, properties);
		Assertions.assertEquals(properties.equals(combination), beanValued.equals(beanValued2));
	}

	/**
	 * Generates all combinations and returns them in a list of lists.
	 */
	private List> combinations(final String... array) {
		final long count = 2L << array.length - 1;
		final List> totalCombinations = new LinkedList<>();

		for (var i = 0; i < count; i++) {
			final List combinations = new LinkedList<>();
			addPropertyCombinations(i, combinations, array);
			totalCombinations.add(combinations);
		}

		return totalCombinations;
	}

	private void addPropertyCombinations(final int i, final List combinations, final String... array) {
		for (var j = 0; j < array.length; j++) {
			if ((i & (1 << j)) != 0) {
				combinations.add(array[j]);
			}
		}
	}

	/**
	 * Simple POJO utility getter/setter for POJO compliance.
	 * 
	 * @param pojo The POJO class.
	 * @return The POJO instance with all setters called.
	 * @param  POJO type.
	 * @throws ReflectiveOperationException When reflects fails.
	 */
	protected  T testPojo(Class pojo) throws ReflectiveOperationException {
		var bean = pojo.getConstructor().newInstance();
		for (final var field : FieldUtils.getAllFields(pojo)) {
			if (field.getName().contains("$") || Modifier.isStatic(field.getModifiers())) {
				continue;
			}
			final var setter = "set" + StringUtils.capitalize(field.getName());
			var getter = "get" + StringUtils.capitalize(field.getName());
			Object param = null;
			var type = field.getType();
			if (type.equals(double.class)) {
				param = 0D;
			} else if (type.equals(boolean.class)) {
				getter = "is" + StringUtils.capitalize(field.getName());
				param = false;
			}

			pojo.getMethod(setter, type).invoke(bean, param);
			pojo.getMethod(getter).invoke(bean);
		}
		return bean;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy