1   /*
2    * Copyright 2006-2007-2007 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package net.sf.ezmorph.bean;
18  
19  import java.util.ArrayList;
20  import java.util.HashMap;
21  import java.util.Map;
22  
23  import junit.framework.Test;
24  import junit.framework.TestCase;
25  import junit.framework.TestSuite;
26  import junit.textui.TestRunner;
27  import net.sf.ezmorph.MorphException;
28  import net.sf.ezmorph.MorphUtils;
29  import net.sf.ezmorph.MorpherRegistry;
30  import net.sf.ezmorph.bean.sample.BeanA;
31  import net.sf.ezmorph.bean.sample.BeanB;
32  import net.sf.ezmorph.bean.sample.BeanC;
33  import net.sf.ezmorph.bean.sample.BeanD;
34  import net.sf.ezmorph.bean.sample.ObjectBean;
35  import net.sf.ezmorph.bean.sample.PrimitiveBean;
36  import net.sf.ezmorph.bean.sample.TypedBean;
37  import net.sf.ezmorph.test.ArrayAssertions;
38  
39  import org.apache.commons.beanutils.DynaBean;
40  
41  /**
42   * @author Andres Almiray <aalmiray@users.sourceforge.net>
43   */
44  public class BeanMorpherTest extends TestCase
45  {
46     public static void main( String[] args )
47     {
48        TestRunner.run( suite() );
49     }
50  
51     public static Test suite()
52     {
53        TestSuite suite = new TestSuite( BeanMorpherTest.class );
54        suite.setName( "BeanMorpher Tests" );
55        return suite;
56     }
57  
58     private MorpherRegistry morpherRegistry;
59  
60     public BeanMorpherTest( String name )
61     {
62        super( name );
63     }
64  
65     public void testException_array_class()
66     {
67        try{
68           new BeanMorpher( Map[].class, morpherRegistry );
69           fail( "Expected an MorphException" );
70        }
71        catch( MorphException expected ){
72           // ok
73        }
74     }
75  
76     public void testException_Collection_subclass()
77     {
78        try{
79           new BeanMorpher( ArrayList.class, morpherRegistry );
80           fail( "Expected an MorphException" );
81        }
82        catch( MorphException expected ){
83           // ok
84        }
85     }
86  
87     public void testException_DynaBean_class()
88     {
89        try{
90           new BeanMorpher( MorphDynaBean.class, morpherRegistry );
91           fail( "Expected an MorphException" );
92        }
93        catch( MorphException expected ){
94           // ok
95        }
96     }
97  
98     public void testException_interface_class()
99     {
100       try{
101          new BeanMorpher( Map.class, morpherRegistry );
102          fail( "Expected an MorphException" );
103       }
104       catch( MorphException expected ){
105          // ok
106       }
107    }
108 
109    public void testException_Map_subclass()
110    {
111       try{
112          new BeanMorpher( HashMap.class, morpherRegistry );
113          fail( "Expected an MorphException" );
114       }
115       catch( MorphException expected ){
116          // ok
117       }
118    }
119 
120    public void testException_null_class()
121    {
122       try{
123          new BeanMorpher( null, morpherRegistry );
124          fail( "Expected an MorphException" );
125       }
126       catch( MorphException expected ){
127          // ok
128       }
129    }
130 
131    public void testException_null_morpherRegistry()
132    {
133       try{
134          new BeanMorpher( BeanA.class, null );
135          fail( "Expected an MorphException" );
136       }
137       catch( MorphException expected ){
138          // ok
139       }
140    }
141 
142    public void testException_primitive_class()
143    {
144       try{
145          new BeanMorpher( int.class, morpherRegistry );
146          fail( "Expected an MorphException" );
147       }
148       catch( MorphException expected ){
149          // ok
150       }
151    }
152 
153    public void testException_String_class()
154    {
155       try{
156          new BeanMorpher( String.class, morpherRegistry );
157          fail( "Expected an MorphException" );
158       }
159       catch( MorphException expected ){
160          // ok
161       }
162    }
163 
164    public void testException_wrapper_class()
165    {
166       try{
167          new BeanMorpher( Integer.class, morpherRegistry );
168          fail( "Expected an MorphException" );
169       }
170       catch( MorphException expected ){
171          // ok
172       }
173       try{
174          new BeanMorpher( Boolean.class, morpherRegistry );
175          fail( "Expected an MorphException" );
176       }
177       catch( MorphException expected ){
178          // ok
179       }
180       try{
181          new BeanMorpher( Character.class, morpherRegistry );
182          fail( "Expected an MorphException" );
183       }
184       catch( MorphException expected ){
185          // ok
186       }
187    }
188 
189    public void testMorph_dynaBean() throws Exception
190    {
191       Map properties = new HashMap();
192       properties.put( "string", String.class );
193       properties.put( "integer", Integer.class );
194       properties.put( "bool", Boolean.class );
195       MorphDynaClass dynaClass = new MorphDynaClass( properties );
196       MorphDynaBean dynaBean = (MorphDynaBean) dynaClass.newInstance();
197       dynaBean.setDynaBeanClass( dynaClass );
198       dynaBean.set( "string", "dyna morph" );
199       dynaBean.set( "integer", "24" );
200       dynaBean.set( "bool", "false" );
201 
202       BeanMorpher morpher = new BeanMorpher( BeanA.class, morpherRegistry );
203       BeanA beanA = (BeanA) morpher.morph( dynaBean );
204       assertNotNull( beanA );
205       assertEquals( false, beanA.isBool() );
206       assertEquals( 24, beanA.getInteger() );
207       assertEquals( "dyna morph", beanA.getString() );
208    }
209 
210    public void testMorph_dynaBean_missingProperty() throws Exception
211    {
212       Map properties = new HashMap();
213       properties.put( "integer", Integer.class );
214       properties.put( "bool", Boolean.class );
215       MorphDynaClass dynaClass = new MorphDynaClass( properties );
216       MorphDynaBean dynaBean = (MorphDynaBean) dynaClass.newInstance();
217       dynaBean.setDynaBeanClass( dynaClass );
218       dynaBean.set( "integer", "24" );
219       dynaBean.set( "bool", "false" );
220 
221       BeanMorpher morpher = new BeanMorpher( BeanA.class, morpherRegistry );
222       BeanA beanA = (BeanA) morpher.morph( dynaBean );
223       assertNotNull( beanA );
224       assertEquals( false, beanA.isBool() );
225       assertEquals( 24, beanA.getInteger() );
226       assertEquals( "morph", beanA.getString() );
227    }
228    
229    public void testMorph_nested__dynaBeans() throws Exception
230    {
231       Map properties = new HashMap();
232       properties.put( "string", String.class );
233       properties.put( "integer", Integer.class );
234       properties.put( "bool", Boolean.class );
235       MorphDynaClass dynaClass = new MorphDynaClass( properties );
236       MorphDynaBean dynaBeanA = (MorphDynaBean) dynaClass.newInstance( morpherRegistry );
237       dynaBeanA.setDynaBeanClass( dynaClass );
238       dynaBeanA.set( "string", "dyna morph" );
239       dynaBeanA.set( "integer", "24" );
240       dynaBeanA.set( "bool", "false" );
241 
242       properties = new HashMap();
243       properties.put( "string", String.class );
244       properties.put( "integer", Integer.class );
245       properties.put( "bool", Boolean.class );
246       properties.put( "intarray", int[].class );
247       dynaClass = new MorphDynaClass( properties );
248       MorphDynaBean dynaBeanB = (MorphDynaBean) dynaClass.newInstance( morpherRegistry );
249       dynaBeanB.setDynaBeanClass( dynaClass );
250       dynaBeanB.set( "string", "dyna morph B" );
251       dynaBeanB.set( "integer", "48" );
252       dynaBeanB.set( "bool", "true" );
253       dynaBeanB.set( "intarray", new int[] { 4, 5, 6 } );
254 
255       properties = new HashMap();
256       properties.put( "beanA", DynaBean.class );
257       properties.put( "beanB", DynaBean.class );
258       dynaClass = new MorphDynaClass( properties );
259       MorphDynaBean dynaBeanC = (MorphDynaBean) dynaClass.newInstance( morpherRegistry );
260       dynaBeanC.setDynaBeanClass( dynaClass );
261       dynaBeanC.set( "beanA", dynaBeanA );
262       dynaBeanC.set( "beanB", dynaBeanB );
263 
264       morpherRegistry.registerMorpher( new BeanMorpher( BeanA.class, morpherRegistry ) );
265       morpherRegistry.registerMorpher( new BeanMorpher( BeanB.class, morpherRegistry ) );
266       BeanMorpher morpher = new BeanMorpher( BeanC.class, morpherRegistry );
267       BeanC beanC = (BeanC) morpher.morph( dynaBeanC );
268       assertNotNull( beanC );
269       BeanA beanA = beanC.getBeanA();
270       assertEquals( false, beanA.isBool() );
271       assertEquals( 24, beanA.getInteger() );
272       assertEquals( "dyna morph", beanA.getString() );
273       BeanB beanB = beanC.getBeanB();
274       assertEquals( true, beanB.isBool() );
275       assertEquals( 48, beanB.getInteger() );
276       assertEquals( "dyna morph B", beanB.getString() );
277       ArrayAssertions.assertEquals( new int[] { 4, 5, 6 }, beanB.getIntarray() );
278    }
279 
280    public void testMorph_null()
281    {
282       BeanMorpher morpher = new BeanMorpher( BeanA.class, morpherRegistry );
283       BeanA beanA = (BeanA) morpher.morph( null );
284       assertNull( beanA );
285    }
286 
287    public void testMorph_ObjectBean_to_PrimitiveBean()
288    {
289       ObjectBean objectBean = new ObjectBean();
290       objectBean.setPclass( Object.class );
291       objectBean.setPstring( "MORPH" );
292       morpherRegistry.registerMorpher( new BeanMorpher( PrimitiveBean.class, morpherRegistry ) );
293       morpherRegistry.registerMorpher( new BeanMorpher( ObjectBean.class, morpherRegistry ) );
294       PrimitiveBean primitiveBean = (PrimitiveBean) morpherRegistry.morph( PrimitiveBean.class,
295             objectBean );
296       assertNotNull( primitiveBean );
297       assertEquals( false, primitiveBean.isPboolean() );
298       assertEquals( (byte) 0, primitiveBean.getPbyte() );
299       assertEquals( (short) 0, primitiveBean.getPshort() );
300       assertEquals( 0, primitiveBean.getPint() );
301       assertEquals( 0L, primitiveBean.getPlong() );
302       assertEquals( 0f, primitiveBean.getPfloat(), 0f );
303       assertEquals( 0d, primitiveBean.getPdouble(), 0d );
304       assertEquals( '\0', primitiveBean.getPchar() );
305       assertEquals( null, primitiveBean.getParray() );
306       assertEquals( null, primitiveBean.getPlist() );
307       assertEquals( null, primitiveBean.getPbean() );
308       assertEquals( null, primitiveBean.getPmap() );
309       assertEquals( "MORPH", primitiveBean.getPstring() );
310       assertEquals( Object.class, primitiveBean.getPclass() );
311    }
312 
313    public void testMorph_ObjectBean_to_PrimitiveBean_lenient()
314    {
315       ObjectBean objectBean = new ObjectBean();
316       objectBean.setPclass( Object.class );
317       objectBean.setPstring( "MORPH" );
318       objectBean.setPbean( objectBean );
319       morpherRegistry.registerMorpher( new BeanMorpher( PrimitiveBean.class, morpherRegistry, true ) );
320       PrimitiveBean primitiveBean = (PrimitiveBean) morpherRegistry.morph( PrimitiveBean.class,
321             objectBean );
322       assertNotNull( primitiveBean );
323       assertEquals( false, primitiveBean.isPboolean() );
324       assertEquals( (byte) 0, primitiveBean.getPbyte() );
325       assertEquals( (short) 0, primitiveBean.getPshort() );
326       assertEquals( 0, primitiveBean.getPint() );
327       assertEquals( 0L, primitiveBean.getPlong() );
328       assertEquals( 0f, primitiveBean.getPfloat(), 0f );
329       assertEquals( 0d, primitiveBean.getPdouble(), 0d );
330       assertEquals( '\0', primitiveBean.getPchar() );
331       assertEquals( null, primitiveBean.getParray() );
332       assertEquals( null, primitiveBean.getPlist() );
333       assertEquals( null, primitiveBean.getPbean() );
334       assertEquals( null, primitiveBean.getPmap() );
335       assertEquals( "MORPH", primitiveBean.getPstring() );
336       assertEquals( Object.class, primitiveBean.getPclass() );
337    }
338 
339    public void testMorph_ObjectBean_to_PrimitiveBean_notLenient()
340    {
341       ObjectBean objectBean = new ObjectBean();
342       objectBean.setPclass( Object.class );
343       objectBean.setPstring( "MORPH" );
344       objectBean.setPbean( objectBean );
345       morpherRegistry.registerMorpher( new BeanMorpher( PrimitiveBean.class, morpherRegistry ) );
346       try{
347          morpherRegistry.morph( PrimitiveBean.class, objectBean );
348          fail( "Should have thrown a MorphException" );
349       }
350       catch( MorphException expected ){
351          // ok
352       }
353    }
354 
355    public void testMorph_ObjectBean_to_TypedBean()
356    {
357       ObjectBean objectBean = new ObjectBean();
358       objectBean.setPclass( Object.class );
359       objectBean.setPstring( "MORPH" );
360       morpherRegistry.registerMorpher( new BeanMorpher( TypedBean.class, morpherRegistry ) );
361       morpherRegistry.registerMorpher( new BeanMorpher( ObjectBean.class, morpherRegistry ) );
362       TypedBean typedBean = (TypedBean) morpherRegistry.morph( TypedBean.class, objectBean );
363       assertNotNull( typedBean );
364       assertEquals( null, typedBean.getPboolean() );
365       assertEquals( null, typedBean.getPbyte() );
366       assertEquals( null, typedBean.getPshort() );
367       assertEquals( null, typedBean.getPint() );
368       assertEquals( null, typedBean.getPlong() );
369       assertEquals( null, typedBean.getPfloat() );
370       assertEquals( null, typedBean.getPdouble() );
371       assertEquals( null, typedBean.getPchar() );
372       assertEquals( null, typedBean.getParray() );
373       assertEquals( null, typedBean.getPlist() );
374       assertEquals( null, typedBean.getPbean() );
375       assertEquals( null, typedBean.getPmap() );
376       assertEquals( "MORPH", typedBean.getPstring() );
377       assertEquals( Object.class, typedBean.getPclass() );
378    }
379 
380    public void testMorph_PrimitiveBean_to_ObjectBean()
381    {
382       PrimitiveBean primitiveBean = new PrimitiveBean();
383       primitiveBean.setPclass( Object.class );
384       primitiveBean.setPstring( "MORPH" );
385       morpherRegistry.registerMorpher( new BeanMorpher( ObjectBean.class, morpherRegistry ) );
386       ObjectBean objectBean = (ObjectBean) morpherRegistry.morph( ObjectBean.class, primitiveBean );
387       assertNotNull( objectBean );
388       assertEquals( Boolean.FALSE, objectBean.getPboolean() );
389       assertEquals( Byte.valueOf( "0" ), objectBean.getPbyte() );
390       assertEquals( Short.valueOf( "0" ), objectBean.getPshort() );
391       assertEquals( Integer.valueOf( "0" ), objectBean.getPint() );
392       assertEquals( Long.valueOf( "0" ), objectBean.getPlong() );
393       assertEquals( Float.valueOf( "0" ), objectBean.getPfloat() );
394       assertEquals( Double.valueOf( "0" ), objectBean.getPdouble() );
395       assertEquals( new Character( '\0' ), objectBean.getPchar() );
396       assertEquals( null, objectBean.getParray() );
397       assertEquals( null, objectBean.getPlist() );
398       assertEquals( null, objectBean.getPbean() );
399       assertEquals( null, objectBean.getPmap() );
400       assertEquals( "MORPH", objectBean.getPstring() );
401       assertEquals( Object.class, objectBean.getPclass() );
402    }
403 
404    public void testMorph_PrimitiveBean_to_TypedBean()
405    {
406       PrimitiveBean primitiveBean = new PrimitiveBean();
407       primitiveBean.setPclass( Object.class );
408       primitiveBean.setPstring( "MORPH" );
409       morpherRegistry.registerMorpher( new BeanMorpher( TypedBean.class, morpherRegistry ) );
410       TypedBean typedBean = (TypedBean) morpherRegistry.morph( TypedBean.class, primitiveBean );
411       assertNotNull( typedBean );
412       assertEquals( Boolean.FALSE, typedBean.getPboolean() );
413       assertEquals( Byte.valueOf( "0" ), typedBean.getPbyte() );
414       assertEquals( Short.valueOf( "0" ), typedBean.getPshort() );
415       assertEquals( Integer.valueOf( "0" ), typedBean.getPint() );
416       assertEquals( Long.valueOf( "0" ), typedBean.getPlong() );
417       assertEquals( Float.valueOf( "0" ), typedBean.getPfloat() );
418       assertEquals( Double.valueOf( "0" ), typedBean.getPdouble() );
419       assertEquals( new Character( '\0' ), typedBean.getPchar() );
420       assertEquals( null, typedBean.getParray() );
421       assertEquals( null, typedBean.getPlist() );
422       assertEquals( null, typedBean.getPbean() );
423       assertEquals( null, typedBean.getPmap() );
424       assertEquals( "MORPH", typedBean.getPstring() );
425       assertEquals( Object.class, typedBean.getPclass() );
426    }
427 
428    public void testMorph_unsupported()
429    {
430       BeanMorpher morpher = new BeanMorpher( BeanA.class, morpherRegistry );
431       try{
432          morpher.morph( new Object[0] );
433          fail( "Should vae thrown a MorphException" );
434       }
435       catch( MorphException expected ){
436          // ok
437       }
438    }
439 
440    public void testMorph_BeanA_to_BeanD()
441    {
442       morpherRegistry.registerMorpher( new BeanMorpher( BeanD.class, morpherRegistry ) );
443       BeanA beanA = new BeanA();
444       beanA.setBool( false );
445       beanA.setInteger( 84 );
446       beanA.setString( "string" );
447       BeanD beanD = (BeanD) morpherRegistry.morph( BeanD.class, beanA );
448       assertNotNull( beanD );
449       assertFalse( beanD.isBool() );
450       assertEquals( 84, beanD.getInteger() );
451       assertEquals( 0d, beanD.getDecimal(), 0d );
452    }
453 
454    protected void setUp() throws Exception
455    {
456       morpherRegistry = new MorpherRegistry();
457       MorphUtils.registerStandardMorphers( morpherRegistry );
458    }
459 }