1   /*
2    * Copyright 2002-2009 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.json;
18  
19  import java.lang.reflect.InvocationTargetException;
20  import java.util.ArrayList;
21  import java.util.Calendar;
22  import java.util.Date;
23  import java.util.HashMap;
24  import java.util.LinkedList;
25  import java.util.List;
26  import java.util.ListIterator;
27  import java.util.Map;
28  
29  import junit.framework.TestCase;
30  import net.sf.ezmorph.object.MapToDateMorpher;
31  import net.sf.json.sample.ArrayBean;
32  import net.sf.json.sample.BeanA;
33  import net.sf.json.sample.BeanA1763699;
34  import net.sf.json.sample.BeanB1763699;
35  import net.sf.json.sample.BeanC;
36  import net.sf.json.sample.ChildBean;
37  import net.sf.json.sample.DateBean;
38  import net.sf.json.sample.FieldBean;
39  import net.sf.json.sample.IdBean;
40  import net.sf.json.sample.InterfaceBean;
41  import net.sf.json.sample.JSONTestBean;
42  import net.sf.json.sample.MappedBean;
43  import net.sf.json.sample.Media;
44  import net.sf.json.sample.MediaBean;
45  import net.sf.json.sample.MediaList;
46  import net.sf.json.sample.MediaListBean;
47  import net.sf.json.sample.NumberArrayBean;
48  import net.sf.json.sample.PackageProtectedBean;
49  import net.sf.json.sample.ParentBean;
50  import net.sf.json.sample.Player;
51  import net.sf.json.sample.PlayerList;
52  import net.sf.json.sample.PrimitiveBean;
53  import net.sf.json.sample.PrivateConstructorBean;
54  import net.sf.json.sample.UnstandardBean;
55  import net.sf.json.sample.UnstandardBeanInstanceStrategy;
56  import net.sf.json.util.JSONUtils;
57  import net.sf.json.util.JavaIdentifierTransformer;
58  import net.sf.json.util.JsonEventListener;
59  
60  import org.apache.commons.beanutils.DynaBean;
61  import org.apache.commons.beanutils.PropertyUtils;
62  
63  /**
64   * @author Andres Almiray <aalmiray@users.sourceforge.net>
65   */
66  public class TestUserSubmitted extends TestCase {
67     public static void main( String[] args ) {
68        junit.textui.TestRunner.run( TestUserSubmitted.class );
69     }
70  
71     private JsonConfig jsonConfig;
72  
73     public TestUserSubmitted( String name ) {
74        super( name );
75     }
76  
77     public void testBug_1635890() throws NoSuchMethodException, IllegalAccessException,
78           InvocationTargetException {
79        // submited by arco.vandenheuvel[at]points[dot].com
80  
81        String TEST_JSON_STRING = "{\"rateType\":\"HOTRATE\",\"rateBreakdown\":{\"rate\":[{\"amount\":\"109.74\",\"date\":{\"month\":\"01\",\"day\":\"15\",\"year\":\"2007\"}},{\"amount\":\"109.74\",\"date\":{\"month\":\"1\",\"day\":\"16\",\"year\":\"2007\"}}]}}";
82  
83        DynaBean jsonBean = (DynaBean) JSONObject.toBean( JSONObject.fromObject( TEST_JSON_STRING ) );
84        assertNotNull( jsonBean );
85        assertEquals( "wrong rate Type", "HOTRATE", jsonBean.get( "rateType" ) );
86        assertNotNull( "null rate breakdown", jsonBean.get( "rateBreakdown" ) );
87        DynaBean jsonRateBreakdownBean = (DynaBean) jsonBean.get( "rateBreakdown" );
88        assertNotNull( "null rate breakdown ", jsonRateBreakdownBean );
89        Object jsonRateBean = jsonRateBreakdownBean.get( "rate" );
90        assertNotNull( "null rate ", jsonRateBean );
91        assertTrue( "list", jsonRateBean instanceof ArrayList );
92        assertNotNull( "null rate ", jsonRateBreakdownBean.get( "rate", 0 ) );
93     }
94  
95     public void testBug_1650535_builders() {
96        // submitted by Paul Field <paulfield[at]users[dot]sourceforge[dot]net>
97  
98        String json = "{\"obj\":\"{}\",\"array\":\"[]\"}";
99        JSONObject object = JSONObject.fromObject( json );
100       assertNotNull( object );
101       assertTrue( object.has( "obj" ) );
102       assertTrue( object.has( "array" ) );
103       Object obj = object.get( "obj" );
104       assertTrue( obj instanceof String );
105       Object array = object.get( "array" );
106       assertTrue( array instanceof String );
107 
108       json = "{'obj':'{}','array':'[]'}";
109       object = JSONObject.fromObject( json );
110       assertNotNull( object );
111       assertTrue( object.has( "obj" ) );
112       assertTrue( object.has( "array" ) );
113       obj = object.get( "obj" );
114       assertTrue( obj instanceof String );
115       array = object.get( "array" );
116       assertTrue( array instanceof String );
117 
118       json = "[\"{}\",\"[]\"]";
119       JSONArray jarray = JSONArray.fromObject( json );
120       assertNotNull( jarray );
121       obj = jarray.get( 0 );
122       assertTrue( obj instanceof String );
123       array = jarray.get( 1 );
124       assertTrue( array instanceof String );
125 
126       json = "['{}','[]']";
127       jarray = JSONArray.fromObject( json );
128       assertNotNull( jarray );
129       obj = jarray.get( 0 );
130       assertTrue( obj instanceof String );
131       array = jarray.get( 1 );
132       assertTrue( array instanceof String );
133 
134       // submitted by Elizabeth Keogh <ekeogh[at]thoughtworks[dot]com>
135 
136       Map map = new HashMap();
137       map.put( "address", "1 The flats [Upper floor]" );
138       map.put( "phoneNumber", "[+44] 582 401923" );
139       map.put( "info1", "[Likes coffee]" );
140       map.put( "info2", "[Likes coffee] [Likes tea]" );
141       map.put( "info3", "[Likes coffee [but not with sugar]]" );
142       object = JSONObject.fromObject( map );
143       assertNotNull( object );
144       assertTrue( object.has( "address" ) );
145       assertTrue( object.has( "phoneNumber" ) );
146       assertTrue( object.has( "info1" ) );
147       assertTrue( object.has( "info2" ) );
148       assertTrue( object.has( "info3" ) );
149       assertTrue( object.get( "address" ) instanceof String );
150       assertTrue( object.get( "phoneNumber" ) instanceof String );
151       assertTrue( object.get( "info1" ) instanceof String );
152       assertTrue( object.get( "info2" ) instanceof String );
153       assertTrue( object.get( "info3" ) instanceof String );
154    }
155 
156    public void testBug_1650535_setters() {
157       JSONObject object = new JSONObject();
158       object.element( "obj", "{}" );
159       object.element( "notobj", "{string}" );
160       object.element( "array", "[]" );
161       object.element( "notarray", "[string]" );
162       assertTrue( object.get( "obj" ) instanceof JSONObject );
163       assertTrue( object.get( "array" ) instanceof JSONArray );
164       assertTrue( object.get( "notobj" ) instanceof String );
165       assertTrue( object.get( "notarray" ) instanceof String );
166       object.element( "str", "json,json" );
167       assertTrue( object.get( "str" ) instanceof String );
168    }
169 
170    public void testBug_1753528_ArrayStringLiteralToString() {
171       // submited bysckimos[at]gmail[dot]com
172       BeanA bean = new BeanA();
173       bean.setString( "[1234]" );
174       JSONObject jsonObject = JSONObject.fromObject( bean );
175       assertEquals( "[1234]", jsonObject.get( "string" ) );
176       bean.setString( "{'key':'1234'}" );
177       jsonObject = JSONObject.fromObject( bean );
178       assertEquals( "{'key':'1234'}", jsonObject.get( "string" ) );
179    }
180 
181    public void testBug_1763699_toBean() {
182       JSONObject json = JSONObject.fromObject( "{'bbeans':[{'str':'test'}]}" );
183       BeanA1763699 bean = (BeanA1763699) JSONObject.toBean( json, BeanA1763699.class );
184       assertNotNull( bean );
185       BeanB1763699[] bbeans = bean.getBbeans();
186       assertNotNull( bbeans );
187       assertEquals( 1, bbeans.length );
188       assertEquals( "test", bbeans[0].getStr() );
189    }
190 
191    public void testBug_1764768_toBean() {
192       JSONObject json = JSONObject.fromObject( "{'beanA':''}" );
193       Map classMap = new HashMap();
194       classMap.put( "beanA", BeanA.class );
195       BeanC bean = (BeanC) JSONObject.toBean( json, BeanC.class, classMap );
196       assertNotNull( bean );
197       assertNotNull( bean.getBeanA() );
198       assertEquals( new BeanA(), bean.getBeanA() );
199    }
200 
201    public void testBug_1769559_array_conversion() {
202       JSONObject jsonObject = new JSONObject().element( "beans", new JSONArray().element( "{}" )
203             .element( "{'bool':false,'integer':216,'string':'JsOn'}" ) );
204       ArrayBean bean = (ArrayBean) JSONObject.toBean( jsonObject, ArrayBean.class );
205       assertNotNull( bean ); // no error should happen here
206       JSONArray jsonArray = jsonObject.getJSONArray( "beans" );
207       BeanA[] beans = (BeanA[]) JSONArray.toArray( jsonArray, BeanA.class );
208       assertNotNull( beans );
209       assertEquals( 2, beans.length );
210       assertEquals( new BeanA(), beans[0] );
211       assertEquals( new BeanA( false, 216, "JsOn" ), beans[1] );
212    }
213 
214    public void testBug_1769578_array_conversion() {
215       JSONObject jsonObject = JSONObject
216             .fromObject( "{'media':[{'title':'Giggles'},{'title':'Dreamland?'}]}" );
217       Map classMap = new HashMap();
218       classMap.put( "media", MediaBean.class );
219       MediaListBean bean = (MediaListBean) JSONObject.toBean( jsonObject, MediaListBean.class,
220             classMap );
221       assertNotNull( bean );
222       assertNotNull( bean.getMedia() );
223       assertTrue( bean.getMedia().getClass().isArray() );
224       Object[] media = (Object[]) bean.getMedia();
225       assertEquals( 2, media.length );
226       Object mediaItem1 = media[0];
227       assertTrue( mediaItem1 instanceof MediaBean );
228       assertEquals( "Giggles", ((MediaBean) mediaItem1).getTitle() );
229    }
230 
231    public void testBug_1812682() {
232       int[] numbers = new int[] { 1, 2, 3, 4, 5 };
233       JSONObject json = new JSONObject().element( "bytes", numbers ).element( "shorts", numbers )
234             .element( "ints", numbers ).element( "longs", numbers ).element( "floats", numbers )
235             .element( "doubles", numbers );
236       JsonConfig jsonConfig = new JsonConfig();
237       jsonConfig.setRootClass( NumberArrayBean.class );
238       NumberArrayBean bean = (NumberArrayBean) JSONObject.toBean( json, jsonConfig );
239       assertNotNull( bean );
240    }
241 
242    public void testBug_1813301() {
243       List list = new ArrayList();
244       list.add( "1" );
245       list.add( "2" );
246       list.add( "3" );
247       JSONObject jsonObject = new JSONObject().element( "name", "JSON" ).element( "list", list );
248       JsonConfig jsonConfig = new JsonConfig();
249       jsonConfig.setRootClass( MappedBean.class );
250       MappedBean bean = (MappedBean) JSONObject.toBean( jsonObject, jsonConfig );
251       assertNotNull( bean );
252       assertEquals( "JSON", bean.getName() );
253       Assertions.assertEquals( list, bean.getList() );
254    }
255 
256    public void testBug_1875600_1() {
257       JSONArray jArray = JSONArray.fromObject( "[]" );
258       int[] iArray = (int[]) JSONArray.toArray( jArray, int.class );
259       JSONArray actual = JSONArray.fromObject( iArray );
260       Assertions.assertEquals( new JSONArray(), actual );
261    }
262 
263    public void testBug_1875600_2() {
264       JSONArray jArray = JSONArray.fromObject( "[ [] ]" );
265       int[][] iArray = (int[][]) JSONArray.toArray( jArray, int.class );
266       JSONArray actual = JSONArray.fromObject( iArray );
267       Assertions.assertEquals( new JSONArray().element( new JSONArray() ), actual );
268    }
269 
270    public void testConstructor_Object__nullArray() {
271       // submitted by Matt Small
272       String[] strarr = null;
273       JSONObject jsonObject = JSONObject.fromObject( strarr, jsonConfig );
274       assertTrue( jsonObject.isNullObject() );
275    }
276 
277    public void testConstructor_Object_EnclosedArray() {
278       // submitted by Matt Small
279       PrimitiveBean bean = new PrimitiveBean();
280       bean.setOarray( new String[] { "hi", "bye" } );
281       JSONObject jsonObject = JSONObject.fromObject( bean, jsonConfig );
282       assertFalse( jsonObject.isNullObject() );
283       assertFalse( jsonObject.getJSONArray( "oarray" ).isEmpty() );
284    }
285 
286    public void testConstructor_Object_EnclosedNullArray() {
287       // submitted by Matt Small
288       PrimitiveBean bean = new PrimitiveBean();
289       bean.setOarray( null );
290       JSONObject jsonObject = JSONObject.fromObject( bean, jsonConfig );
291       assertFalse( jsonObject.isNullObject() );
292       assertTrue( jsonObject.getJSONArray( "oarray" ).isEmpty() );
293    }
294 
295    public void testConstructorAndToBean_Object_RoundTrip_EnclosedNullArray() {
296 
297       PrimitiveBean bean = new PrimitiveBean();
298       bean.setOarray( null );
299       JSONObject jsonObject = JSONObject.fromObject( bean, jsonConfig );
300       PrimitiveBean bean2 = (PrimitiveBean) JSONObject.toBean( jsonObject, PrimitiveBean.class );
301       assertNotNull( bean2 );
302       // bean.oarray == null
303       // jsonObject.oarray == [] therefore
304       // bean2.oarray != null
305       assertEquals( 0, bean2.getOarray().length );
306    }
307 
308    public void testDynaBeanAttributeMap() throws NoSuchMethodException, IllegalAccessException,
309          InvocationTargetException {
310       // submited by arco.vandenheuvel[at]points[dot].com
311       JSONObject jsonObject = JSONObject.fromObject( new JSONTestBean() );
312       String jsonString = jsonObject.toString();
313       DynaBean jsonBean = (DynaBean) JSONObject.toBean( JSONObject.fromObject( jsonString ) );
314       assertNotNull( jsonBean );
315       assertEquals( "wrong inventoryID", "", jsonBean.get( "inventoryID" ) );
316    }
317 
318    public void testFR_1768960_array_conversion() { // 2 items
319       JSONObject jsonObject = JSONObject
320             .fromObject( "{'media2':[{'title':'Giggles'},{'title':'Dreamland?'}]}" );
321       Map classMap = new HashMap();
322       classMap.put( "media2", MediaBean.class );
323       MediaListBean bean = (MediaListBean) JSONObject.toBean( jsonObject, MediaListBean.class,
324             classMap );
325       assertNotNull( bean );
326       assertNotNull( bean.getMedia2() );
327       List media2 = bean.getMedia2();
328       assertEquals( 2, media2.size() );
329       Object mediaItem1 = media2.get( 0 );
330       assertTrue( mediaItem1 instanceof MediaBean );
331       assertEquals( "Giggles", ((MediaBean) mediaItem1).getTitle() ); // 1
332       // item
333       jsonObject = JSONObject.fromObject( "{'media2':[{'title':'Giggles'}]}" );
334       bean = (MediaListBean) JSONObject.toBean( jsonObject, MediaListBean.class, classMap );
335       assertNotNull( bean );
336       assertNotNull( bean.getMedia2() );
337       media2 = bean.getMedia2();
338       assertEquals( 1, media2.size() );
339       mediaItem1 = media2.get( 0 );
340       assertTrue( mediaItem1 instanceof MediaBean );
341       assertEquals( "Giggles", ((MediaBean) mediaItem1).getTitle() );
342    }
343 
344    public void testFR_1808430_newBeanInstance() {
345       JsonConfig jsonConfig = new JsonConfig();
346       jsonConfig.setNewBeanInstanceStrategy( new UnstandardBeanInstanceStrategy() );
347       JSONObject jsonObject = new JSONObject();
348       jsonObject.element( "id", 1 );
349       jsonConfig.setRootClass( UnstandardBean.class );
350       UnstandardBean bean = (UnstandardBean) JSONObject.toBean( jsonObject, jsonConfig );
351       assertNotNull( bean );
352       assertEquals( UnstandardBean.class, bean.getClass() );
353       assertEquals( 1, bean.getId() );
354    }
355 
356    public void testFR_1832047_packageProtectedBean() {
357       JSONObject jsonObject = new JSONObject().element( "value", "42" );
358       JsonConfig jsonConfig = new JsonConfig();
359       jsonConfig.setRootClass( PackageProtectedBean.class );
360       PackageProtectedBean bean = (PackageProtectedBean) JSONObject.toBean( jsonObject, jsonConfig );
361       assertNotNull( bean );
362       assertEquals( 42, bean.getValue() );
363    }
364 
365    public void testFR_1832047_privateProtectedBean() {
366       JSONObject jsonObject = new JSONObject().element( "value", "42" );
367       JsonConfig jsonConfig = new JsonConfig();
368       jsonConfig.setRootClass( PrivateConstructorBean.class );
369       PrivateConstructorBean bean = (PrivateConstructorBean) JSONObject.toBean( jsonObject,
370             jsonConfig );
371       assertNotNull( bean );
372       assertEquals( 42, bean.getValue() );
373    }
374 
375    public void testFR_1858073_preserveInsertionOrder() {
376       JSONObject jsonObject = new JSONObject().element( "one", "one" ).element( "two", "two" )
377             .element( "three", "three" );
378       JSONArray actual = jsonObject.names();
379       JSONArray expected = new JSONArray().element( "one" ).element( "two" ).element( "three" );
380       Assertions.assertEquals( expected, actual );
381    }
382 
383    public void testFromObjectCurliesOnString() {
384       String json = "{'prop':'{value}'}";
385       JSONObject jsonObject = JSONObject.fromObject( json );
386       assertNotNull( jsonObject );
387       assertEquals( 1, jsonObject.size() );
388       assertEquals( "{value}", jsonObject.get( "prop" ) );
389 
390       json = "{'prop':'{{value}}'}";
391       jsonObject = JSONObject.fromObject( json );
392       assertNotNull( jsonObject );
393       assertEquals( 1, jsonObject.size() );
394       assertEquals( "{{value}}", jsonObject.get( "prop" ) );
395 
396       json = "{'prop':'{{{value}}}'}";
397       jsonObject = JSONObject.fromObject( json );
398       assertNotNull( jsonObject );
399       assertEquals( 1, jsonObject.size() );
400       assertEquals( "{{{value}}}", jsonObject.get( "prop" ) );
401    }
402 
403    public void testHandleJettisonEmptyElement() {
404       JSONObject jsonObject = JSONObject.fromObject( "{'beanA':'','beanB':''}" );
405       jsonConfig.setHandleJettisonEmptyElement( true );
406       jsonConfig.setRootClass( BeanC.class );
407       BeanC bean = (BeanC) JSONObject.toBean( jsonObject, jsonConfig );
408       assertNotNull( bean );
409       assertNull( bean.getBeanA() );
410       assertNull( bean.getBeanB() );
411    }
412 
413    public void testHandleJettisonSingleElementArray() {
414       JSONObject jsonObject = JSONObject.fromObject( "{'media2':{'title':'Giggles'}}" );
415       Map classMap = new HashMap();
416       classMap.put( "media2", MediaBean.class );
417       jsonConfig.setHandleJettisonSingleElementArray( true );
418       jsonConfig.setRootClass( MediaListBean.class );
419       jsonConfig.setClassMap( classMap );
420       MediaListBean bean = (MediaListBean) JSONObject.toBean( jsonObject, jsonConfig );
421       assertNotNull( bean );
422       assertNotNull( bean.getMedia2() );
423       List media2 = bean.getMedia2();
424       assertEquals( 1, media2.size() );
425       Object mediaItem1 = media2.get( 0 );
426       assertTrue( mediaItem1 instanceof MediaBean );
427       assertEquals( "Giggles", ((MediaBean) mediaItem1).getTitle() );
428    }
429 
430    public void testHandleJettisonSingleElementArray2() {
431       JSONObject jsonObject = JSONObject.fromObject( "{'mediaList':{'media':{'title':'Giggles'}}}" );
432       Map classMap = new HashMap();
433       classMap.put( "media", Media.class );
434       classMap.put( "mediaList", MediaList.class );
435       jsonConfig.setHandleJettisonSingleElementArray( true );
436       jsonConfig.setRootClass( Player.class );
437       jsonConfig.setClassMap( classMap );
438       Player bean = (Player) JSONObject.toBean( jsonObject, jsonConfig );
439       assertNotNull( bean );
440       assertNotNull( bean.getMediaList() );
441       MediaList mediaList = bean.getMediaList();
442       assertNotNull( mediaList.getMedia() );
443       ArrayList medias = mediaList.getMedia();
444       assertEquals( "Giggles", ((Media) medias.get( 0 )).getTitle() );
445    }
446 
447    public void testHandleJettisonSingleElementArray3() {
448       JSONObject jsonObject = JSONObject
449             .fromObject( "{'player':{'mediaList':{'media':{'title':'Giggles'}}}}" );
450       Map classMap = new HashMap();
451       classMap.put( "media", Media.class );
452       classMap.put( "mediaList", MediaList.class );
453       classMap.put( "player", Player.class );
454       jsonConfig.setHandleJettisonSingleElementArray( true );
455       jsonConfig.setRootClass( PlayerList.class );
456       jsonConfig.setClassMap( classMap );
457       PlayerList bean = (PlayerList) JSONObject.toBean( jsonObject, jsonConfig );
458       assertNotNull( bean );
459       assertNotNull( bean.getPlayer() );
460       ArrayList players = bean.getPlayer();
461       assertNotNull( players );
462       assertNotNull( players.get( 0 ) );
463       Player player = (Player) players.get( 0 );
464       assertNotNull( player.getMediaList() );
465       MediaList mediaList = player.getMediaList();
466       assertNotNull( mediaList.getMedia() );
467       ArrayList medias = mediaList.getMedia();
468       assertEquals( "Giggles", ((Media) medias.get( 0 )).getTitle() );
469    }
470 
471    public void testJsonWithNamespaceToDynaBean() throws Exception {
472       // submited by Girish Ipadi
473 
474       jsonConfig.setJavaIdentifierTransformer( JavaIdentifierTransformer.NOOP );
475       String str = "{'version':'1.0'," + "'sid':'AmazonDocStyle',    'svcVersion':'0.1',"
476             + "'oid':'ItemLookup',    'params':[{            'ns:ItemLookup': {"
477             + "'ns:SubscriptionId':'0525E2PQ81DD7ZTWTK82'," + "'ns:Validate':'False',"
478             + "'ns:Request':{" + "'ns:ItemId':'SDGKJSHDGAJSGL'," + "'ns:IdType':'ASIN',"
479             + "'ns:ResponseGroup':'Large'" + "}," + "'ns:Request':{" + "'ns:ItemId':'XXXXXXXXXX',"
480             + "'ns:IdType':'ASIN'," + "'ns:ResponseGroup':'Large'" + "}" + "}" + "}]" + "} ";
481       JSONObject json = JSONObject.fromObject( str, jsonConfig );
482       Object bean = JSONObject.toBean( (JSONObject) json );
483       assertNotNull( bean );
484       List params = (List) PropertyUtils.getProperty( bean, "params" );
485       DynaBean param0 = (DynaBean) params.get( 0 );
486       DynaBean itemLookup = (DynaBean) param0.get( "ns:ItemLookup" );
487       assertNotNull( itemLookup );
488       assertEquals( "0525E2PQ81DD7ZTWTK82", itemLookup.get( "ns:SubscriptionId" ) );
489    }
490 
491    public void testToBeanSimpleToComplexValueTransformation() {
492       // Submitted by Oliver Zyngier
493       JSONObject jsonObject = JSONObject.fromObject( "{'id':null}" );
494       IdBean idBean = (IdBean) JSONObject.toBean( jsonObject, IdBean.class );
495       assertNotNull( idBean );
496       assertEquals( null, idBean.getId() );
497 
498       jsonObject = JSONObject.fromObject( "{'id':1}" );
499       idBean = (IdBean) JSONObject.toBean( jsonObject, IdBean.class );
500       assertNotNull( idBean );
501       assertNotNull( idBean.getId() );
502       assertEquals( 0L, idBean.getId().getValue() );
503 
504       JSONUtils.getMorpherRegistry().registerMorpher( new IdBean.IdMorpher(), true );
505       jsonObject = JSONObject.fromObject( "{'id':1}" );
506       idBean = (IdBean) JSONObject.toBean( jsonObject, IdBean.class );
507       assertNotNull( idBean );
508       assertEquals( new IdBean.Id( 1L ), idBean.getId() );
509    }
510 
511    public void testToBeanWithMultipleMorphersForTargetType() {
512       Calendar c = Calendar.getInstance();
513       c.set( Calendar.YEAR, 2007 );
514       c.set( Calendar.MONTH, 5 );
515       c.set( Calendar.DATE, 17 );
516       c.set( Calendar.HOUR_OF_DAY, 12 );
517       c.set( Calendar.MINUTE, 13 );
518       c.set( Calendar.SECOND, 14 );
519       c.set( Calendar.MILLISECOND, 150 );
520       Date date = c.getTime();
521 
522       DateBean bean = new DateBean();
523       bean.setDate( date );
524       JSONObject jsonObject = JSONObject.fromObject( bean );
525 
526       JSONUtils.getMorpherRegistry().registerMorpher( new MapToDateMorpher() );
527 
528       JsonConfig jsonConfig = new JsonConfig();
529       jsonConfig.setRootClass( DateBean.class );
530       DateBean actual = (DateBean) JSONObject.toBean( jsonObject, jsonConfig );
531       Calendar d = Calendar.getInstance();
532       d.setTime( actual.getDate() );
533       assertEquals( c.get( Calendar.YEAR ), d.get( Calendar.YEAR ) );
534       assertEquals( c.get( Calendar.MONTH ), d.get( Calendar.MONTH ) );
535       assertEquals( c.get( Calendar.DATE ), d.get( Calendar.DATE ) );
536       assertEquals( c.get( Calendar.HOUR_OF_DAY ), d.get( Calendar.HOUR_OF_DAY ) );
537       assertEquals( c.get( Calendar.MINUTE ), d.get( Calendar.MINUTE ) );
538       assertEquals( c.get( Calendar.SECOND ), d.get( Calendar.SECOND ) );
539       assertEquals( c.get( Calendar.MILLISECOND ), d.get( Calendar.MILLISECOND ) );
540    }
541 
542    public void testToBeanWithInterfaceField() {
543       JSONObject jsonObject = JSONObject.fromObject( "{runnable:{}}" );
544       JsonConfig jsonConfig = new JsonConfig();
545       jsonConfig.setRootClass( InterfaceBean.class );
546       Map classMap = new HashMap();
547       classMap.put( "runnable", RunnableImpl.class );
548       jsonConfig.setClassMap( classMap );
549       InterfaceBean bean = (InterfaceBean) JSONObject.toBean( jsonObject, jsonConfig );
550       assertNotNull( bean );
551       assertNotNull( bean.getRunnable() );
552       assertTrue( bean.getRunnable() instanceof RunnableImpl );
553    }
554    
555    public void testCycleDetection_withExclusions() {
556       ParentBean parent = new ParentBean();
557       parent.setChild( new ChildBean() );
558 
559       // will fail if throws an exception
560       jsonConfig.setExcludes( new String[] { "parent" } );
561       JSONObject.fromObject( parent, jsonConfig );
562    }
563    
564    public void testJSONArrayIterator() {
565       JSONArray jsonArray = new JSONArray();
566       jsonArray.add( "1" );
567       jsonArray.add( "2" );
568       jsonArray.add( "3" );
569 
570       List list = new LinkedList();
571       list.add( "4" );
572       list.add( "5" );
573       list.add( "6" );
574       jsonArray.add( list );
575 
576       List newList = new LinkedList();
577       newList.add( "7" );
578       newList.add( "8" );
579       newList.add( "9" );
580 
581       Assertions.assertEquals( JSONArray.fromObject( "['1','2','3',['4','5','6']]" ), jsonArray );
582 
583       ListIterator listIterator = jsonArray.listIterator();
584       listIterator.add( newList );
585 
586       Assertions.assertEquals( JSONArray.fromObject( "[['7','8','9'],'1','2','3',['4','5','6']]" ), jsonArray );
587    }
588    
589    public void testJSONArray_badFormattedString() {
590       String badJson = "[{\"a\":\"b\"},";
591       try {
592          JSONArray.fromObject(badJson);
593          fail("Expecting a syntax error from JSONTokener.");
594       }catch( JSONException jsone ) {
595          assertTrue( jsone.getMessage().startsWith( "Found starting '[' but missing ']' at the end." ));
596       }
597    }
598    
599    public void testJSONObject_badFormattedString() {
600       String badJson = "{\"a\":\"b\"},";
601       try {
602          JSONObject.fromObject(badJson);
603          fail("Expecting a syntax error from JSONTokener.");
604       }catch( JSONException jsone ) {
605          assertTrue( jsone.getMessage().startsWith( "Found starting '{' but missing '}' at the end." ));
606       }
607    }
608 
609    public void testQuotedFunctions() {
610       JSONObject json = JSONObject.fromObject( "{'func':\"function(){blah;}\"}" );
611       assertTrue( json.get( "func" ) instanceof String );
612       assertEquals( "\"function(){blah;}\"", json.get( "func" ));
613    }
614  
615    public void testJsonWithNullKeys() {
616       Map map = new HashMap();
617       map.put("key", "value");
618       map.put(null, "value2");
619 
620       Object[] obj = {map};
621 
622       try {
623          JSONSerializer.toJSON( obj );
624          fail( "Should have thrown a ClassCastException" );
625       } catch( JSONException expected ) {
626          // ok
627       }
628   }
629 
630   public void testJsonWithNullKeys2() {
631       Map map = new HashMap();
632       map.put("key", "value");
633       map.put(null, "value2");
634 
635       try {
636          System.err.println(JSONSerializer.toJSON( map ));
637          fail( "Should have thrown a ClassCastException" );
638       } catch( JSONException expected ) {
639          // ok
640       }
641   }
642 
643    public void testJSONArray_JavascriptCompliant() {
644       JsonConfig jsonConfig = new JsonConfig();
645       jsonConfig.setJavascriptCompliant( true );
646       String json = "[null, undefined]";
647       JSONArray array = JSONArray.fromObject( json, jsonConfig );
648       assertNotNull(array);
649       Assertions.assertEquals( JSONNull.getInstance(), array.get(1) );
650    }
651   
652    public void testJSONArray_JavascriptComplian2t() {
653       JsonConfig jsonConfig = new JsonConfig();
654       jsonConfig.setJavascriptCompliant( true );
655       JSONArray array = new JSONArray();
656       array.element("null", jsonConfig);
657       array.element("undefined", jsonConfig);
658       assertNotNull(array);
659       Assertions.assertEquals( JSONNull.getInstance(), array.get(0) );
660       Assertions.assertEquals( JSONNull.getInstance(), array.get(1) );
661    }
662    
663    public void testJSONObject_JavascriptCompliant() {
664       JsonConfig jsonConfig = new JsonConfig();
665       jsonConfig.setJavascriptCompliant( true );
666       String json = "{key1: null, key2: undefined}";
667       JSONObject object = JSONObject.fromObject( json, jsonConfig );
668       assertNotNull(object);
669       Assertions.assertEquals( JSONNull.getInstance(), object.get("key2") );
670    }
671    
672    public void testJSONObject_JavascriptCompliant2() {
673       JsonConfig jsonConfig = new JsonConfig();
674       jsonConfig.setJavascriptCompliant( true );
675       JSONObject object = new JSONObject();
676       object.element( "key1", "null", jsonConfig );
677       object.element( "key2", "undefined", jsonConfig );
678       assertNotNull(object);
679       Assertions.assertEquals( JSONNull.getInstance(), object.get("key2") );
680    }
681    
682    public void testJSONObject_fromObject_FieldBean() {
683       JsonConfig jsonConfig = new JsonConfig();
684       jsonConfig.setIgnorePublicFields( false );
685       FieldBean bean = new FieldBean();
686       bean.setValue( 42 );
687       bean.string = "stringy";
688       JSONObject jsonObject = JSONObject.fromObject( bean );
689       assertNotNull( jsonObject );
690       assertEquals( 42, jsonObject.getInt( "value" ));
691       assertFalse( jsonObject.has( "string" ));
692       jsonObject = JSONObject.fromObject( bean, jsonConfig );
693       assertNotNull( jsonObject );
694       assertEquals( 42, jsonObject.getInt( "value" ));
695       assertEquals( "stringy", jsonObject.getString( "string" ));
696    }
697    
698    public void testJSONObject_toBean_FieldBean() {
699       JSONObject jsonObject = new JSONObject();
700       jsonObject.element( "value", 42 );
701       jsonObject.element( "string", "stringy" );
702       FieldBean bean1 = (FieldBean) JSONObject.toBean( jsonObject, FieldBean.class );
703       assertNotNull( bean1 );
704       assertEquals( 42, bean1.getValue());
705       assertNull( bean1.string );
706 
707       JsonConfig jsonConfig = new JsonConfig();
708       jsonConfig.setIgnorePublicFields( false );
709       jsonConfig.setRootClass( FieldBean.class );
710       FieldBean bean2 = (FieldBean) JSONObject.toBean( jsonObject, jsonConfig );
711       assertNotNull( bean2 );
712       assertEquals( 42, bean1.getValue());
713       assertEquals( "stringy", bean2.string );
714    }
715    
716    /*
717    public void testBug_2692698() {
718       String input = "[\"{'selectedOperatorIndex':2,'leftSideValue':'report.field9','rightSideValue':'2009-3-1'}\",\"all\"]";
719       JSON json = JSONArray.fromObject( input );
720       String output = json.toString();
721       System.err.println(input);
722       System.err.println(output);
723    }
724    */
725    
726    public void testWithoutAnyTroubleTheyMayBeAlreadyDoneByOtherTest() {
727       JsonConfig tConfig = new JsonConfig();
728       tConfig.enableEventTriggering();
729       tConfig.addJsonEventListener(new JsonErrorDetector());
730 
731       // String
732       JSONObject jsonObject = JSONObject.fromObject( "{\"string\":\"aString\"}", tConfig );
733       assertTrue( "L'objet doit contenir une clef \"string\"", jsonObject.containsKey( "string" ) );
734       assertNotNull( "Le membre \"string\" doit être une String", jsonObject.optString( "string" ) );
735       assertEquals( "Le membre \"string\" doit être égal a \"aString\"", "aString", jsonObject.get( "string" ) );
736 
737       // int
738       jsonObject = JSONObject.fromObject( "{\"integer\":10}", tConfig );
739       assertTrue( "L'objet doit contenir une clef \"integer\"", jsonObject.containsKey( "integer" ) );
740       assertEquals( "Le membre \"integer\" doit être égal a 10", 10, jsonObject.optInt( "integer" ) );
741 
742       // boolean
743       jsonObject = JSONObject.fromObject( "{\"double\":2.02}", tConfig );
744       assertTrue( "L'objet doit contenir une clef \"double\"", jsonObject.containsKey( "double" ) );
745       assertEquals( "Le membre \"double\" doit être égal a 2.02", 2.02d, jsonObject.optDouble( "double" ), 0.0001 );
746 
747       // double
748       jsonObject = JSONObject.fromObject( "{\"boolean\":true}", tConfig );
749       assertTrue( "L'objet doit contenir une clef \"boolean\"", jsonObject.containsKey( "boolean" ) );
750       assertEquals( "Le membre \"boolean\" doit être égal a true", true, jsonObject.optBoolean( "boolean" ) );
751 
752       // String array
753       jsonObject = JSONObject.fromObject( "{\"strArray\":[\"a\",\"b\",\"c\"]}", tConfig );
754       assertTrue( "L'objet doit contenir une clef \"strArray\"", jsonObject.containsKey( "strArray" ) );
755       assertNotNull( "Le membre \"strArray\" doit être une Array", jsonObject.optJSONArray( "strArray" ) );
756       assertEquals( "L'element 0 de \"strArray\" doit être égal a \"a\"", "a", jsonObject.optJSONArray( "strArray" )
757             .optString( 0 ) );
758       assertEquals( "L'element 1 de \"strArray\" doit être égal a \"b\"", "b", jsonObject.optJSONArray( "strArray" )
759             .optString( 1 ) );
760       assertEquals( "L'element 2 de \"strArray\" doit être égal a \"c\"", "c", jsonObject.optJSONArray( "strArray" )
761             .optString( 2 ) );
762 
763       // int array
764       jsonObject = JSONObject.fromObject( "{\"intArray\":[1,2,3]}", tConfig );
765       assertTrue( "L'objet doit contenir une clef \"intArray\"", jsonObject.containsKey( "intArray" ) );
766       assertNotNull( "Le membre \"intArray\" doit être une Array", jsonObject.optJSONArray( "intArray" ) );
767       assertEquals( "L'element 0 de \"intArray\" doit être égal a 1", 1, jsonObject.optJSONArray( "intArray" ).optInt(
768             0 ) );
769       assertEquals( "L'element 1 de \"intArray\" doit être égal a 2", 2, jsonObject.optJSONArray( "intArray" ).optInt(
770             1 ) );
771       assertEquals( "L'element 2 de \"intArray\" doit être égal a 3", 3, jsonObject.optJSONArray( "intArray" ).optInt(
772             2 ) );
773 
774       // boolean array
775       jsonObject = JSONObject.fromObject( "{\"booleanArray\":[true, false, true]}", tConfig );
776       assertTrue( "L'objet doit contenir une clef \"booleanArray\"", jsonObject.containsKey( "booleanArray" ) );
777       assertNotNull( "Le membre \"strArray\" doit être une booleanArray", jsonObject.optJSONArray( "booleanArray" ) );
778       assertEquals( "L'element 0 de \"booleanArray\" doit être égal a true", true, jsonObject.optJSONArray(
779             "booleanArray" ).optBoolean( 0 ) );
780       assertEquals( "L'element 1 de \"booleanArray\" doit être égal a false", false, jsonObject.optJSONArray(
781             "booleanArray" ).optBoolean( 1 ) );
782       assertEquals( "L'element 2 de \"booleanArray\" doit être égal a true", true, jsonObject.optJSONArray(
783             "booleanArray" ).optBoolean( 2 ) );
784 
785       // double array
786       jsonObject = JSONObject.fromObject( "{\"doubleArray\":[\"a\",\"b\",\"c\"]}", tConfig );
787       assertTrue( "L'objet doit contenir une clef \"doubleArray\"", jsonObject.containsKey( "doubleArray" ) );
788       assertNotNull( "Le membre \"doubleArray\" doit être une Array", jsonObject.optJSONArray( "doubleArray" ) );
789       assertEquals( "L'element 0 de \"doubleArray\" doit être égal a \"a\"", "a", jsonObject.optJSONArray(
790             "doubleArray" ).optString( 0 ) );
791 
792       jsonObject = JSONObject.fromObject( "{\"weirdString\":\"[Hello]\"}", tConfig );
793       assertTrue( "L'objet doit contenir une clef \"weirdString\"", jsonObject.containsKey( "weirdString" ) );
794       assertNotNull( "Le membre \"weirdString\" doit être une String", jsonObject.optString( "weirdString" ) );
795       assertEquals( "Le membre \"weirdString\" doit être égal a \"[Hello]\"", "[Hello]", jsonObject.get( "weirdString" ) );
796       jsonObject = JSONObject.fromObject( "{\"weirdString\":\"{912}\"}" );
797       assertTrue( "L'objet doit contenir une clef \"weirdString\"", jsonObject.containsKey( "weirdString" ) );
798       assertNotNull( "Le membre \"weirdString\" doit être une String", jsonObject.optString( "weirdString" ) );
799       assertEquals( "Le membre \"weirdString\" doit être égal a \"{912}\"", "{912}", jsonObject.get( "weirdString" ) );
800    }
801    /*
802    public void testDifferenceBetweenStringSerialisationWithJSONObjectAndJSONArray() {
803       JsonConfig tConfig = new JsonConfig();
804       tConfig.enableEventTriggering();
805       tConfig.addJsonEventListener( new JsonErrorDetector() );
806 
807       // This was Ko
808       JSONObject tJsonSource = new JSONObject();
809       tJsonSource.element( "weirdString", "[{}][:,;:.[][[]", jsonConfig );
810       assertEquals( "[{}][:,;:.[][[]", tJsonSource.get( "weirdString" ) );
811 
812       String tExpected = "{\"weirdString\":\"[{}][:,;:.[][[]\"}";
813       assertEquals( tExpected, tJsonSource.toString() );
814 
815       // This was Ko too
816       tJsonSource = new JSONObject();
817       JSONArray tArraySource = new JSONArray();
818       tArraySource.element( "{912}", jsonConfig );
819       tArraySource.element( "[Hello]", jsonConfig );
820       tArraySource.element( "[]{}[,;.:[[]", jsonConfig );
821       assertEquals( "[]{}[,;.:[[]", tArraySource.get( 2 ) );
822       tJsonSource.put( "weirdStringArray", tArraySource );
823 
824       tExpected = "{\"weirdStringArray\":[\"{912}\",\"[Hello]\",\"[]{}[,;.:[[]\"]}";
825       assertEquals( tExpected, tJsonSource.toString() );
826    }
827    /*
828    public void testDifferenceBetweenStringParsingIntoJSONObjectAndJSONArray() {
829       JsonConfig tConfig = new JsonConfig();
830       tConfig.enableEventTriggering();
831       tConfig.addJsonEventListener( new JsonErrorDetector() );
832 
833       // This part was Ok
834       JSONObject jsonObject = JSONObject.fromObject( "{\"weirdString\":\"[{}][:,;:.[][[]\"}", tConfig );
835       assertTrue( jsonObject.containsKey( "weirdString" ) );
836       assertNotNull( jsonObject.optString( "weirdString" ) );
837       assertEquals( "[{}][:,;:.[][[]", jsonObject.get( "weirdString" ) );
838 
839       // This part very similar to the previous part was Ko
840       jsonObject = JSONObject.fromObject( "{\"weirdStringArray\":[\"{912}\",\"[Hello]\",\"[]{}[,;.:[[]\"]}", tConfig );
841       assertTrue( jsonObject.containsKey( "weirdStringArray" ) );
842       assertNotNull( jsonObject.optJSONArray( "weirdStringArray" ) );
843       assertEquals( "{912}", jsonObject.getJSONArray( "weirdStringArray" ).optString( 0 ) );
844       assertEquals( "[Hello]", jsonObject.getJSONArray( "weirdStringArray" ).optString( 1 ) );
845       assertEquals( "[]{}[,;.:[[]", jsonObject.getJSONArray( "weirdStringArray" ).optString( 2 ) );
846    }
847    */
848    public static class RunnableImpl implements Runnable {
849       public void run() {
850 
851       }
852    }
853    
854    public static class JsonErrorDetector implements JsonEventListener{
855       public void onArrayEnd() {
856       }
857 
858       public void onArrayStart() {
859       }
860 
861       public void onElementAdded( int index, Object element ) {
862       }
863 
864       public void onError( JSONException jsone ) {
865          fail("An error occurs during JsonProcessing "+ jsone.getMessage());
866       }
867 
868       public void onObjectEnd() { 
869       }
870 
871       public void onObjectStart() {
872       }
873 
874       public void onPropertySet( String key, Object value, boolean accumulated ) { 
875       }
876 
877       public void onWarning( String warning ) {
878       }
879    }
880 
881    protected void setUp() throws Exception {
882       super.setUp();
883       jsonConfig = new JsonConfig();
884    }
885 }