com.qcadoo.model.internal.classconverter.ModelXmlToClassConverterTest.java Source code

Java tutorial

Introduction

Here is the source code for com.qcadoo.model.internal.classconverter.ModelXmlToClassConverterTest.java

Source

/**
 * ***************************************************************************
 * Copyright (c) 2010 Qcadoo Limited
 * Project: Qcadoo Framework
 * Version: 1.2.0
 *
 * This file is part of Qcadoo.
 *
 * Qcadoo is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation; either version 3 of the License,
 * or (at your option) any later version.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 * ***************************************************************************
 */
package com.qcadoo.model.internal.classconverter;

import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import java.beans.PropertyDescriptor;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import junit.framework.Assert;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.junit.BeforeClass;
import org.junit.Test;

import com.google.common.collect.Sets;
import com.qcadoo.model.Utils;
import com.qcadoo.model.internal.utils.ClassNameUtils;

public class ModelXmlToClassConverterTest {

    private static final ModelXmlToClassConverterImpl MODEL_XML_TO_CLASSCONVERTER = new ModelXmlToClassConverterImpl();

    private static Map<String, Class<?>> classes = new HashMap<String, Class<?>>();

    private static Map<String, PropertyDescriptor> propertyDescriptors = new HashMap<String, PropertyDescriptor>();

    @BeforeClass
    public static void init() throws Exception {
        MODEL_XML_TO_CLASSCONVERTER.setBeanClassLoader(ClassLoader.getSystemClassLoader());

        for (Class<?> clazz : MODEL_XML_TO_CLASSCONVERTER.convert(Utils.FULL_FIRST_ENTITY_XML_RESOURCE,
                Utils.FULL_SECOND_ENTITY_XML_RESOURCE, Utils.FULL_THIRD_ENTITY_XML_RESOURCE,
                Utils.OTHER_FIRST_ENTITY_XML_RESOURCE, Utils.OTHER_SECOND_ENTITY_XML_RESOURCE)) {
            classes.put(clazz.getCanonicalName(), clazz);
        }

        for (PropertyDescriptor propertyDescriptor : PropertyUtils.getPropertyDescriptors(
                classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "firstEntity")))) {
            propertyDescriptors.put(propertyDescriptor.getName(), propertyDescriptor);
        }
    }

    @Test
    public void shouldDefineClasses() throws Exception {
        assertEquals(5, classes.size());
    }

    @Test
    public void shouldHaveProperName() throws Exception {
        assertNotNull(classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "firstEntity")));
        assertNotNull(classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "secondEntity")));
        assertNotNull(classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "thirdEntity")));
        assertNotNull(classes.get(ClassNameUtils.getFullyQualifiedClassName("other", "firstEntity")));
        assertNotNull(classes.get(ClassNameUtils.getFullyQualifiedClassName("other", "secondEntity")));
    }

    @Test
    public void shouldDefineIdentifier() {
        verifyField(propertyDescriptors.get("id"), Long.class);
    }

    @Test
    public void shouldDefineSimpleFields() throws Exception {
        verifyField(propertyDescriptors.get("fieldInteger"), Integer.class);
        verifyField(propertyDescriptors.get("fieldString"), String.class);
        verifyField(propertyDescriptors.get("fieldText"), String.class);
        verifyField(propertyDescriptors.get("fieldDecimal"), BigDecimal.class);
        verifyField(propertyDescriptors.get("fieldDecimalOnlyWithScale"), BigDecimal.class);
        verifyField(propertyDescriptors.get("fieldDecimalWithoutValidators"), BigDecimal.class);
        verifyField(propertyDescriptors.get("fieldDatetime"), Date.class);
        verifyField(propertyDescriptors.get("fieldDate"), Date.class);
        verifyField(propertyDescriptors.get("fieldBoolean"), Boolean.class);
        verifyField(propertyDescriptors.get("fieldDictionary"), String.class);
        verifyField(propertyDescriptors.get("fieldOtherDictionary"), String.class);
        verifyField(propertyDescriptors.get("fieldEnum"), String.class);
        verifyField(propertyDescriptors.get("fieldPassword"), String.class);
        verifyField(propertyDescriptors.get("fieldPriority"), Integer.class);
    }

    @Test
    public void shouldDefineActivableField() throws Exception {
        verifyField(propertyDescriptors.get("active"), Boolean.class);
    }

    @Test
    public void shouldDefineBelongsToFields() throws Exception {
        verifyField(propertyDescriptors.get("fieldSecondEntity"),
                classes.get(ClassNameUtils.getFullyQualifiedClassName("other", "secondEntity")));
        verifyField(propertyDescriptors.get("fieldSecondEntity2"),
                classes.get(ClassNameUtils.getFullyQualifiedClassName("other", "secondEntity")));
    }

    @Test
    public void shouldDefineManyToManyFields() throws Exception {
        verifyField(propertyDescriptors.get("fieldManyToMany"), Set.class);
    }

    @Test
    public void shouldDefineHasManyFields() throws Exception {
        verifyField(propertyDescriptors.get("fieldTree"), Set.class);
        verifyField(propertyDescriptors.get("fieldHasMany"), Set.class);
    }

    @Test
    public void shouldHaveAuditableFields() throws Exception {
        verifyField(propertyDescriptors.get("createDate"), Date.class);
        verifyField(propertyDescriptors.get("updateDate"), Date.class);
        verifyField(propertyDescriptors.get("createUser"), String.class);
        verifyField(propertyDescriptors.get("updateUser"), String.class);
    }

    @Test
    public void shouldHaveToStringMethod() throws Exception {
        // given
        Object entity = classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "firstEntity")).newInstance();

        BeanUtils.setProperty(entity, "fieldInteger", 13);
        BeanUtils.setProperty(entity, "fieldString", "Xxx");

        // when
        String string = entity.toString();

        // then
        assertTrue(string.contains("fieldInteger=13"));
        assertTrue(string.contains("fieldString=Xxx"));
        assertTrue(string.contains(ClassNameUtils.getFullyQualifiedClassName("full", "firstEntity")));
    }

    @Test
    public void shouldHaveHashCodeMethod() throws Exception {
        Object entity1 = classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "firstEntity"))
                .newInstance();
        Object entity2 = classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "firstEntity"))
                .newInstance();

        BeanUtils.setProperty(entity1, "fieldInteger", 13);
        BeanUtils.setProperty(entity2, "fieldInteger", 13);
        BeanUtils.setProperty(entity1, "fieldString", "Xxx");
        BeanUtils.setProperty(entity2, "fieldString", "Xxx");

        assertTrue(entity1.hashCode() == entity1.hashCode());
        assertTrue(entity1.hashCode() == entity2.hashCode());

        BeanUtils.setProperty(entity2, "fieldString", "Xxz");

        assertFalse(entity1.hashCode() == entity2.hashCode());
    }

    @Test
    public void shouldHaveEqualsMethod() throws Exception {
        Object entity1 = classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "firstEntity"))
                .newInstance();
        Object entity2 = classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "firstEntity"))
                .newInstance();
        Object entity3 = classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "secondEntity"))
                .newInstance();

        BeanUtils.setProperty(entity1, "fieldInteger", 13);
        BeanUtils.setProperty(entity2, "fieldInteger", 13);
        BeanUtils.setProperty(entity1, "fieldString", "Xxx");
        BeanUtils.setProperty(entity2, "fieldString", "Xxx");

        assertTrue(entity1.equals(entity1));
        assertTrue(entity1.equals(entity2));
        assertTrue(entity2.equals(entity1));

        BeanUtils.setProperty(entity2, "fieldString", "Xxz");

        assertFalse(entity1.equals(entity2));
        assertFalse(entity2.equals(entity1));
        assertFalse(entity1.equals(null));
        assertFalse(entity1.equals(entity3));
    }

    @Test
    public void shouldHashCodeDoNotHaveCycleWithBelongsToFields() throws Exception {
        // given
        Object firstEntity = classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "firstEntity"))
                .newInstance();
        Object thirdEntity = classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "thirdEntity"))
                .newInstance();

        BeanUtils.setProperty(firstEntity, "fieldThirdEntity", thirdEntity);
        BeanUtils.setProperty(thirdEntity, "fieldFirstEntity", firstEntity);

        // when & then
        try {
            firstEntity.hashCode();
            thirdEntity.hashCode();
        } catch (StackOverflowError t) {
            Assert.fail();
        }
    }

    @Test
    public void shouldHashCodeDoNotHaveCycleWithHasManyFields() throws Exception {
        // given
        Object firstEntity = classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "firstEntity"))
                .newInstance();
        Object thirdEntity = classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "thirdEntity"))
                .newInstance();

        BeanUtils.setProperty(firstEntity, "fieldHasMany", Sets.newHashSet(thirdEntity));
        BeanUtils.setProperty(thirdEntity, "fieldFirstEntity", firstEntity);

        // when & then
        try {
            firstEntity.hashCode();
            thirdEntity.hashCode();
        } catch (StackOverflowError t) {
            Assert.fail();
        }
    }

    @Test
    public void shouldHashCodeDoNotHaveCycleWithManyToManyFields() throws Exception {
        // given
        Object firstEntity = classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "firstEntity"))
                .newInstance();
        Object thirdEntity = classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "thirdEntity"))
                .newInstance();

        BeanUtils.setProperty(firstEntity, "fieldManyToMany", Sets.newHashSet(thirdEntity));
        BeanUtils.setProperty(thirdEntity, "fieldManyToMany", Sets.newHashSet(firstEntity));

        // when & then
        try {
            firstEntity.hashCode();
            thirdEntity.hashCode();
        } catch (StackOverflowError t) {
            Assert.fail();
        }
    }

    @Test
    public void shouldHashCodeDoNotHaveCycleWithBelongsToAndManyToManyFields() throws Exception {
        // given
        Object firstEntity = classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "firstEntity"))
                .newInstance();
        Object thirdEntity = classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "thirdEntity"))
                .newInstance();

        BeanUtils.setProperty(firstEntity, "fieldThirdEntity", thirdEntity);
        BeanUtils.setProperty(thirdEntity, "fieldManyToMany", Sets.newHashSet(firstEntity));

        // when & then
        try {
            firstEntity.hashCode();
            thirdEntity.hashCode();
        } catch (StackOverflowError t) {
            Assert.fail();
        }
    }

    @Test
    public final void shouldReturnDifferentHashCodesIfRelatedEntitiesAreDifferent() throws Exception {
        // given
        Object firstEntityA = classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "firstEntity"))
                .newInstance();
        Object firstEntityB = classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "firstEntity"))
                .newInstance();

        Object thirdEntityA = classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "thirdEntity"))
                .newInstance();
        Object thirdEntityB = classes.get(ClassNameUtils.getFullyQualifiedClassName("full", "thirdEntity"))
                .newInstance();

        BeanUtils.setProperty(firstEntityA, "fieldInteger", 13);
        BeanUtils.setProperty(firstEntityA, "fieldString", "Xxx");
        BeanUtils.setProperty(firstEntityA, "fieldManyToMany", Sets.newHashSet(thirdEntityA));
        BeanUtils.setProperty(thirdEntityA, "fieldString", "Aaa");
        BeanUtils.setProperty(thirdEntityA, "fieldManyToMany", Sets.newHashSet(firstEntityA));

        BeanUtils.setProperty(firstEntityB, "fieldInteger", 13);
        BeanUtils.setProperty(firstEntityB, "fieldString", "Xxx");
        BeanUtils.setProperty(firstEntityB, "fieldManyToMany", Sets.newHashSet(thirdEntityB));
        BeanUtils.setProperty(thirdEntityB, "fieldString", "Bbb");
        BeanUtils.setProperty(thirdEntityB, "fieldManyToMany", Sets.newHashSet(firstEntityB));

        // when
        int hashCodeFirstB = firstEntityB.hashCode();
        assertFalse(firstEntityA.hashCode() == firstEntityB.hashCode());
        BeanUtils.setProperty(thirdEntityB, "fieldString", "Aaa");
        assertFalse(hashCodeFirstB == firstEntityB.hashCode());
        BeanUtils.setProperty(firstEntityB, "fieldManyToMany", Sets.newHashSet(thirdEntityA));
        assertTrue(firstEntityA.hashCode() == firstEntityB.hashCode());
    }

    private void verifyField(final PropertyDescriptor propertyDescriptor, final Class<?> type) {
        verifyField(propertyDescriptor, type, true, true);
    }

    private void verifyField(final PropertyDescriptor propertyDescriptor, final Class<?> type,
            final boolean readable, final boolean writable) {
        assertEquals(type, propertyDescriptor.getPropertyType());
        if (writable) {
            assertNotNull(propertyDescriptor.getWriteMethod());
        } else {
            assertNull(propertyDescriptor.getWriteMethod());
        }
        if (readable) {
            assertNotNull(propertyDescriptor.getReadMethod());
        } else {
            assertNull(propertyDescriptor.getReadMethod());
        }
    }
}