JSONObjectTest.java revision 661054f5a2f7f8f5f3ceffb97e803211b546e7fc
1/* 2 * Copyright (C) 2010 The Android Open Source Project 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 17package org.json; 18 19import java.math.BigDecimal; 20import java.math.BigInteger; 21import java.util.Arrays; 22import java.util.Collections; 23import java.util.HashMap; 24import java.util.HashSet; 25import java.util.Iterator; 26import java.util.Map; 27import java.util.NoSuchElementException; 28import java.util.Set; 29import junit.framework.TestCase; 30 31/** 32 * This black box test was written without inspecting the non-free org.json sourcecode. 33 */ 34public class JSONObjectTest extends TestCase { 35 36 public void testEmptyObject() throws JSONException { 37 JSONObject object = new JSONObject(); 38 assertEquals(0, object.length()); 39 40 // bogus (but documented) behaviour: returns null rather than the empty object! 41 assertNull(object.names()); 42 43 // returns null rather than an empty array! 44 assertNull(object.toJSONArray(new JSONArray())); 45 assertEquals("{}", object.toString()); 46 assertEquals("{}", object.toString(5)); 47 try { 48 object.get("foo"); 49 fail(); 50 } catch (JSONException e) { 51 } 52 try { 53 object.getBoolean("foo"); 54 fail(); 55 } catch (JSONException e) { 56 } 57 try { 58 object.getDouble("foo"); 59 fail(); 60 } catch (JSONException e) { 61 } 62 try { 63 object.getInt("foo"); 64 fail(); 65 } catch (JSONException e) { 66 } 67 try { 68 object.getJSONArray("foo"); 69 fail(); 70 } catch (JSONException e) { 71 } 72 try { 73 object.getJSONObject("foo"); 74 fail(); 75 } catch (JSONException e) { 76 } 77 try { 78 object.getLong("foo"); 79 fail(); 80 } catch (JSONException e) { 81 } 82 try { 83 object.getString("foo"); 84 fail(); 85 } catch (JSONException e) { 86 } 87 assertFalse(object.has("foo")); 88 assertTrue(object.isNull("foo")); // isNull also means "is not present" 89 assertNull(object.opt("foo")); 90 assertEquals(false, object.optBoolean("foo")); 91 assertEquals(true, object.optBoolean("foo", true)); 92 assertEquals(Double.NaN, object.optDouble("foo")); 93 assertEquals(5.0, object.optDouble("foo", 5.0)); 94 assertEquals(0, object.optInt("foo")); 95 assertEquals(5, object.optInt("foo", 5)); 96 assertEquals(null, object.optJSONArray("foo")); 97 assertEquals(null, object.optJSONObject("foo")); 98 assertEquals(0, object.optLong("foo")); 99 assertEquals(Long.MAX_VALUE-1, object.optLong("foo", Long.MAX_VALUE-1)); 100 assertEquals("", object.optString("foo")); // empty string is default! 101 assertEquals("bar", object.optString("foo", "bar")); 102 assertNull(object.remove("foo")); 103 } 104 105 public void testEqualsAndHashCode() throws JSONException { 106 JSONObject a = new JSONObject(); 107 JSONObject b = new JSONObject(); 108 109 // JSON object doesn't override either equals or hashCode (!) 110 assertFalse(a.equals(b)); 111 assertEquals(a.hashCode(), System.identityHashCode(a)); 112 } 113 114 public void testGet() throws JSONException { 115 JSONObject object = new JSONObject(); 116 Object value = new Object(); 117 object.put("foo", value); 118 object.put("bar", new Object()); 119 object.put("baz", new Object()); 120 assertSame(value, object.get("foo")); 121 try { 122 object.get("FOO"); 123 fail(); 124 } catch (JSONException e) { 125 } 126 try { 127 object.put(null, value); 128 fail(); 129 } catch (JSONException e) { 130 } 131 try { 132 object.get(null); 133 fail(); 134 } catch (JSONException e) { 135 } 136 } 137 138 public void testPut() throws JSONException { 139 JSONObject object = new JSONObject(); 140 assertSame(object, object.put("foo", true)); 141 object.put("foo", false); 142 assertEquals(false, object.get("foo")); 143 144 object.put("foo", 5.0d); 145 assertEquals(5.0d, object.get("foo")); 146 object.put("foo", 0); 147 assertEquals(0, object.get("foo")); 148 object.put("bar", Long.MAX_VALUE - 1); 149 assertEquals(Long.MAX_VALUE - 1, object.get("bar")); 150 object.put("baz", "x"); 151 assertEquals("x", object.get("baz")); 152 object.put("bar", JSONObject.NULL); 153 assertSame(JSONObject.NULL, object.get("bar")); 154 } 155 156 public void testPutNullRemoves() throws JSONException { 157 JSONObject object = new JSONObject(); 158 object.put("foo", "bar"); 159 object.put("foo", null); 160 assertEquals(0, object.length()); 161 assertFalse(object.has("foo")); 162 try { 163 object.get("foo"); 164 fail(); 165 } catch (JSONException e) { 166 } 167 } 168 169 public void testPutOpt() throws JSONException { 170 JSONObject object = new JSONObject(); 171 object.put("foo", "bar"); 172 object.putOpt("foo", null); 173 assertEquals("bar", object.get("foo")); 174 object.putOpt(null, null); 175 assertEquals(1, object.length()); 176 object.putOpt(null, "bar"); 177 assertEquals(1, object.length()); 178 } 179 180 public void testPutOptUnsupportedNumbers() throws JSONException { 181 JSONObject object = new JSONObject(); 182 try { 183 object.putOpt("foo", Double.NaN); 184 fail(); 185 } catch (JSONException e) { 186 } 187 try { 188 object.putOpt("foo", Double.NEGATIVE_INFINITY); 189 fail(); 190 } catch (JSONException e) { 191 } 192 try { 193 object.putOpt("foo", Double.POSITIVE_INFINITY); 194 fail(); 195 } catch (JSONException e) { 196 } 197 } 198 199 public void testRemove() throws JSONException { 200 JSONObject object = new JSONObject(); 201 object.put("foo", "bar"); 202 assertEquals(null, object.remove(null)); 203 assertEquals(null, object.remove("")); 204 assertEquals(null, object.remove("bar")); 205 assertEquals("bar", object.remove("foo")); 206 assertEquals(null, object.remove("foo")); 207 } 208 209 public void testBooleans() throws JSONException { 210 JSONObject object = new JSONObject(); 211 object.put("foo", true); 212 object.put("bar", false); 213 object.put("baz", "true"); 214 object.put("quux", "false"); 215 assertEquals(4, object.length()); 216 assertEquals(true, object.getBoolean("foo")); 217 assertEquals(false, object.getBoolean("bar")); 218 assertEquals(true, object.getBoolean("baz")); 219 assertEquals(false, object.getBoolean("quux")); 220 assertFalse(object.isNull("foo")); 221 assertFalse(object.isNull("quux")); 222 assertTrue(object.has("foo")); 223 assertTrue(object.has("quux")); 224 assertFalse(object.has("missing")); 225 assertEquals(true, object.optBoolean("foo")); 226 assertEquals(false, object.optBoolean("bar")); 227 assertEquals(true, object.optBoolean("baz")); 228 assertEquals(false, object.optBoolean("quux")); 229 assertEquals(false, object.optBoolean("missing")); 230 assertEquals(true, object.optBoolean("foo", true)); 231 assertEquals(false, object.optBoolean("bar", true)); 232 assertEquals(true, object.optBoolean("baz", true)); 233 assertEquals(false, object.optBoolean("quux", true)); 234 assertEquals(true, object.optBoolean("missing", true)); 235 236 object.put("foo", "truE"); 237 object.put("bar", "FALSE"); 238 assertEquals(true, object.getBoolean("foo")); 239 assertEquals(false, object.getBoolean("bar")); 240 assertEquals(true, object.optBoolean("foo")); 241 assertEquals(false, object.optBoolean("bar")); 242 assertEquals(true, object.optBoolean("foo", false)); 243 assertEquals(false, object.optBoolean("bar", false)); 244 } 245 246 // http://code.google.com/p/android/issues/detail?id=16411 247 public void testCoerceStringToBoolean() throws JSONException { 248 JSONObject object = new JSONObject(); 249 object.put("foo", "maybe"); 250 try { 251 object.getBoolean("foo"); 252 fail(); 253 } catch (JSONException expected) { 254 } 255 assertEquals(false, object.optBoolean("foo")); 256 assertEquals(true, object.optBoolean("foo", true)); 257 } 258 259 public void testNumbers() throws JSONException { 260 JSONObject object = new JSONObject(); 261 object.put("foo", Double.MIN_VALUE); 262 object.put("bar", 9223372036854775806L); 263 object.put("baz", Double.MAX_VALUE); 264 object.put("quux", -0d); 265 assertEquals(4, object.length()); 266 267 String toString = object.toString(); 268 assertTrue(toString, toString.contains("\"foo\":4.9E-324")); 269 assertTrue(toString, toString.contains("\"bar\":9223372036854775806")); 270 assertTrue(toString, toString.contains("\"baz\":1.7976931348623157E308")); 271 272 // toString() and getString() return different values for -0d! 273 assertTrue(toString, toString.contains("\"quux\":-0}") // no trailing decimal point 274 || toString.contains("\"quux\":-0,")); 275 276 assertEquals(Double.MIN_VALUE, object.get("foo")); 277 assertEquals(9223372036854775806L, object.get("bar")); 278 assertEquals(Double.MAX_VALUE, object.get("baz")); 279 assertEquals(-0d, object.get("quux")); 280 assertEquals(Double.MIN_VALUE, object.getDouble("foo")); 281 assertEquals(9.223372036854776E18, object.getDouble("bar")); 282 assertEquals(Double.MAX_VALUE, object.getDouble("baz")); 283 assertEquals(-0d, object.getDouble("quux")); 284 assertEquals(0, object.getLong("foo")); 285 assertEquals(9223372036854775806L, object.getLong("bar")); 286 assertEquals(Long.MAX_VALUE, object.getLong("baz")); 287 assertEquals(0, object.getLong("quux")); 288 assertEquals(0, object.getInt("foo")); 289 assertEquals(-2, object.getInt("bar")); 290 assertEquals(Integer.MAX_VALUE, object.getInt("baz")); 291 assertEquals(0, object.getInt("quux")); 292 assertEquals(Double.MIN_VALUE, object.opt("foo")); 293 assertEquals(9223372036854775806L, object.optLong("bar")); 294 assertEquals(Double.MAX_VALUE, object.optDouble("baz")); 295 assertEquals(0, object.optInt("quux")); 296 assertEquals(Double.MIN_VALUE, object.opt("foo")); 297 assertEquals(9223372036854775806L, object.optLong("bar")); 298 assertEquals(Double.MAX_VALUE, object.optDouble("baz")); 299 assertEquals(0, object.optInt("quux")); 300 assertEquals(Double.MIN_VALUE, object.optDouble("foo", 5.0d)); 301 assertEquals(9223372036854775806L, object.optLong("bar", 1L)); 302 assertEquals(Long.MAX_VALUE, object.optLong("baz", 1L)); 303 assertEquals(0, object.optInt("quux", -1)); 304 assertEquals("4.9E-324", object.getString("foo")); 305 assertEquals("9223372036854775806", object.getString("bar")); 306 assertEquals("1.7976931348623157E308", object.getString("baz")); 307 assertEquals("-0.0", object.getString("quux")); 308 } 309 310 public void testFloats() throws JSONException { 311 JSONObject object = new JSONObject(); 312 try { 313 object.put("foo", (Float) Float.NaN); 314 fail(); 315 } catch (JSONException e) { 316 } 317 try { 318 object.put("foo", (Float) Float.NEGATIVE_INFINITY); 319 fail(); 320 } catch (JSONException e) { 321 } 322 try { 323 object.put("foo", (Float) Float.POSITIVE_INFINITY); 324 fail(); 325 } catch (JSONException e) { 326 } 327 } 328 329 public void testOtherNumbers() throws JSONException { 330 Number nan = new Number() { 331 public int intValue() { 332 throw new UnsupportedOperationException(); 333 } 334 public long longValue() { 335 throw new UnsupportedOperationException(); 336 } 337 public float floatValue() { 338 throw new UnsupportedOperationException(); 339 } 340 public double doubleValue() { 341 return Double.NaN; 342 } 343 @Override public String toString() { 344 return "x"; 345 } 346 }; 347 348 JSONObject object = new JSONObject(); 349 try { 350 object.put("foo", nan); 351 fail("Object.put() accepted a NaN (via a custom Number class)"); 352 } catch (JSONException e) { 353 } 354 } 355 356 public void testForeignObjects() throws JSONException { 357 Object foreign = new Object() { 358 @Override public String toString() { 359 return "x"; 360 } 361 }; 362 363 // foreign object types are accepted and treated as Strings! 364 JSONObject object = new JSONObject(); 365 object.put("foo", foreign); 366 assertEquals("{\"foo\":\"x\"}", object.toString()); 367 } 368 369 public void testNullKeys() { 370 try { 371 new JSONObject().put(null, false); 372 fail(); 373 } catch (JSONException e) { 374 } 375 try { 376 new JSONObject().put(null, 0.0d); 377 fail(); 378 } catch (JSONException e) { 379 } 380 try { 381 new JSONObject().put(null, 5); 382 fail(); 383 } catch (JSONException e) { 384 } 385 try { 386 new JSONObject().put(null, 5L); 387 fail(); 388 } catch (JSONException e) { 389 } 390 try { 391 new JSONObject().put(null, "foo"); 392 fail(); 393 } catch (JSONException e) { 394 } 395 } 396 397 public void testStrings() throws JSONException { 398 JSONObject object = new JSONObject(); 399 object.put("foo", "true"); 400 object.put("bar", "5.5"); 401 object.put("baz", "9223372036854775806"); 402 object.put("quux", "null"); 403 object.put("height", "5\"8' tall"); 404 405 assertTrue(object.toString().contains("\"foo\":\"true\"")); 406 assertTrue(object.toString().contains("\"bar\":\"5.5\"")); 407 assertTrue(object.toString().contains("\"baz\":\"9223372036854775806\"")); 408 assertTrue(object.toString().contains("\"quux\":\"null\"")); 409 assertTrue(object.toString().contains("\"height\":\"5\\\"8' tall\"")); 410 411 assertEquals("true", object.get("foo")); 412 assertEquals("null", object.getString("quux")); 413 assertEquals("5\"8' tall", object.getString("height")); 414 assertEquals("true", object.opt("foo")); 415 assertEquals("5.5", object.optString("bar")); 416 assertEquals("true", object.optString("foo", "x")); 417 assertFalse(object.isNull("foo")); 418 419 assertEquals(true, object.getBoolean("foo")); 420 assertEquals(true, object.optBoolean("foo")); 421 assertEquals(true, object.optBoolean("foo", false)); 422 assertEquals(0, object.optInt("foo")); 423 assertEquals(-2, object.optInt("foo", -2)); 424 425 assertEquals(5.5d, object.getDouble("bar")); 426 assertEquals(5L, object.getLong("bar")); 427 assertEquals(5, object.getInt("bar")); 428 assertEquals(5, object.optInt("bar", 3)); 429 430 // The last digit of the string is a 6 but getLong returns a 7. It's probably parsing as a 431 // double and then converting that to a long. This is consistent with JavaScript. 432 assertEquals(9223372036854775807L, object.getLong("baz")); 433 assertEquals(9.223372036854776E18, object.getDouble("baz")); 434 assertEquals(Integer.MAX_VALUE, object.getInt("baz")); 435 436 assertFalse(object.isNull("quux")); 437 try { 438 object.getDouble("quux"); 439 fail(); 440 } catch (JSONException e) { 441 } 442 assertEquals(Double.NaN, object.optDouble("quux")); 443 assertEquals(-1.0d, object.optDouble("quux", -1.0d)); 444 445 object.put("foo", "TRUE"); 446 assertEquals(true, object.getBoolean("foo")); 447 } 448 449 public void testJSONObjects() throws JSONException { 450 JSONObject object = new JSONObject(); 451 452 JSONArray a = new JSONArray(); 453 JSONObject b = new JSONObject(); 454 object.put("foo", a); 455 object.put("bar", b); 456 457 assertSame(a, object.getJSONArray("foo")); 458 assertSame(b, object.getJSONObject("bar")); 459 try { 460 object.getJSONObject("foo"); 461 fail(); 462 } catch (JSONException e) { 463 } 464 try { 465 object.getJSONArray("bar"); 466 fail(); 467 } catch (JSONException e) { 468 } 469 assertEquals(a, object.optJSONArray("foo")); 470 assertEquals(b, object.optJSONObject("bar")); 471 assertEquals(null, object.optJSONArray("bar")); 472 assertEquals(null, object.optJSONObject("foo")); 473 } 474 475 public void testNullCoercionToString() throws JSONException { 476 JSONObject object = new JSONObject(); 477 object.put("foo", JSONObject.NULL); 478 assertEquals("null", object.getString("foo")); 479 } 480 481 public void testArrayCoercion() throws JSONException { 482 JSONObject object = new JSONObject(); 483 object.put("foo", "[true]"); 484 try { 485 object.getJSONArray("foo"); 486 fail(); 487 } catch (JSONException e) { 488 } 489 } 490 491 public void testObjectCoercion() throws JSONException { 492 JSONObject object = new JSONObject(); 493 object.put("foo", "{}"); 494 try { 495 object.getJSONObject("foo"); 496 fail(); 497 } catch (JSONException e) { 498 } 499 } 500 501 public void testAccumulateValueChecking() throws JSONException { 502 JSONObject object = new JSONObject(); 503 try { 504 object.accumulate("foo", Double.NaN); 505 fail(); 506 } catch (JSONException e) { 507 } 508 object.accumulate("foo", 1); 509 try { 510 object.accumulate("foo", Double.NaN); 511 fail(); 512 } catch (JSONException e) { 513 } 514 object.accumulate("foo", 2); 515 try { 516 object.accumulate("foo", Double.NaN); 517 fail(); 518 } catch (JSONException e) { 519 } 520 } 521 522 public void testToJSONArray() throws JSONException { 523 JSONObject object = new JSONObject(); 524 Object value = new Object(); 525 object.put("foo", true); 526 object.put("bar", 5.0d); 527 object.put("baz", -0.0d); 528 object.put("quux", value); 529 530 JSONArray names = new JSONArray(); 531 names.put("baz"); 532 names.put("quux"); 533 names.put("foo"); 534 535 JSONArray array = object.toJSONArray(names); 536 assertEquals(-0.0d, array.get(0)); 537 assertEquals(value, array.get(1)); 538 assertEquals(true, array.get(2)); 539 540 object.put("foo", false); 541 assertEquals(true, array.get(2)); 542 } 543 544 public void testToJSONArrayMissingNames() throws JSONException { 545 JSONObject object = new JSONObject(); 546 object.put("foo", true); 547 object.put("bar", 5.0d); 548 object.put("baz", JSONObject.NULL); 549 550 JSONArray names = new JSONArray(); 551 names.put("bar"); 552 names.put("foo"); 553 names.put("quux"); 554 names.put("baz"); 555 556 JSONArray array = object.toJSONArray(names); 557 assertEquals(4, array.length()); 558 559 assertEquals(5.0d, array.get(0)); 560 assertEquals(true, array.get(1)); 561 try { 562 array.get(2); 563 fail(); 564 } catch (JSONException e) { 565 } 566 assertEquals(JSONObject.NULL, array.get(3)); 567 } 568 569 public void testToJSONArrayNull() throws JSONException { 570 JSONObject object = new JSONObject(); 571 assertEquals(null, object.toJSONArray(null)); 572 object.put("foo", 5); 573 try { 574 object.toJSONArray(null); 575 } catch (JSONException e) { 576 } 577 } 578 579 public void testToJSONArrayEndsUpEmpty() throws JSONException { 580 JSONObject object = new JSONObject(); 581 object.put("foo", 5); 582 JSONArray array = new JSONArray(); 583 array.put("bar"); 584 assertEquals(1, object.toJSONArray(array).length()); 585 } 586 587 public void testToJSONArrayNonString() throws JSONException { 588 JSONObject object = new JSONObject(); 589 object.put("foo", 5); 590 object.put("null", 10); 591 object.put("false", 15); 592 593 JSONArray names = new JSONArray(); 594 names.put(JSONObject.NULL); 595 names.put(false); 596 names.put("foo"); 597 598 // array elements are converted to strings to do name lookups on the map! 599 JSONArray array = object.toJSONArray(names); 600 assertEquals(3, array.length()); 601 assertEquals(10, array.get(0)); 602 assertEquals(15, array.get(1)); 603 assertEquals(5, array.get(2)); 604 } 605 606 public void testPutUnsupportedNumbers() throws JSONException { 607 JSONObject object = new JSONObject(); 608 try { 609 object.put("foo", Double.NaN); 610 fail(); 611 } catch (JSONException e) { 612 } 613 try { 614 object.put("foo", Double.NEGATIVE_INFINITY); 615 fail(); 616 } catch (JSONException e) { 617 } 618 try { 619 object.put("foo", Double.POSITIVE_INFINITY); 620 fail(); 621 } catch (JSONException e) { 622 } 623 } 624 625 public void testPutUnsupportedNumbersAsObjects() throws JSONException { 626 JSONObject object = new JSONObject(); 627 try { 628 object.put("foo", (Double) Double.NaN); 629 fail(); 630 } catch (JSONException e) { 631 } 632 try { 633 object.put("foo", (Double) Double.NEGATIVE_INFINITY); 634 fail(); 635 } catch (JSONException e) { 636 } 637 try { 638 object.put("foo", (Double) Double.POSITIVE_INFINITY); 639 fail(); 640 } catch (JSONException e) { 641 } 642 } 643 644 /** 645 * Although JSONObject is usually defensive about which numbers it accepts, 646 * it doesn't check inputs in its constructor. 647 */ 648 public void testCreateWithUnsupportedNumbers() throws JSONException { 649 Map<String, Object> contents = new HashMap<String, Object>(); 650 contents.put("foo", Double.NaN); 651 contents.put("bar", Double.NEGATIVE_INFINITY); 652 contents.put("baz", Double.POSITIVE_INFINITY); 653 654 JSONObject object = new JSONObject(contents); 655 assertEquals(Double.NaN, object.get("foo")); 656 assertEquals(Double.NEGATIVE_INFINITY, object.get("bar")); 657 assertEquals(Double.POSITIVE_INFINITY, object.get("baz")); 658 } 659 660 public void testToStringWithUnsupportedNumbers() { 661 // when the object contains an unsupported number, toString returns null! 662 JSONObject object = new JSONObject(Collections.singletonMap("foo", Double.NaN)); 663 assertEquals(null, object.toString()); 664 } 665 666 public void testMapConstructorCopiesContents() throws JSONException { 667 Map<String, Object> contents = new HashMap<String, Object>(); 668 contents.put("foo", 5); 669 JSONObject object = new JSONObject(contents); 670 contents.put("foo", 10); 671 assertEquals(5, object.get("foo")); 672 } 673 674 public void testMapConstructorWithBogusEntries() { 675 Map<Object, Object> contents = new HashMap<Object, Object>(); 676 contents.put(5, 5); 677 678 try { 679 new JSONObject(contents); 680 fail("JSONObject constructor doesn't validate its input!"); 681 } catch (Exception e) { 682 } 683 } 684 685 public void testTokenerConstructor() throws JSONException { 686 JSONObject object = new JSONObject(new JSONTokener("{\"foo\": false}")); 687 assertEquals(1, object.length()); 688 assertEquals(false, object.get("foo")); 689 } 690 691 public void testTokenerConstructorWrongType() throws JSONException { 692 try { 693 new JSONObject(new JSONTokener("[\"foo\", false]")); 694 fail(); 695 } catch (JSONException e) { 696 } 697 } 698 699 public void testTokenerConstructorNull() throws JSONException { 700 try { 701 new JSONObject((JSONTokener) null); 702 fail(); 703 } catch (NullPointerException e) { 704 } 705 } 706 707 public void testTokenerConstructorParseFail() { 708 try { 709 new JSONObject(new JSONTokener("{")); 710 fail(); 711 } catch (JSONException e) { 712 } 713 } 714 715 public void testStringConstructor() throws JSONException { 716 JSONObject object = new JSONObject("{\"foo\": false}"); 717 assertEquals(1, object.length()); 718 assertEquals(false, object.get("foo")); 719 } 720 721 public void testStringConstructorWrongType() throws JSONException { 722 try { 723 new JSONObject("[\"foo\", false]"); 724 fail(); 725 } catch (JSONException e) { 726 } 727 } 728 729 public void testStringConstructorNull() throws JSONException { 730 try { 731 new JSONObject((String) null); 732 fail(); 733 } catch (NullPointerException e) { 734 } 735 } 736 737 public void testStringonstructorParseFail() { 738 try { 739 new JSONObject("{"); 740 fail(); 741 } catch (JSONException e) { 742 } 743 } 744 745 public void testCopyConstructor() throws JSONException { 746 JSONObject source = new JSONObject(); 747 source.put("a", JSONObject.NULL); 748 source.put("b", false); 749 source.put("c", 5); 750 751 JSONObject copy = new JSONObject(source, new String[] { "a", "c" }); 752 assertEquals(2, copy.length()); 753 assertEquals(JSONObject.NULL, copy.get("a")); 754 assertEquals(5, copy.get("c")); 755 assertEquals(null, copy.opt("b")); 756 } 757 758 public void testCopyConstructorMissingName() throws JSONException { 759 JSONObject source = new JSONObject(); 760 source.put("a", JSONObject.NULL); 761 source.put("b", false); 762 source.put("c", 5); 763 764 JSONObject copy = new JSONObject(source, new String[]{ "a", "c", "d" }); 765 assertEquals(2, copy.length()); 766 assertEquals(JSONObject.NULL, copy.get("a")); 767 assertEquals(5, copy.get("c")); 768 assertEquals(0, copy.optInt("b")); 769 } 770 771 public void testAccumulateMutatesInPlace() throws JSONException { 772 JSONObject object = new JSONObject(); 773 object.put("foo", 5); 774 object.accumulate("foo", 6); 775 JSONArray array = object.getJSONArray("foo"); 776 assertEquals("[5,6]", array.toString()); 777 object.accumulate("foo", 7); 778 assertEquals("[5,6,7]", array.toString()); 779 } 780 781 public void testAccumulateExistingArray() throws JSONException { 782 JSONArray array = new JSONArray(); 783 JSONObject object = new JSONObject(); 784 object.put("foo", array); 785 object.accumulate("foo", 5); 786 assertEquals("[5]", array.toString()); 787 } 788 789 public void testAccumulatePutArray() throws JSONException { 790 JSONObject object = new JSONObject(); 791 object.accumulate("foo", 5); 792 assertEquals("{\"foo\":5}", object.toString()); 793 object.accumulate("foo", new JSONArray()); 794 assertEquals("{\"foo\":[5,[]]}", object.toString()); 795 } 796 797 public void testAccumulateNull() { 798 JSONObject object = new JSONObject(); 799 try { 800 object.accumulate(null, 5); 801 fail(); 802 } catch (JSONException e) { 803 } 804 } 805 806 public void testEmptyStringKey() throws JSONException { 807 JSONObject object = new JSONObject(); 808 object.put("", 5); 809 assertEquals(5, object.get("")); 810 assertEquals("{\"\":5}", object.toString()); 811 } 812 813 public void testNullValue() throws JSONException { 814 JSONObject object = new JSONObject(); 815 object.put("foo", JSONObject.NULL); 816 object.put("bar", null); 817 818 // there are two ways to represent null; each behaves differently! 819 assertTrue(object.has("foo")); 820 assertFalse(object.has("bar")); 821 assertTrue(object.isNull("foo")); 822 assertTrue(object.isNull("bar")); 823 } 824 825 public void testHas() throws JSONException { 826 JSONObject object = new JSONObject(); 827 object.put("foo", 5); 828 assertTrue(object.has("foo")); 829 assertFalse(object.has("bar")); 830 assertFalse(object.has(null)); 831 } 832 833 public void testOptNull() throws JSONException { 834 JSONObject object = new JSONObject(); 835 object.put("foo", "bar"); 836 assertEquals(null, object.opt(null)); 837 assertEquals(false, object.optBoolean(null)); 838 assertEquals(Double.NaN, object.optDouble(null)); 839 assertEquals(0, object.optInt(null)); 840 assertEquals(0L, object.optLong(null)); 841 assertEquals(null, object.optJSONArray(null)); 842 assertEquals(null, object.optJSONObject(null)); 843 assertEquals("", object.optString(null)); 844 assertEquals(true, object.optBoolean(null, true)); 845 assertEquals(0.0d, object.optDouble(null, 0.0d)); 846 assertEquals(1, object.optInt(null, 1)); 847 assertEquals(1L, object.optLong(null, 1L)); 848 assertEquals("baz", object.optString(null, "baz")); 849 } 850 851 public void testToStringWithIndentFactor() throws JSONException { 852 JSONObject object = new JSONObject(); 853 object.put("foo", new JSONArray(Arrays.asList(5, 6))); 854 object.put("bar", new JSONObject()); 855 String foobar = "{\n" + 856 " \"foo\": [\n" + 857 " 5,\n" + 858 " 6\n" + 859 " ],\n" + 860 " \"bar\": {}\n" + 861 "}"; 862 String barfoo = "{\n" + 863 " \"bar\": {},\n" + 864 " \"foo\": [\n" + 865 " 5,\n" + 866 " 6\n" + 867 " ]\n" + 868 "}"; 869 String string = object.toString(5); 870 assertTrue(string, foobar.equals(string) || barfoo.equals(string)); 871 } 872 873 public void testNames() throws JSONException { 874 JSONObject object = new JSONObject(); 875 object.put("foo", 5); 876 object.put("bar", 6); 877 object.put("baz", 7); 878 JSONArray array = object.names(); 879 assertTrue(array.toString().contains("foo")); 880 assertTrue(array.toString().contains("bar")); 881 assertTrue(array.toString().contains("baz")); 882 } 883 884 public void testKeysEmptyObject() { 885 JSONObject object = new JSONObject(); 886 assertFalse(object.keys().hasNext()); 887 try { 888 object.keys().next(); 889 fail(); 890 } catch (NoSuchElementException e) { 891 } 892 } 893 894 public void testKeys() throws JSONException { 895 JSONObject object = new JSONObject(); 896 object.put("foo", 5); 897 object.put("bar", 6); 898 object.put("foo", 7); 899 900 @SuppressWarnings("unchecked") 901 Iterator<String> keys = (Iterator<String>) object.keys(); 902 Set<String> result = new HashSet<String>(); 903 assertTrue(keys.hasNext()); 904 result.add(keys.next()); 905 assertTrue(keys.hasNext()); 906 result.add(keys.next()); 907 assertFalse(keys.hasNext()); 908 assertEquals(new HashSet<String>(Arrays.asList("foo", "bar")), result); 909 910 try { 911 keys.next(); 912 fail(); 913 } catch (NoSuchElementException e) { 914 } 915 } 916 917 public void testMutatingKeysMutatesObject() throws JSONException { 918 JSONObject object = new JSONObject(); 919 object.put("foo", 5); 920 Iterator keys = object.keys(); 921 keys.next(); 922 keys.remove(); 923 assertEquals(0, object.length()); 924 } 925 926 public void testQuote() { 927 // covered by JSONStringerTest.testEscaping 928 } 929 930 public void testQuoteNull() throws JSONException { 931 assertEquals("\"\"", JSONObject.quote(null)); 932 } 933 934 public void testNumberToString() throws JSONException { 935 assertEquals("5", JSONObject.numberToString(5)); 936 assertEquals("-0", JSONObject.numberToString(-0.0d)); 937 assertEquals("9223372036854775806", JSONObject.numberToString(9223372036854775806L)); 938 assertEquals("4.9E-324", JSONObject.numberToString(Double.MIN_VALUE)); 939 assertEquals("1.7976931348623157E308", JSONObject.numberToString(Double.MAX_VALUE)); 940 try { 941 JSONObject.numberToString(Double.NaN); 942 fail(); 943 } catch (JSONException e) { 944 } 945 try { 946 JSONObject.numberToString(Double.NEGATIVE_INFINITY); 947 fail(); 948 } catch (JSONException e) { 949 } 950 try { 951 JSONObject.numberToString(Double.POSITIVE_INFINITY); 952 fail(); 953 } catch (JSONException e) { 954 } 955 assertEquals("0.001", JSONObject.numberToString(new BigDecimal("0.001"))); 956 assertEquals("9223372036854775806", 957 JSONObject.numberToString(new BigInteger("9223372036854775806"))); 958 try { 959 JSONObject.numberToString(null); 960 fail(); 961 } catch (JSONException e) { 962 } 963 } 964} 965