151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson/* 251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * Copyright (C) 2010 The Android Open Source Project 351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * 451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * you may not use this file except in compliance with the License. 651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * You may obtain a copy of the License at 751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * 851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * 1051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * Unless required by applicable law or agreed to in writing, software 1151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 1251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * See the License for the specific language governing permissions and 1451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * limitations under the License. 1551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson */ 1651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 1751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilsonpackage org.json; 1851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 197365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilsonimport java.util.ArrayList; 207365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilsonimport java.util.Arrays; 217365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilsonimport java.util.HashMap; 227365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilsonimport java.util.Iterator; 237365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilsonimport java.util.List; 247365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilsonimport java.util.Map; 2551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilsonimport junit.framework.TestCase; 2651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 2751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilsonpublic class ParsingTest extends TestCase { 2851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 2951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testParsingNoObjects() { 3051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson try { 3151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson new JSONTokener("").nextValue(); 3251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson fail(); 3351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } catch (JSONException e) { 3451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 3551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 3651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 3751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testParsingLiterals() throws JSONException { 3851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(Boolean.TRUE, "true"); 3951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(Boolean.FALSE, "false"); 4051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(JSONObject.NULL, "null"); 4151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(JSONObject.NULL, "NULL"); 4251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(Boolean.FALSE, "False"); 4351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(Boolean.TRUE, "truE"); 4451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 4551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 4651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testParsingQuotedStrings() throws JSONException { 4751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed("abc", "\"abc\""); 4851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed("123", "\"123\""); 4951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed("foo\nbar", "\"foo\\nbar\""); 5051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed("foo bar", "\"foo\\u0020bar\""); 5151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed("\"{}[]/\\:,=;#", "\"\\\"{}[]/\\\\:,=;#\""); 5251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 5351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 5451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testParsingSingleQuotedStrings() throws JSONException { 5551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed("abc", "'abc'"); 5651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed("123", "'123'"); 5751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed("foo\nbar", "'foo\\nbar'"); 5851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed("foo bar", "'foo\\u0020bar'"); 5951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed("\"{}[]/\\:,=;#", "'\\\"{}[]/\\\\:,=;#'"); 6051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 6151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 6251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testParsingUnquotedStrings() throws JSONException { 6351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed("abc", "abc"); 6451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed("123abc", "123abc"); 6551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed("123e0x", "123e0x"); 6651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed("123e", "123e"); 6751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed("123ee21", "123ee21"); 6851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed("0xFFFFFFFFFFFFFFFFF", "0xFFFFFFFFFFFFFFFFF"); 6951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 7051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 7151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson /** 7251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * Unfortunately the original implementation attempts to figure out what 7351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * Java number type best suits an input value. 7451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson */ 7551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testParsingNumbersThatAreBestRepresentedAsLongs() throws JSONException { 7651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(9223372036854775807L, "9223372036854775807"); 7751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(9223372036854775806L, "9223372036854775806"); 7851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(-9223372036854775808L, "-9223372036854775808"); 7951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(-9223372036854775807L, "-9223372036854775807"); 8051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 8151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 8251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testParsingNumbersThatAreBestRepresentedAsIntegers() throws JSONException { 8351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(0, "0"); 8451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(5, "5"); 8551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(-2147483648, "-2147483648"); 8651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(2147483647, "2147483647"); 8751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 8851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 8951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testParsingNegativeZero() throws JSONException { 9051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(0, "-0"); 9151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 9251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 9351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testParsingIntegersWithAdditionalPrecisionYieldDoubles() throws JSONException { 9451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(1d, "1.00"); 9551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(1d, "1.0"); 9651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(0d, "0.0"); 9751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(-0d, "-0.0"); 9851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 9951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 10051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testParsingNumbersThatAreBestRepresentedAsDoubles() throws JSONException { 10151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(9.223372036854776E18, "9223372036854775808"); 10251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(-9.223372036854776E18, "-9223372036854775809"); 10351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(1.7976931348623157E308, "1.7976931348623157e308"); 10451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(2.2250738585072014E-308, "2.2250738585072014E-308"); 10551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(4.9E-324, "4.9E-324"); 10651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(4.9E-324, "4.9e-324"); 10751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 10851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 10951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testParsingOctalNumbers() throws JSONException { 11051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(5, "05"); 11151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(8, "010"); 11251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(1046, "02026"); 11351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 11451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 11551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testParsingHexNumbers() throws JSONException { 11651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(5, "0x5"); 11751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(16, "0x10"); 11851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(8230, "0x2026"); 11951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(180150010, "0xABCDEFA"); 12051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(2077093803, "0x7BCDEFAB"); 12151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 12251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 12351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testParsingLargeHexValues() throws JSONException { 12451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(Integer.MAX_VALUE, "0x7FFFFFFF"); 12551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson String message = "Hex values are parsed as Strings if their signed " + 12651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson "value is greater than Integer.MAX_VALUE."; 12751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(message, 0x80000000L, "0x80000000"); 12851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 12951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 13051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void test64BitHexValues() throws JSONException { 131f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes assertParsed("Large hex longs shouldn't be yield ints or strings", 13251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson -1L, "0xFFFFFFFFFFFFFFFF"); 13351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 13451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 13551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testParsingWithCommentsAndWhitespace() throws JSONException { 13651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed("baz", " // foo bar \n baz"); 13719554ec99d57e820a4c9da3bcde93d77b537d515Jesse Wilson assertParsed("baz", " // foo bar \r baz"); 13819554ec99d57e820a4c9da3bcde93d77b537d515Jesse Wilson assertParsed("baz", " // foo bar \r\n baz"); 13919554ec99d57e820a4c9da3bcde93d77b537d515Jesse Wilson assertParsed("baz", " # foo bar \n baz"); 14019554ec99d57e820a4c9da3bcde93d77b537d515Jesse Wilson assertParsed("baz", " # foo bar \r baz"); 14119554ec99d57e820a4c9da3bcde93d77b537d515Jesse Wilson assertParsed("baz", " # foo bar \r\n baz"); 14251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(5, " /* foo bar \n baz */ 5"); 14351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(5, " /* foo bar \n baz */ 5 // quux"); 14451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(5, " 5 "); 14551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(5, " 5 \r\n\t "); 14651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(5, "\r\n\t 5 "); 14751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 14851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 14951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testParsingArrays() throws JSONException { 15051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(array(), "[]"); 15151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(array(5, 6, true), "[5,6,true]"); 15251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(array(5, 6, array()), "[5,6,[]]"); 15351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(array(5, 6, 7), "[5;6;7]"); 15451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(array(5, 6, 7), "[5 , 6 \t; \r\n 7\n]"); 15551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(array(5, 6, 7, null), "[5,6,7,]"); 15651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(array(null, null), "[,]"); 15751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(array(5, null, null, null, 5), "[5,,,,5]"); 15851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(array(null, 5), "[,5]"); 15951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(array(null, null, null), "[,,]"); 16051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(array(null, null, null, 5), "[,,,5]"); 16151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 16251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 16351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testParsingObjects() throws JSONException { 16451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(object("foo", 5), "{\"foo\": 5}"); 16551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(object("foo", 5), "{foo: 5}"); 16651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(object("foo", 5, "bar", "baz"), "{\"foo\": 5, \"bar\": \"baz\"}"); 16751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(object("foo", 5, "bar", "baz"), "{\"foo\": 5; \"bar\": \"baz\"}"); 16851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(object("foo", 5, "bar", "baz"), "{\"foo\"= 5; \"bar\"= \"baz\"}"); 16951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(object("foo", 5, "bar", "baz"), "{\"foo\"=> 5; \"bar\"=> \"baz\"}"); 17051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(object("foo", object(), "bar", array()), "{\"foo\"=> {}; \"bar\"=> []}"); 17151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(object("foo", object("foo", array(5, 6))), "{\"foo\": {\"foo\": [5, 6]}}"); 17251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed(object("foo", object("foo", array(5, 6))), "{\"foo\":\n\t{\t \"foo\":[5,\r6]}}"); 17351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 17451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 17551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testSyntaxProblemUnterminatedObject() { 17651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("{"); 17751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("{\"foo\""); 17851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("{\"foo\":"); 17951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("{\"foo\":bar"); 18051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("{\"foo\":bar,"); 18151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("{\"foo\":bar,\"baz\""); 18251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("{\"foo\":bar,\"baz\":"); 18351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("{\"foo\":bar,\"baz\":true"); 18451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("{\"foo\":bar,\"baz\":true,"); 18551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 18651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 18751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testSyntaxProblemEmptyString() { 18851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail(""); 18951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 19051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 19151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testSyntaxProblemUnterminatedArray() { 19251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("["); 19351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("[,"); 19451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("[,,"); 19551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("[true"); 19651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("[true,"); 19751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("[true,,"); 19851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 19951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 20051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson public void testSyntaxProblemMalformedObject() { 20151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("{:}"); 20251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("{\"key\":}"); 20351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("{:true}"); 20451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("{\"key\":true:}"); 20551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("{null:true}"); 20651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("{true:true}"); 20751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParseFail("{0xFF:true}"); 20851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 20951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 21051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson private void assertParseFail(String malformedJson) { 21151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson try { 21251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson new JSONTokener(malformedJson).nextValue(); 21351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson fail("Successfully parsed: \"" + malformedJson + "\""); 21451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } catch (JSONException e) { 21551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } catch (StackOverflowError e) { 21651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson fail("Stack overflowed on input: \"" + malformedJson + "\""); 21751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 21851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 21951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 22051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson private JSONArray array(Object... elements) { 22151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson return new JSONArray(Arrays.asList(elements)); 22251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 22351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 22451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson private JSONObject object(Object... keyValuePairs) throws JSONException { 22551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson JSONObject result = new JSONObject(); 22651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson for (int i = 0; i < keyValuePairs.length; i+=2) { 22751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson result.put((String) keyValuePairs[i], keyValuePairs[i+1]); 22851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 22951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson return result; 23051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 23151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 23251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson private void assertParsed(String message, Object expected, String json) throws JSONException { 23351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson Object actual = new JSONTokener(json).nextValue(); 23451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson actual = canonicalize(actual); 23551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson expected = canonicalize(expected); 23651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertEquals("For input \"" + json + "\" " + message, expected, actual); 23751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 23851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 23951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson private void assertParsed(Object expected, String json) throws JSONException { 24051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson assertParsed("", expected, json); 24151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 24251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson 24351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson /** 24451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * Since they don't implement equals or hashCode properly, this recursively 24551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * replaces JSONObjects with an equivalent HashMap, and JSONArrays with the 24651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * equivalent ArrayList. 24751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson */ 24851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson private Object canonicalize(Object input) throws JSONException { 24951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson if (input instanceof JSONArray) { 25051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson JSONArray array = (JSONArray) input; 25151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson List<Object> result = new ArrayList<Object>(); 25251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson for (int i = 0; i < array.length(); i++) { 25351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson result.add(canonicalize(array.opt(i))); 25451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 25551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson return result; 25651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } else if (input instanceof JSONObject) { 25751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson JSONObject object = (JSONObject) input; 25851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson Map<String, Object> result = new HashMap<String, Object>(); 25951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson for (Iterator<?> i = object.keys(); i.hasNext(); ) { 26051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson String key = (String) i.next(); 26151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson result.put(key, canonicalize(object.get(key))); 26251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 26351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson return result; 2643ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes } else if (input == null || input.equals(JSONObject.NULL)) { 2653ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes return JSONObject.NULL; 26651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } else { 26751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson return input; 26851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 26951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson } 27051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson} 271