/*
 * Copyright 2017, TeamDev Ltd. All rights reserved.
 *
 * Redistribution and use in source and/or binary forms, with or without
 * modification, must retain the above copyright notice and the following
 * disclaimer.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.spine3.server.storage.datastore.type;

import com.google.protobuf.Timestamp;
import org.junit.Test;
import org.spine3.base.Version;
import org.spine3.server.entity.storage.Column;
import org.spine3.server.entity.storage.ColumnTypeRegistry;

import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

/**
 * @author Dmytro Dashenkov
 */
public class DatastoreTypeRegistryShould {

    @Test
    public void have_default_column_types() {
        final ColumnTypeRegistry<DatastoreColumnType> registry = DatastoreTypeRegistry.defaultInstance();
        final DatastoreColumnType<?, ?> stringType = registry.get(mockColumn(String.class));
        assertNotNull(stringType);
        final DatastoreColumnType<?, ?> intType = registry.get(mockColumn(int.class));
        assertNotNull(intType);
        final DatastoreColumnType<?, ?> booleanType = registry.get(mockColumn(boolean.class));
        assertNotNull(booleanType);
        final DatastoreColumnType<?, ?> messageType = registry.get(mockColumn(String.class));
        assertNotNull(messageType);
        final DatastoreColumnType<?, ?> timestampType = registry.get(mockColumn(Timestamp.class));
        assertNotNull(timestampType);
        final DatastoreColumnType<?, ?> versionType = registry.get(mockColumn(Version.class));
        assertNotNull(versionType);
    }

    private static Column<?> mockColumn(Class type) {
        final Column<?> column = mock(Column.class);
        when(column.getType()).thenReturn(type);
        return column;
    }
}

@@ -1061,16 +1061,58 @@
 .type;%0A%0A
+import com.google.cloud.datastore.Entity;%0A
 import c
@@ -1305,16 +1305,64 @@
 istry;%0A%0A
+import static org.hamcrest.Matchers.instanceOf;%0A
 import s
@@ -1399,16 +1399,59 @@
 otNull;%0A
+import static org.junit.Assert.assertThat;%0A
 import s
@@ -2556,182 +2556,1905 @@
     
-private static Column%3C?%3E mockColumn(Class type) %7B%0A        final Column%3C?%3E column = mock(Column.class);%0A        when(column.getType()).thenReturn(type);%0A        return column;
+@Test%0A    public void allow_to_customize_types() %7B%0A        final ColumnTypeRegistry%3CDatastoreColumnType%3E registry =%0A                DatastoreTypeRegistry.predifinedValuesAnd()%0A                                     .put(byte.class, new ByteColumnType())%0A                                     .build();%0A        final DatastoreColumnType byteColumnType = registry.get(mockColumn(Byte.class));%0A        assertNotNull(byteColumnType);%0A        assertThat(byteColumnType, instanceOf(ByteColumnType.class));%0A    %7D%0A%0A    @Test%0A    public void allow_to_override_types() %7B%0A        final ColumnTypeRegistry%3CDatastoreColumnType%3E registry =%0A                DatastoreTypeRegistry.predifinedValuesAnd()%0A                                     .put(String.class, new CustomStringType())%0A                                     .build();%0A        final DatastoreColumnType byteColumnType = registry.get(mockColumn(String.class));%0A        assertNotNull(byteColumnType);%0A        assertThat(byteColumnType, instanceOf(CustomStringType.class));%0A    %7D%0A%0A    private static Column%3C?%3E mockColumn(Class type) %7B%0A        final Column%3C?%3E column = mock(Column.class);%0A        when(column.getType()).thenReturn(type);%0A        return column;%0A    %7D%0A%0A    private static class ByteColumnType extends SimpleDatastoreColumnType%3CByte%3E %7B%0A        @Override%0A        public void setColumnValue(Entity.Builder storageRecord, Byte value, String columnIdentifier) %7B%0A            storageRecord.set(columnIdentifier, value);%0A        %7D%0A    %7D%0A%0A    private static class CustomStringType implements DatastoreColumnType%3CString, Integer%3E %7B%0A%0A        @Override%0A        public Integer convertColumnValue(String fieldValue) %7B%0A            return fieldValue.length();%0A        %7D%0A%0A        @Override%0A        public void setColumnValue(Entity.Builder storageRecord, Integer value, String columnIdentifier) %7B%0A            storageRecord.set(columnIdentifier, value);%0A        %7D
 %0A   

Add some more tests for DatastoreTypeRegistry.