Package info.archinnov.achilles.internal.metadata.parsing

Source Code of info.archinnov.achilles.internal.metadata.parsing.EntityIntrospectorTest

/*
* Copyright (C) 2012-2014 DuyHai DOAN
*
*  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 info.archinnov.achilles.internal.metadata.parsing;

import static info.archinnov.achilles.type.ConsistencyLevel.ALL;
import static info.archinnov.achilles.type.ConsistencyLevel.ANY;
import static info.archinnov.achilles.type.ConsistencyLevel.LOCAL_QUORUM;
import static info.archinnov.achilles.type.ConsistencyLevel.ONE;
import static info.archinnov.achilles.type.ConsistencyLevel.THREE;
import static info.archinnov.achilles.type.ConsistencyLevel.TWO;
import static info.archinnov.achilles.type.InsertStrategy.ALL_FIELDS;
import static info.archinnov.achilles.type.InsertStrategy.NOT_NULL_FIELDS;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import com.google.common.base.Optional;
import info.archinnov.achilles.internal.metadata.parsing.context.PropertyParsingContext;
import info.archinnov.achilles.test.parser.entity.BeanWithKeyspaceAndTableName;
import info.archinnov.achilles.test.parser.entity.BeanWithNamingStrategy;
import info.archinnov.achilles.type.NamingStrategy;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import info.archinnov.achilles.annotations.Column;
import info.archinnov.achilles.annotations.Consistency;
import info.archinnov.achilles.annotations.Entity;
import info.archinnov.achilles.annotations.Id;
import info.archinnov.achilles.annotations.Strategy;
import info.archinnov.achilles.annotations.TimeUUID;
import info.archinnov.achilles.exception.AchillesBeanMappingException;
import info.archinnov.achilles.internal.context.ConfigurationContext;
import info.archinnov.achilles.internal.metadata.holder.EntityMeta;
import info.archinnov.achilles.internal.metadata.holder.PropertyMeta;
import info.archinnov.achilles.internal.metadata.parsing.context.EntityParsingContext;
import info.archinnov.achilles.test.mapping.entity.CompleteBean;
import info.archinnov.achilles.test.parser.entity.BeanWithComment;
import info.archinnov.achilles.test.parser.entity.ChildBean;
import info.archinnov.achilles.type.ConsistencyLevel;
import info.archinnov.achilles.type.InsertStrategy;
import info.archinnov.achilles.type.Pair;

@RunWith(MockitoJUnitRunner.class)
public class EntityIntrospectorTest {

    @Rule
    public ExpectedException expectedEx = ExpectedException.none();

    @Mock
    private EntityMeta entityMeta;

    @Mock
    private PropertyMeta idMeta;

    @Mock
    private PropertyMeta wideMapMeta;

    @Mock
    private Map<Method, PropertyMeta> getterMetas;

    @Mock
    private Map<Method, PropertyMeta> setterMetas;

    @Mock
    private EntityParsingContext parsingContext;

    @Mock
    private ConfigurationContext configContext;

    private final EntityIntrospector introspector = new EntityIntrospector();

    @Test
    public void should_derive_getter() throws Exception {

        class Test {

            @SuppressWarnings("unused")
            Boolean old;
        }

        String[] getterNames = introspector.deriveGetterName(Test.class.getDeclaredField("old"));
        assertThat(getterNames).hasSize(1);
        assertThat(getterNames[0]).isEqualTo("getOld");
    }

    @Test
    public void should_derive_getter_for_boolean_primitive() throws Exception {

        class Test {

            @SuppressWarnings("unused")
            boolean old;
        }

        String[] getterNames = introspector.deriveGetterName(Test.class.getDeclaredField("old"));
        assertThat(getterNames).hasSize(2);
        assertThat(getterNames[0]).isEqualTo("isOld");
        assertThat(getterNames[1]).isEqualTo("getOld");
    }

    @Test
    public void should_derive_setter() throws Exception {
        class Test {
            @SuppressWarnings("unused")
            boolean a;
        }

        assertThat(introspector.deriveSetterName(Test.class.getDeclaredField("a"))).isEqualTo("setA");
    }

    @Test
    public void should_exception_when_no_getter() throws Exception {

        class Test {
            @SuppressWarnings("unused")
            String name;
        }

        expectedEx.expect(AchillesBeanMappingException.class);
        expectedEx.expectMessage("The getter for field 'name' of type 'null' does not exist");

        introspector.findGetter(Test.class, Test.class.getDeclaredField("name"));
    }

    @Test
    public void should_exception_when_no_setter() throws Exception {

        class Test {
            String name;

            @SuppressWarnings("unused")
            public String getA() {
                return name;
            }
        }

        expectedEx.expect(AchillesBeanMappingException.class);
        expectedEx.expectMessage("The setter for field 'name' of type 'null' does not exist");

        introspector.findSetter(Test.class, Test.class.getDeclaredField("name"));
    }

    @Test
    public void should_exception_when_incorrect_getter() throws Exception {

        class Test {
            @SuppressWarnings("unused")
            String name;

            @SuppressWarnings("unused")
            public Long getName() {
                return 1L;
            }

        }
        expectedEx.expect(AchillesBeanMappingException.class);
        expectedEx.expectMessage("The getter for field 'name' of type 'null' does not return correct type");

        introspector.findGetter(Test.class, Test.class.getDeclaredField("name"));
    }

    @Test
    public void should_exception_when_setter_returning_wrong_type() throws Exception {

        @SuppressWarnings("unused")
        class Test {
            String name;

            public String getName() {
                return name;
            }

            public Long setName(String name) {
                return 1L;
            }

        }
        expectedEx.expect(AchillesBeanMappingException.class);
        expectedEx
                .expectMessage("The setter for field 'name' of type 'null' does not return correct type or does not have the correct parameter");

        introspector.findSetter(Test.class, Test.class.getDeclaredField("name"));
    }

    @Test
    public void should_exception_when_setter_taking_wrong_type() throws Exception {

        @SuppressWarnings("unused")
        class Test {
            String name;

            public String getName() {
                return name;
            }

            public void setName(Long name) {
            }

        }

        expectedEx.expect(AchillesBeanMappingException.class);
        expectedEx.expectMessage("The setter for field 'name' of type 'null' does not exist or is incorrect");

        introspector.findSetter(Test.class, Test.class.getDeclaredField("name"));
    }

    @Test
    public void should_find_getter_from_boolean_as_isOld() throws Exception {
        @SuppressWarnings("unused")
        class Test {
            boolean old;

            public boolean isOld() {
                return old;
            }

            public void setOld(boolean old) {
                this.old = old;
            }
        }

        Method[] accessors = introspector.findAccessors(Test.class, Test.class.getDeclaredField("old"));

        assertThat(accessors[0].getName()).isEqualTo("isOld");
    }

    @Test
    public void should_find_getter_from_boolean_as_getOld() throws Exception {
        @SuppressWarnings("unused")
        class Test {
            boolean old;

            public boolean getOld() {
                return old;
            }

            public void setOld(boolean old) {
                this.old = old;
            }
        }

        Method[] accessors = introspector.findAccessors(Test.class, Test.class.getDeclaredField("old"));

        assertThat(accessors[0].getName()).isEqualTo("getOld");
    }

    @Test
    public void should_find_accessors() throws Exception {

        Method[] accessors = introspector.findAccessors(Bean.class,
                Bean.class.getDeclaredField("complicatedAttributeName"));

        assertThat(accessors).hasSize(2);
        assertThat(accessors[0].getName()).isEqualTo("getComplicatedAttributeName");
        assertThat(accessors[1].getName()).isEqualTo("setComplicatedAttributeName");
    }

    @Test
    public void should_find_accessors_from_collection_types() throws Exception {

        Method[] accessors = introspector.findAccessors(ComplexBean.class,
                ComplexBean.class.getDeclaredField("friends"));

        assertThat(accessors).hasSize(2);
        assertThat(accessors[0].getName()).isEqualTo("getFriends");
        assertThat(accessors[1].getName()).isEqualTo("setFriends");
    }

    @Test
    public void should_find_accessors_from_counter_type() throws Exception {
        Method[] accessors = introspector.findAccessors(CompleteBean.class,
                CompleteBean.class.getDeclaredField("count"));

        assertThat(accessors).hasSize(2);
        assertThat(accessors[0].getName()).isEqualTo("getCount");
        assertThat(accessors[1].getName()).isEqualTo("setCount");
    }

    @Test
    public void should_get_inherited_fields() throws Exception {
        List<Field> fields = introspector.getInheritedPrivateFields(ChildBean.class);

        assertThat(fields).hasSize(4);
        assertThat(fields.get(0).getName()).isEqualTo("nickname");
        assertThat(fields.get(1).getName()).isEqualTo("name");
        assertThat(fields.get(2).getName()).isEqualTo("address");
        assertThat(fields.get(3).getName()).isEqualTo("id");
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Test
    public void should_get_inherited_field_by_annotation() throws Exception {
        Field id = introspector.getInheritedPrivateFields(ChildBean.class, Id.class);

        assertThat(id.getName()).isEqualTo("id");
        assertThat(id.getType()).isEqualTo((Class) Long.class);
    }

    @Test
    public void should_not_get_inherited_field_by_annotation_when_no_match() throws Exception {
        assertThat(introspector.getInheritedPrivateFields(ChildBean.class, TimeUUID.class)).isNull();
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Test
    public void should_get_inherited_field_by_annotation_and_name() throws Exception {
        Field address = introspector.getInheritedPrivateFields(ChildBean.class, Column.class, "address");

        assertThat(address.getName()).isEqualTo("address");
        assertThat(address.getType()).isEqualTo((Class) String.class);
    }

    @Test
    public void should_not_get_inherited_field_by_annotation_and_name_when_no_match() throws Exception {
        assertThat(introspector.getInheritedPrivateFields(ChildBean.class, TimeUUID.class, "address")).isNull();
    }

    @Test
    public void should_infer_table_comment_from_annotation() throws Exception {
        String comment = introspector.inferTableComment(BeanWithComment.class, "default comment");
        assertThat(comment).isEqualTo("Table BeanWithComment");
    }

    @Test
    public void should_infer_table_comment_from_default_value() throws Exception {
        String comment = introspector.inferTableComment(BeanWithKeyspaceAndTableName.class, "default comment");
        assertThat(comment).isEqualTo("default comment");
    }

    @Test
    public void should_infer_keyspace_name_from_annotation() throws Exception {
        //When
        String keyspaceName = introspector.inferKeyspaceName(BeanWithNamingStrategy.class, Optional.<String>absent(), NamingStrategy.SNAKE_CASE);

        //Then
        assertThat(keyspaceName).isEqualTo("my_keyspace");
    }

    @Test
    public void should_infer_keyspace_name_from_config() throws Exception {
        //When
        String keyspaceName = introspector.inferKeyspaceName(ComplexBean.class, Optional.fromNullable("ks"), NamingStrategy.LOWER_CASE);

        //Then
        assertThat(keyspaceName).isEqualTo("ks");
    }

    @Test
    public void should_exception_when_keyspace_name_not_found() throws Exception {
        //When
        expectedEx.expect(AchillesBeanMappingException.class);
        expectedEx.expectMessage("No keyspace name found for entity '"+CompleteBean.class.getCanonicalName()+"'. Keyspace name is looked up using either the @Entity annotation or in configuration parameter");

        introspector.inferKeyspaceName(CompleteBean.class,  Optional.<String>absent(), NamingStrategy.LOWER_CASE);
    }

    @Test
    public void should_infer_table_name_from_annotation() throws Exception {
        String tableName = introspector.inferTableName(BeanWithNamingStrategy.class,  "canonicalName", NamingStrategy.SNAKE_CASE);
        assertThat(tableName).isEqualTo("my_table");
    }

    @Test
    public void should_infer_table_name_from_default_name() throws Exception {
        String tableName = introspector.inferTableName(CompleteBean.class, CompleteBean.class.getCanonicalName(), NamingStrategy.SNAKE_CASE);
        assertThat(tableName).isEqualTo("complete_bean");
    }

    @Test
    public void should_infer_table_name_from_default_name_when_empty_annotation_name() throws Exception {
        @Entity(table = "")
        class Test {

        }
        String tableName = introspector.inferTableName(Test.class, "canonicalName", NamingStrategy.LOWER_CASE);
        assertThat(tableName).isEqualTo("canonicalname");
    }

   


    @Test
    public void should_find_consistency_level_from_class() throws Exception {
        @Consistency(read = ANY, write = LOCAL_QUORUM)
        class Test {
        }

        when(configContext.getDefaultReadConsistencyLevel()).thenReturn(ONE);
        when(configContext.getDefaultWriteConsistencyLevel()).thenReturn(TWO);
        when(configContext.getReadConsistencyLevelForTable("table")).thenReturn(null);
        when(configContext.getWriteConsistencyLevelForTable("table")).thenReturn(null);

        Pair<ConsistencyLevel, ConsistencyLevel> levels = introspector.findConsistencyLevels(Test.class,"table",configContext);

        assertThat(levels.left).isEqualTo(ANY);
        assertThat(levels.right).isEqualTo(LOCAL_QUORUM);
    }

    @Test
    public void should_find_consistency_level_by_default() throws Exception {
        class Test {
        }

        when(configContext.getDefaultReadConsistencyLevel()).thenReturn(ONE);
        when(configContext.getDefaultWriteConsistencyLevel()).thenReturn(TWO);
        when(configContext.getReadConsistencyLevelForTable("table")).thenReturn(null);
        when(configContext.getWriteConsistencyLevelForTable("table")).thenReturn(null);

        Pair<ConsistencyLevel, ConsistencyLevel> levels = introspector.findConsistencyLevels(Test.class,"table",configContext);

        assertThat(levels.left).isEqualTo(ONE);
        assertThat(levels.right).isEqualTo(TWO);
    }

    @Test
    public void should_find_consistency_level_from_map_overriding_default() throws Exception {
        //Given
        class Test {
        }

        when(configContext.getDefaultReadConsistencyLevel()).thenReturn(ONE);
        when(configContext.getDefaultWriteConsistencyLevel()).thenReturn(TWO);
        when(configContext.getReadConsistencyLevelForTable("table")).thenReturn(THREE);
        when(configContext.getWriteConsistencyLevelForTable("table")).thenReturn(ALL);

        //When
        Pair<ConsistencyLevel, ConsistencyLevel> levels = introspector.findConsistencyLevels(Test.class,"table",configContext);

        //Then
        assertThat(levels.left).isEqualTo(THREE);
        assertThat(levels.right).isEqualTo(ALL);
    }

    @Test
    public void should_find_consistency_level_from_map_overriding_entity() throws Exception {
        //Given
        @Consistency(read = ANY, write = LOCAL_QUORUM)
        class Test {
        }

        when(configContext.getDefaultReadConsistencyLevel()).thenReturn(ONE);
        when(configContext.getDefaultWriteConsistencyLevel()).thenReturn(TWO);
        when(configContext.getReadConsistencyLevelForTable("table")).thenReturn(THREE);
        when(configContext.getWriteConsistencyLevelForTable("table")).thenReturn(ALL);

        //When
        Pair<ConsistencyLevel, ConsistencyLevel> levels = introspector.findConsistencyLevels(Test.class,"table",configContext);

        //Then
        assertThat(levels.left).isEqualTo(THREE);
        assertThat(levels.right).isEqualTo(ALL);
    }

    @Test
    public void should_get_insert_strategy_on_entity() throws Exception {
        //Given
        when(parsingContext.getDefaultInsertStrategy()).thenReturn(ALL_FIELDS);

        //When
        final InsertStrategy insertStrategy = introspector.getInsertStrategy(ComplexBean.class, parsingContext);

        //Then
        assertThat(insertStrategy).isEqualTo(NOT_NULL_FIELDS);
    }

    @Test
    public void should_get_default_insert_strategy_on_entity() throws Exception {
        //Given
        when(parsingContext.getDefaultInsertStrategy()).thenReturn(ALL_FIELDS);

        //When
        final InsertStrategy insertStrategy = introspector.getInsertStrategy(Bean.class, parsingContext);

        //Then
        assertThat(insertStrategy).isEqualTo(ALL_FIELDS);
    }

    @Test
    public void should_determine_class_naming_strategy() throws Exception {
        //When
        when(configContext.getGlobalNamingStrategy()).thenReturn(NamingStrategy.LOWER_CASE);
        final NamingStrategy classNamingStrategy = introspector.determineClassNamingStrategy(configContext, BeanWithNamingStrategy.class);
        final NamingStrategy defaultNamingStrategy = introspector.determineClassNamingStrategy(configContext, CompleteBean.class);

        //Then
        assertThat(classNamingStrategy).isSameAs(NamingStrategy.SNAKE_CASE);
        assertThat(defaultNamingStrategy).isSameAs(NamingStrategy.LOWER_CASE);
    }

    @Test
    public void should_infer_property_name_from_class_naming_strategy() throws Exception {
        //Given
        Field field = BeanWithNamingStrategy.class.getDeclaredField("firstName");

        //When
        final String actual = introspector.inferCQLColumnName(field, NamingStrategy.SNAKE_CASE);

        //Then
        assertThat(actual).isEqualTo("first_name");
    }

    @Test
         public void should_infer_property_name_from_column_annotation() throws Exception {
        //Given
        Field field = BeanWithNamingStrategy.class.getDeclaredField("lastName");

        //When
        final String actual = introspector.inferCQLColumnName(field, NamingStrategy.SNAKE_CASE);

        //Then
        assertThat(actual).isEqualTo("\"lastName\"");
    }

    @Test
    public void should_infer_property_name_from_id_annotation() throws Exception {
        //Given
        Field field = BeanWithNamingStrategy.class.getDeclaredField("id");

        //When
        final String actual = introspector.inferCQLColumnName(field, NamingStrategy.SNAKE_CASE);

        //Then
        assertThat(actual).isEqualTo("my_Id");
    }

    @Test
    public void should_infer_property_name_to_lower_case_when_no_column_annotation() throws Exception {
        //Given
        Field field = BeanWithNamingStrategy.class.getDeclaredField("unMappedColumn");

        //When
        final String actual = introspector.inferCQLColumnName(field, NamingStrategy.LOWER_CASE);

        //Then
        assertThat(actual).isEqualTo("unmappedcolumn");
    }


    class Bean {

        private String complicatedAttributeName;

        public String getComplicatedAttributeName() {
            return complicatedAttributeName;
        }

        public void setComplicatedAttributeName(String complicatedAttributeName) {
            this.complicatedAttributeName = complicatedAttributeName;
        }
    }

    @Strategy(insert = InsertStrategy.NOT_NULL_FIELDS)
    class ComplexBean {
        private List<String> friends;

        public List<String> getFriends() {
            return friends;
        }

        public void setFriends(List<String> friends) {
            this.friends = friends;
        }
    }
}
TOP

Related Classes of info.archinnov.achilles.internal.metadata.parsing.EntityIntrospectorTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.