/* * Copyright (c) 2011, Niclas Hehdman. All Rights Reserved. * Copyright (c) 2012, Paul Merlin. All Rights Reserved. * * 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 org.qi4j.test.value; import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.junit.Before; import org.junit.Test; import org.qi4j.api.common.Optional; import org.qi4j.api.injection.scope.Service; import org.qi4j.api.property.Property; import org.qi4j.api.type.CollectionType; import org.qi4j.api.type.MapType; import org.qi4j.api.type.ValueCompositeType; import org.qi4j.api.type.ValueType; import org.qi4j.api.value.ValueBuilder; import org.qi4j.api.value.ValueSerialization; import org.qi4j.bootstrap.AssemblyException; import org.qi4j.bootstrap.ModuleAssembly; import org.qi4j.functional.Iterables; import org.qi4j.test.AbstractQi4jTest; import static org.junit.Assert.*; import static org.qi4j.io.Inputs.iterable; import static org.qi4j.io.Inputs.text; import static org.qi4j.io.Outputs.collection; import static org.qi4j.io.Outputs.text; import static org.qi4j.io.Transforms.map; /** * Assert that ValueSerialization behaviour on Collections and Maps is correct. */ // TODO How to assert that given a collection of valuecomposites when serializing and deserializing we have to OOME? public class AbstractCollectionSerializationTest extends AbstractQi4jTest { @Override public void assemble( ModuleAssembly module ) throws AssemblyException { module.values( SomeValue.class ); } @Before public void before() { module.injectTo( this ); } @Service @SuppressWarnings( "ProtectedField" ) protected ValueSerialization valueSerialization; @Test public void testIOString() throws Exception { StringBuilder sb = new StringBuilder(); iterable( byteCollection() ).transferTo( map( valueSerialization.serialize(), text( sb ) ) ); String output = sb.toString(); List<Byte> list = new ArrayList<Byte>(); text( output ).transferTo( map( valueSerialization.deserialize( Byte.class ), collection( list ) ) ); assertEquals( byteCollection(), list ); } @Test public void givenPrimitiveArrayWithIntsWhenSerializingAndDeserializingExpectEquals() throws Exception { int[] primitiveArray = new int[] { 23, 42, -23, -42 }; String output = valueSerialization.serialize( primitiveArray ); int[] deserialized = valueSerialization.deserialize( int[].class, output ); assertArrayEquals( primitiveArray, deserialized ); } @Test public void givenArrayWithByteAndNullElementWhenSerializingAndDeserializingExpectEquals() throws Exception { Byte[] array = new Byte[] { 9, null, -12, -12, 127, -128, 73 }; String output = valueSerialization.serialize( array ); Byte[] deserialized = valueSerialization.deserialize( Byte[].class, output ); assertArrayEquals( array, deserialized ); } @Test public void givenIterableTypeWithByteAndNullElementWhenSerializingAndDeserializingExpectEquals() throws Exception { String output = valueSerialization.serialize( Iterables.iterable( byteCollection().toArray() ) ); CollectionType collectionType = new CollectionType( List.class, new ValueType( Byte.class ) ); List<Byte> list = valueSerialization.deserialize( collectionType, output ); assertEquals( byteCollection(), list ); } @Test public void givenCollectionTypeWithByteAndNullElementWhenSerializingAndDeserializingExpectEquals() throws Exception { String output = valueSerialization.serialize( byteCollection() ); CollectionType collectionType = new CollectionType( Set.class, new ValueType( Byte.class ) ); Set<Byte> list = valueSerialization.deserialize( collectionType, output ); assertEquals( new LinkedHashSet<Byte>( byteCollection() ), list ); } @Test public void givenCollectionTypeWithCharacterAndNullElementWhenSerializingAndDeserializingExpectEquals() throws Exception { String output = valueSerialization.serialize( characterCollection() ); CollectionType collectionType = new CollectionType( List.class, new ValueType( Character.class ) ); List<Character> list = valueSerialization.deserialize( collectionType, output ); assertEquals( characterCollection(), list ); } @Test public void givenCollectionTypeWithShortAndNullElementWhenSerializingAndDeserializingExpectEquals() throws Exception { String output = valueSerialization.serialize( shortCollection() ); CollectionType collectionType = new CollectionType( List.class, new ValueType( Short.class ) ); List<Short> list = valueSerialization.deserialize( collectionType, output ); assertEquals( shortCollection(), list ); } @Test public void givenCollectionTypeWithIntegerAndNullElementWhenSerializingAndDeserializingExpectEquals() throws Exception { String output = valueSerialization.serialize( integerCollection() ); CollectionType collectionType = new CollectionType( List.class, new ValueType( Integer.class ) ); List<Integer> list = valueSerialization.deserialize( collectionType, output ); assertEquals( integerCollection(), list ); } @Test public void givenCollectionTypeWithLongAndNullElementWhenSerializingAndDeserializingExpectEquals() throws Exception { String output = valueSerialization.serialize( longCollection() ); CollectionType collectionType = new CollectionType( List.class, new ValueType( Long.class ) ); List<Long> list = valueSerialization.deserialize( collectionType, output ); assertEquals( longCollection(), list ); } @Test public void givenCollectionTypeWithFloatAndNullElementWhenSerializingAndDeserializingExpectEquals() throws Exception { String output = valueSerialization.serialize( floatCollection() ); CollectionType collectionType = new CollectionType( List.class, new ValueType( Float.class ) ); List<Float> list = valueSerialization.deserialize( collectionType, output ); assertEquals( floatCollection(), list ); } @Test public void givenCollectionTypeWithDoubleAndNullElementWhenSerializingExpectCorrectJsonOutput() throws Exception { String output = valueSerialization.serialize( doubleCollection() ); CollectionType collectionType = new CollectionType( List.class, new ValueType( Double.class ) ); List<Double> list = valueSerialization.deserialize( collectionType, output ); assertEquals( doubleCollection(), list ); } @Test public void givenCollectionTypeWithBigIntegerAndNullElementWhenSerializingAndDeserializingExpectEquals() throws Exception { String output = valueSerialization.serialize( bigIntegerCollection() ); CollectionType collectionType = new CollectionType( List.class, new ValueType( BigInteger.class ) ); List<BigInteger> list = valueSerialization.deserialize( collectionType, output ); assertEquals( bigIntegerCollection(), list ); } @Test public void givenCollectionTypeWithBigDecimalAndNullElementWhenSerializingAndDeserializingExpectEquals() throws Exception { String output = valueSerialization.serialize( bigDecimalCollection() ); CollectionType collectionType = new CollectionType( Collection.class, new ValueType( BigDecimal.class ) ); Collection<BigDecimal> collection = valueSerialization.deserialize( collectionType, output ); assertEquals( bigDecimalCollection(), collection ); } @Test public void givenMapOfStringByteAndNullElementWhenSerializingAndDeserializingExpectEquals() throws Exception { String output = valueSerialization.serialize( stringByteMap() ); MapType mapType = new MapType( Map.class, new ValueType( String.class ), new ValueType( Byte.class ) ); Map<String, Byte> value = valueSerialization.deserialize( mapType, output ); assertEquals( stringByteMap(), value ); } @Test public void givenMapOfStringListStringAndNullElementWhenSerializingAndDeserializingExpectEquals() throws Exception { String output = valueSerialization.serialize( stringMultiMap() ); CollectionType collectionType = new CollectionType( List.class, new ValueType( String.class ) ); MapType mapType = new MapType( Map.class, new ValueType( String.class ), collectionType ); Map<String, List<String>> value = valueSerialization.deserialize( mapType, output ); assertEquals( stringMultiMap(), value ); } @Test public void givenListOfMapStringStringAndNullElementWhenSerializingAndDeserializingExpectEquals() throws Exception { String output = valueSerialization.serialize( stringListOfMaps() ); ValueType stringType = new ValueType( String.class ); CollectionType collectionType = new CollectionType( List.class, new MapType( Map.class, stringType, stringType ) ); List<Map<String, String>> value = valueSerialization.deserialize( collectionType, output ); assertEquals( stringListOfMaps(), value ); } @Test public void givenListOfValueCompositesAndNullElementWhenSerializingAndDeserializingExpectEquals() throws Exception { String output = valueSerialization.serialize( valueCompositesList() ); ValueCompositeType valueType = module.valueDescriptor( SomeValue.class.getName() ).valueType(); CollectionType collectionType = new CollectionType( List.class, valueType ); List<SomeValue> value = valueSerialization.deserialize( collectionType, output ); assertEquals( valueCompositesList(), value ); } private ArrayList<Byte> byteCollection() { ArrayList<Byte> value = new ArrayList<Byte>(); value.add( (byte) 9 ); value.add( null ); value.add( (byte) -12 ); value.add( (byte) -12 ); value.add( (byte) 127 ); value.add( (byte) -128 ); value.add( (byte) 73 ); return value; } private List<Character> characterCollection() { List<Character> value = new ArrayList<Character>(); value.add( 'Q' ); value.add( 'i' ); value.add( null ); value.add( '4' ); value.add( 'j' ); return value; } private Collection<Short> shortCollection() { Collection<Short> value = new ArrayList<Short>(); value.add( (short) -32768 ); value.add( (short) 32767 ); value.add( (short) -82 ); value.add( null ); return value; } private Collection<Integer> integerCollection() { Collection<Integer> value = new ArrayList<Integer>(); value.add( Integer.MAX_VALUE ); value.add( -283 ); value.add( null ); value.add( Integer.MIN_VALUE ); value.add( 238 ); return value; } private Collection<Long> longCollection() { Collection<Long> value = new ArrayList<Long>(); value.add( 98239723L ); value.add( -1298233L ); value.add( -1L ); value.add( 0L ); value.add( null ); value.add( 1L ); value.add( Long.MAX_VALUE ); value.add( Long.MIN_VALUE ); return value; } private Collection<Float> floatCollection() { Collection<Float> value = new ArrayList<Float>(); value.add( -1f ); value.add( 1f ); value.add( 1f ); value.add( 0f ); value.add( Float.MAX_VALUE ); value.add( Float.MIN_VALUE ); value.add( null ); value.add( 0.123456f ); value.add( -0.232321f ); return value; } private Collection<Double> doubleCollection() { Collection<Double> value = new ArrayList<Double>(); value.add( -1.0 ); value.add( 1.0 ); value.add( 0.0 ); value.add( Double.MAX_VALUE ); value.add( null ); value.add( Double.MIN_VALUE ); value.add( 0.123456 ); value.add( -0.232321 ); return value; } private Collection<BigInteger> bigIntegerCollection() { Collection<BigInteger> value = new ArrayList<BigInteger>(); value.add( new BigInteger( "-1" ) ); value.add( BigInteger.ZERO ); value.add( BigInteger.ONE ); value.add( null ); value.add( BigInteger.TEN ); value.add( new BigInteger( "-1827368263823729372397239829332" ) ); value.add( new BigInteger( "2398723982982379827373972398723" ) ); return value; } private Collection<BigDecimal> bigDecimalCollection() { Collection<BigDecimal> value = new ArrayList<BigDecimal>(); value.add( new BigDecimal( "1.2" ) ); value.add( new BigDecimal( "3.4" ) ); value.add( null ); value.add( new BigDecimal( "5.6" ) ); return value; } private Map<String, Byte> stringByteMap() { Map<String, Byte> value = new LinkedHashMap<String, Byte>(); value.put( "a", (byte) 9 ); value.put( "b", null ); value.put( "c", (byte) -12 ); return value; } private Map<String, List<String>> stringMultiMap() { Map<String, List<String>> value = new LinkedHashMap<String, List<String>>(); List<String> list = new ArrayList<String>(); list.add( "foo" ); list.add( "bar" ); list.add( null ); list.add( "cathedral" ); list.add( "bazar" ); value.put( "alpha", list ); value.put( "beta", null ); value.put( "gamma", Collections.<String>emptyList() ); return value; } private List<Map<String, String>> stringListOfMaps() { List<Map<String, String>> value = new ArrayList<Map<String, String>>(); Map<String, String> map = new LinkedHashMap<String, String>(); map.put( "foo", "bar" ); map.put( "cathedral", "bazar" ); map.put( "yield", null ); map.put( "42", "23" ); value.add( map ); value.add( null ); value.add( Collections.<String, String>emptyMap() ); return value; } private List<SomeValue> valueCompositesList() { List<SomeValue> list = new ArrayList<SomeValue>(); list.add( newSomeValue( "", "bazar" ) ); list.add( null ); list.add( newSomeValue( "bar", null ) ); return list; } public static interface SomeValue { Property<String> foo(); @Optional Property<String> cathedral(); } private SomeValue newSomeValue( String foo, String cathedral ) { ValueBuilder<SomeValue> builder = module.newValueBuilder( SomeValue.class ); SomeValue value = builder.prototype(); value.foo().set( foo ); if( cathedral != null ) { value.cathedral().set( cathedral ); } return builder.newInstance(); } }