JSONArrayTest.java revision 4558195b4a7ee014517f1aa3c59bc6c561baa2ef
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 junit.framework.TestCase; 20 21import java.util.Arrays; 22import java.util.List; 23import java.util.Collections; 24 25/** 26 * This black box test was written without inspecting the non-free org.json sourcecode. 27 */ 28public class JSONArrayTest extends TestCase { 29 30 public void testEmptyArray() throws JSONException { 31 JSONArray array = new JSONArray(); 32 assertEquals(0, array.length()); 33 assertEquals("", array.join(" AND ")); 34 try { 35 array.get(0); 36 fail(); 37 } catch (JSONException e) { 38 } 39 try { 40 array.getBoolean(0); 41 fail(); 42 } catch (JSONException e) { 43 } 44 45 assertEquals("[]", array.toString()); 46 assertEquals("[]", array.toString(4)); 47 48 // out of bounds is co-opted with defaulting 49 assertTrue(array.isNull(0)); 50 assertNull(array.opt(0)); 51 assertFalse(array.optBoolean(0)); 52 assertTrue(array.optBoolean(0, true)); 53 54 // bogus (but documented) behaviour: returns null rather than an empty object! 55 assertNull(array.toJSONObject(new JSONArray())); 56 } 57 58 public void testEqualsAndHashCode() throws JSONException { 59 JSONArray a = new JSONArray(); 60 JSONArray b = new JSONArray(); 61 assertTrue(a.equals(b)); 62 assertEquals("equals() not consistent with hashCode()", a.hashCode(), b.hashCode()); 63 64 a.put(true); 65 a.put(false); 66 b.put(true); 67 b.put(false); 68 assertTrue(a.equals(b)); 69 assertEquals(a.hashCode(), b.hashCode()); 70 71 b.put(true); 72 assertFalse(a.equals(b)); 73 assertTrue(a.hashCode() != b.hashCode()); 74 } 75 76 public void testBooleans() throws JSONException { 77 JSONArray array = new JSONArray(); 78 array.put(true); 79 array.put(false); 80 array.put(2, false); 81 array.put(3, false); 82 array.put(2, true); 83 assertEquals("[true,false,true,false]", array.toString()); 84 assertEquals(4, array.length()); 85 assertEquals(Boolean.TRUE, array.get(0)); 86 assertEquals(Boolean.FALSE, array.get(1)); 87 assertEquals(Boolean.TRUE, array.get(2)); 88 assertEquals(Boolean.FALSE, array.get(3)); 89 assertFalse(array.isNull(0)); 90 assertFalse(array.isNull(1)); 91 assertFalse(array.isNull(2)); 92 assertFalse(array.isNull(3)); 93 assertEquals(true, array.optBoolean(0)); 94 assertEquals(false, array.optBoolean(1, true)); 95 assertEquals(true, array.optBoolean(2, false)); 96 assertEquals(false, array.optBoolean(3)); 97 assertEquals("true", array.getString(0)); 98 assertEquals("false", array.getString(1)); 99 assertEquals("true", array.optString(2)); 100 assertEquals("false", array.optString(3, "x")); 101 assertEquals("[\n true,\n false,\n true,\n false\n]", array.toString(5)); 102 103 JSONArray other = new JSONArray(); 104 other.put(true); 105 other.put(false); 106 other.put(true); 107 other.put(false); 108 assertTrue(array.equals(other)); 109 other.put(true); 110 assertFalse(array.equals(other)); 111 112 other = new JSONArray(); 113 other.put("true"); 114 other.put("false"); 115 other.put("truE"); 116 other.put("FALSE"); 117 assertFalse(array.equals(other)); 118 assertFalse(other.equals(array)); 119 assertEquals(true, other.getBoolean(0)); 120 assertEquals(false, other.optBoolean(1, true)); 121 assertEquals(true, other.optBoolean(2)); 122 assertEquals(false, other.getBoolean(3)); 123 } 124 125 public void testNulls() throws JSONException { 126 JSONArray array = new JSONArray(); 127 array.put(3, null); 128 array.put(0, JSONObject.NULL); 129 assertEquals(4, array.length()); 130 assertEquals("[null,null,null,null]", array.toString()); 131 132 // there's 2 ways to represent null; each behaves differently! 133 assertEquals(JSONObject.NULL, array.get(0)); 134 try { 135 array.get(1); 136 fail(); 137 } catch (JSONException e) { 138 } 139 try { 140 array.get(2); 141 fail(); 142 } catch (JSONException e) { 143 } 144 try { 145 array.get(3); 146 fail(); 147 } catch (JSONException e) { 148 } 149 assertEquals(JSONObject.NULL, array.opt(0)); 150 assertEquals(null, array.opt(1)); 151 assertEquals(null, array.opt(2)); 152 assertEquals(null, array.opt(3)); 153 assertTrue(array.isNull(0)); 154 assertTrue(array.isNull(1)); 155 assertTrue(array.isNull(2)); 156 assertTrue(array.isNull(3)); 157 assertEquals("null", array.optString(0)); 158 assertEquals("", array.optString(1)); 159 assertEquals("", array.optString(2)); 160 assertEquals("", array.optString(3)); 161 } 162 163 public void testNumbers() throws JSONException { 164 JSONArray array = new JSONArray(); 165 array.put(Double.MIN_VALUE); 166 array.put(9223372036854775806L); 167 array.put(Double.MAX_VALUE); 168 array.put(-0d); 169 assertEquals(4, array.length()); 170 171 // toString() and getString(int) return different values for -0d 172 assertEquals("[4.9E-324,9223372036854775806,1.7976931348623157E308,-0]", array.toString()); 173 174 assertEquals(Double.MIN_VALUE, array.get(0)); 175 assertEquals(9223372036854775806L, array.get(1)); 176 assertEquals(Double.MAX_VALUE, array.get(2)); 177 assertEquals(-0d, array.get(3)); 178 assertEquals(Double.MIN_VALUE, array.getDouble(0)); 179 assertEquals(9.223372036854776E18, array.getDouble(1)); 180 assertEquals(Double.MAX_VALUE, array.getDouble(2)); 181 assertEquals(-0d, array.getDouble(3)); 182 assertEquals(0, array.getLong(0)); 183 assertEquals(9223372036854775806L, array.getLong(1)); 184 assertEquals(Long.MAX_VALUE, array.getLong(2)); 185 assertEquals(0, array.getLong(3)); 186 assertEquals(0, array.getInt(0)); 187 assertEquals(-2, array.getInt(1)); 188 assertEquals(Integer.MAX_VALUE, array.getInt(2)); 189 assertEquals(0, array.getInt(3)); 190 assertEquals(Double.MIN_VALUE, array.opt(0)); 191 assertEquals(Double.MIN_VALUE, array.optDouble(0)); 192 assertEquals(0, array.optLong(0, 1L)); 193 assertEquals(0, array.optInt(0, 1)); 194 assertEquals("4.9E-324", array.getString(0)); 195 assertEquals("9223372036854775806", array.getString(1)); 196 assertEquals("1.7976931348623157E308", array.getString(2)); 197 assertEquals("-0.0", array.getString(3)); 198 199 JSONArray other = new JSONArray(); 200 other.put(Double.MIN_VALUE); 201 other.put(9223372036854775806L); 202 other.put(Double.MAX_VALUE); 203 other.put(-0d); 204 assertTrue(array.equals(other)); 205 other.put(0, 0L); 206 assertFalse(array.equals(other)); 207 } 208 209 public void testStrings() throws JSONException { 210 JSONArray array = new JSONArray(); 211 array.put("true"); 212 array.put("5.5"); 213 array.put("9223372036854775806"); 214 array.put("null"); 215 array.put("5\"8' tall"); 216 assertEquals(5, array.length()); 217 assertEquals("[\"true\",\"5.5\",\"9223372036854775806\",\"null\",\"5\\\"8' tall\"]", 218 array.toString()); 219 220 // although the documentation doesn't mention it, join() escapes text and wraps 221 // strings in quotes 222 assertEquals("\"true\" \"5.5\" \"9223372036854775806\" \"null\" \"5\\\"8' tall\"", 223 array.join(" ")); 224 225 assertEquals("true", array.get(0)); 226 assertEquals("null", array.getString(3)); 227 assertEquals("5\"8' tall", array.getString(4)); 228 assertEquals("true", array.opt(0)); 229 assertEquals("5.5", array.optString(1)); 230 assertEquals("9223372036854775806", array.optString(2, null)); 231 assertEquals("null", array.optString(3, "-1")); 232 assertFalse(array.isNull(0)); 233 assertFalse(array.isNull(3)); 234 235 assertEquals(true, array.getBoolean(0)); 236 assertEquals(true, array.optBoolean(0)); 237 assertEquals(true, array.optBoolean(0, false)); 238 assertEquals(0, array.optInt(0)); 239 assertEquals(-2, array.optInt(0, -2)); 240 241 assertEquals(5.5d, array.getDouble(1)); 242 assertEquals(5L, array.getLong(1)); 243 assertEquals(5, array.getInt(1)); 244 assertEquals(5, array.optInt(1, 3)); 245 246 // The last digit of the string is a 6 but getLong returns a 7. It's probably parsing as a 247 // double and then converting that to a long. This is consistent with JavaScript. 248 assertEquals(9223372036854775807L, array.getLong(2)); 249 assertEquals(9.223372036854776E18, array.getDouble(2)); 250 assertEquals(Integer.MAX_VALUE, array.getInt(2)); 251 252 assertFalse(array.isNull(3)); 253 try { 254 array.getDouble(3); 255 fail(); 256 } catch (JSONException e) { 257 } 258 assertEquals(Double.NaN, array.optDouble(3)); 259 assertEquals(-1.0d, array.optDouble(3, -1.0d)); 260 } 261 262 public void testJoin() throws JSONException { 263 JSONArray array = new JSONArray(); 264 array.put(null); 265 assertEquals("null", array.join(" & ")); 266 array.put("\""); 267 assertEquals("null & \"\\\"\"", array.join(" & ")); 268 array.put(5); 269 assertEquals("null & \"\\\"\" & 5", array.join(" & ")); 270 array.put(true); 271 assertEquals("null & \"\\\"\" & 5 & true", array.join(" & ")); 272 array.put(new JSONArray(Arrays.asList(true, false))); 273 assertEquals("null & \"\\\"\" & 5 & true & [true,false]", array.join(" & ")); 274 array.put(new JSONObject(Collections.singletonMap("x", 6))); 275 assertEquals("null & \"\\\"\" & 5 & true & [true,false] & {\"x\":6}", array.join(" & ")); 276 } 277 278 public void testJoinWithNull() throws JSONException { 279 JSONArray array = new JSONArray(Arrays.asList(5, 6)); 280 assertEquals("5null6", array.join(null)); 281 } 282 283 public void testJoinWithSpecialCharacters() throws JSONException { 284 JSONArray array = new JSONArray(Arrays.asList(5, 6)); 285 assertEquals("5\"6", array.join("\"")); 286 } 287 288 public void testToJSONObject() throws JSONException { 289 JSONArray keys = new JSONArray(); 290 keys.put("a"); 291 keys.put("b"); 292 293 JSONArray values = new JSONArray(); 294 values.put(5.5d); 295 values.put(false); 296 297 JSONObject object = values.toJSONObject(keys); 298 assertEquals(5.5d, object.get("a")); 299 assertEquals(false, object.get("b")); 300 301 keys.put(0, "a"); 302 values.put(0, 11.0d); 303 assertEquals(5.5d, object.get("a")); 304 } 305 306 public void testToJSONObjectWithNulls() throws JSONException { 307 JSONArray keys = new JSONArray(); 308 keys.put("a"); 309 keys.put("b"); 310 311 JSONArray values = new JSONArray(); 312 values.put(5.5d); 313 values.put(null); 314 315 // null values are stripped! 316 JSONObject object = values.toJSONObject(keys); 317 assertEquals(1, object.length()); 318 assertFalse(object.has("b")); 319 assertEquals("{\"a\":5.5}", object.toString()); 320 } 321 322 public void testToJSONObjectMoreNamesThanValues() throws JSONException { 323 JSONArray keys = new JSONArray(); 324 keys.put("a"); 325 keys.put("b"); 326 JSONArray values = new JSONArray(); 327 values.put(5.5d); 328 JSONObject object = values.toJSONObject(keys); 329 assertEquals(1, object.length()); 330 assertEquals(5.5d, object.get("a")); 331 } 332 333 public void testToJSONObjectMoreValuesThanNames() throws JSONException { 334 JSONArray keys = new JSONArray(); 335 keys.put("a"); 336 JSONArray values = new JSONArray(); 337 values.put(5.5d); 338 values.put(11.0d); 339 JSONObject object = values.toJSONObject(keys); 340 assertEquals(1, object.length()); 341 assertEquals(5.5d, object.get("a")); 342 } 343 344 public void testToJSONObjectNullKey() throws JSONException { 345 JSONArray keys = new JSONArray(); 346 keys.put(JSONObject.NULL); 347 JSONArray values = new JSONArray(); 348 values.put(5.5d); 349 JSONObject object = values.toJSONObject(keys); 350 assertEquals(1, object.length()); 351 assertEquals(5.5d, object.get("null")); 352 } 353 354 public void testPutUnsupportedNumbers() throws JSONException { 355 JSONArray array = new JSONArray(); 356 357 try { 358 array.put(Double.NaN); 359 fail(); 360 } catch (JSONException e) { 361 } 362 try { 363 array.put(0, Double.NEGATIVE_INFINITY); 364 fail(); 365 } catch (JSONException e) { 366 } 367 try { 368 array.put(0, Double.POSITIVE_INFINITY); 369 fail(); 370 } catch (JSONException e) { 371 } 372 } 373 374 public void testPutUnsupportedNumbersAsObject() throws JSONException { 375 JSONArray array = new JSONArray(); 376 array.put(Double.valueOf(Double.NaN)); 377 array.put(Double.valueOf(Double.NEGATIVE_INFINITY)); 378 array.put(Double.valueOf(Double.POSITIVE_INFINITY)); 379 assertEquals(null, array.toString()); 380 } 381 382 /** 383 * Although JSONArray is usually defensive about which numbers it accepts, 384 * it doesn't check inputs in its constructor. 385 */ 386 public void testCreateWithUnsupportedNumbers() throws JSONException { 387 JSONArray array = new JSONArray(Arrays.asList(5.5, Double.NaN)); 388 assertEquals(2, array.length()); 389 assertEquals(5.5, array.getDouble(0)); 390 assertEquals(Double.NaN, array.getDouble(1)); 391 } 392 393 public void testToStringWithUnsupportedNumbers() throws JSONException { 394 // when the array contains an unsupported number, toString returns null! 395 JSONArray array = new JSONArray(Arrays.asList(5.5, Double.NaN)); 396 assertNull(array.toString()); 397 } 398 399 public void testListConstructorCopiesContents() throws JSONException { 400 List<Object> contents = Arrays.<Object>asList(5); 401 JSONArray array = new JSONArray(contents); 402 contents.set(0, 10); 403 assertEquals(5, array.get(0)); 404 } 405 406 public void testTokenerConstructor() throws JSONException { 407 JSONArray object = new JSONArray(new JSONTokener("[false]")); 408 assertEquals(1, object.length()); 409 assertEquals(false, object.get(0)); 410 } 411 412 public void testTokenerConstructorWrongType() throws JSONException { 413 try { 414 new JSONArray(new JSONTokener("{\"foo\": false}")); 415 fail(); 416 } catch (JSONException e) { 417 } 418 } 419 420 public void testTokenerConstructorNull() throws JSONException { 421 try { 422 new JSONArray((JSONTokener) null); 423 fail(); 424 } catch (NullPointerException e) { 425 } 426 } 427 428 public void testTokenerConstructorParseFail() { 429 try { 430 new JSONArray(new JSONTokener("[")); 431 fail(); 432 } catch (JSONException e) { 433 } catch (StackOverflowError e) { 434 fail("Stack overflowed on input: \"[\""); 435 } 436 } 437 438 public void testStringConstructor() throws JSONException { 439 JSONArray object = new JSONArray("[false]"); 440 assertEquals(1, object.length()); 441 assertEquals(false, object.get(0)); 442 } 443 444 public void testStringConstructorWrongType() throws JSONException { 445 try { 446 new JSONArray("{\"foo\": false}"); 447 fail(); 448 } catch (JSONException e) { 449 } 450 } 451 452 public void testStringConstructorNull() throws JSONException { 453 try { 454 new JSONArray((String) null); 455 fail(); 456 } catch (NullPointerException e) { 457 } 458 } 459 460 public void testStringConstructorParseFail() { 461 try { 462 new JSONArray("["); 463 fail(); 464 } catch (JSONException e) { 465 } catch (StackOverflowError e) { 466 fail("Stack overflowed on input: \"[\""); 467 } 468 } 469 470 public void testCreate() throws JSONException { 471 JSONArray array = new JSONArray(Arrays.asList(5.5, true)); 472 assertEquals(2, array.length()); 473 assertEquals(5.5, array.getDouble(0)); 474 assertEquals(true, array.get(1)); 475 assertEquals("[5.5,true]", array.toString()); 476 } 477 478 public void testAccessOutOfBounds() throws JSONException { 479 JSONArray array = new JSONArray(); 480 array.put("foo"); 481 assertEquals(null, array.opt(3)); 482 assertEquals(null, array.opt(-3)); 483 assertEquals("", array.optString(3)); 484 assertEquals("", array.optString(-3)); 485 try { 486 array.get(3); 487 fail(); 488 } catch (JSONException e) { 489 } 490 try { 491 array.get(-3); 492 fail(); 493 } catch (JSONException e) { 494 } 495 try { 496 array.getString(3); 497 fail(); 498 } catch (JSONException e) { 499 } 500 try { 501 array.getString(-3); 502 fail(); 503 } catch (JSONException e) { 504 } 505 } 506} 507