You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2012/07/09 00:21:33 UTC
[9/9] git commit: Convert existing JSON tests from TestNG to Spock
Convert existing JSON tests from TestNG to Spock
Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/3281925b
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/3281925b
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/3281925b
Branch: refs/heads/5.4-js-rewrite
Commit: 3281925b0441f0342dd5c5f653a69ed892c07fc4
Parents: cea40f5
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Sun Jul 8 13:46:18 2012 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Sun Jul 8 13:46:18 2012 -0700
----------------------------------------------------------------------
tapestry-json/build.gradle | 3 +-
.../test/groovy/json/specs/JSONArraySpec.groovy | 266 ++++
.../test/groovy/json/specs/JSONObjectSpec.groovy | 595 +++++++++
.../org/apache/tapestry5/json/JSONObjectTest.java | 964 ---------------
4 files changed, 862 insertions(+), 966 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3281925b/tapestry-json/build.gradle
----------------------------------------------------------------------
diff --git a/tapestry-json/build.gradle b/tapestry-json/build.gradle
index 24efa4b..e1924ab 100644
--- a/tapestry-json/build.gradle
+++ b/tapestry-json/build.gradle
@@ -3,8 +3,7 @@ description = "Repackaged, improved (and tested) version of code originally from
dependencies {
provided project(':tapestry-ioc')
- testCompile project(':tapestry-test')
-
+ testCompile "org.spockframework:spock-core:${versions.spock}"
}
jar {
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3281925b/tapestry-json/src/test/groovy/json/specs/JSONArraySpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-json/src/test/groovy/json/specs/JSONArraySpec.groovy b/tapestry-json/src/test/groovy/json/specs/JSONArraySpec.groovy
new file mode 100644
index 0000000..1018606
--- /dev/null
+++ b/tapestry-json/src/test/groovy/json/specs/JSONArraySpec.groovy
@@ -0,0 +1,266 @@
+package json.specs
+
+import org.apache.tapestry5.json.JSONArray
+import spock.lang.Specification
+
+class JSONArraySpec extends Specification {
+
+ def "can create a JSONArray by parsing a JSON string"() {
+ when:
+
+ def array = new JSONArray(/[ 'foo', 'bar', "baz" ]/)
+
+ then:
+
+ array.length() == 3
+ array.get(0) == "foo"
+ array.get(1) == "bar"
+ array.get(2) == "baz"
+ }
+
+ def "create a JSONArray from varags"() {
+ when:
+
+ def array = new JSONArray("fred", "barney", "wilma")
+
+ then:
+
+ array.length() == 3
+
+ array.toCompactString() == /["fred","barney","wilma"]/
+ }
+
+ def "array must start with a bracket"() {
+ when:
+
+ new JSONArray("1, 2, 3]")
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message == "A JSONArray text must start with '[' at character 1 of 1, 2, 3]"
+ }
+
+ def "parse an empty array"() {
+ when:
+
+ def array = new JSONArray("[]")
+
+ then:
+
+ array.length() == 0
+ }
+
+ def "an empty element in the parse is a null"() {
+ when:
+
+ def array = new JSONArray("[1,,3]")
+
+ then:
+
+ array.length() == 3
+ array.getInt(0) == 1
+ array.isNull(1)
+ array.getInt(2) == 3
+ }
+
+ def "a comma at the end of the list is ignored"() {
+ when:
+
+ def array = new JSONArray("[1,2,]")
+
+ then:
+
+ array.length() == 2
+ array.get(0) == 1
+ array.get(1) == 2
+ }
+
+ def "getBoolean() when not a boolean at index is an exception"() {
+ def array = new JSONArray("[123]")
+
+ when:
+
+ array.getBoolean(0)
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message == "JSONArray[0] is not a Boolean."
+ }
+
+ def "handling of boolean values passed into constructor"() {
+ when:
+
+ def array = new JSONArray(true, false, "True", "False")
+
+ then:
+
+ array.getBoolean(0) == true
+ array.getBoolean(1) == false
+
+ array.getBoolean(2) == true
+ array.getBoolean(3) == false
+ }
+
+ def "getDouble() when not a double at index is an exception"() {
+ def array = new JSONArray(true)
+
+ when:
+
+ array.getDouble(0)
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message == "JSONArray[0] is not a number."
+ }
+
+ def "getDouble() works with numbers and parseable strings"() {
+ def array = new JSONArray(400l, "95.5")
+
+ expect:
+
+ array.getDouble(0) == 400d
+ array.getDouble(1) == 95.5d
+ }
+
+ def "getLong() works with numbers and parseable strings"() {
+ def array = new JSONArray(400l, "95.5")
+
+ expect:
+
+ array.getLong(0) == 400l
+ array.getLong(1) == 95l
+ }
+
+ def "getJSONArray() when not an array at index is exception"() {
+ def array = new JSONArray("fred", "barney")
+
+ when:
+
+ array.getJSONArray(1)
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message == "JSONArray[1] is not a JSONArray."
+ }
+
+ def "get a nested array"() {
+ def nested = new JSONArray()
+ def outer = new JSONArray(nested)
+
+ expect:
+
+ outer.getJSONArray(0).is(nested)
+ }
+
+ def "getJSONObject() when not a JSONObject at index is an exception"() {
+ def array = new JSONArray("fred", "barney", "wilma")
+
+ when:
+
+ array.getJSONObject(1)
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message == "JSONArray[1] is not a JSONObject."
+ }
+
+ def "may not put at a negative index"() {
+ def array = new JSONArray()
+
+ when:
+
+ array.put(-1, "fred")
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message == "JSONArray[-1] not found."
+ }
+
+ def "put() overrides existing value in array"() {
+ def array = new JSONArray("fred", "barney", "wilma")
+
+ when:
+
+ array.put 2, "betty"
+
+ then:
+
+ array.get(2) == "betty"
+ }
+
+ def "put() with index past end pads array with nulls"() {
+ def array = new JSONArray("fred", "barney", "wilma")
+
+ when:
+
+ array.put 4, "bambam"
+
+ then:
+
+ array.isNull(3)
+
+ array.toCompactString() == /["fred","barney","wilma",null,"bambam"]/
+ }
+
+ def "array equality"() {
+ when:
+
+ def array1 = new JSONArray(1, 2, 3)
+ def array2 = new JSONArray(1, 2, 3)
+
+ then:
+
+ array1 == array1
+ array1 != null
+ array1 != this
+ array1 == array2
+
+ when:
+
+ array2.put 9, "stuff"
+
+ then:
+
+ array1 != array2
+ }
+
+ def "pretty print"() {
+ def array = new JSONArray("fred", "barney")
+
+ expect:
+
+ array.toString() == '''[
+ "fred",
+ "barney"
+]'''
+ }
+
+ def "JSONArray is Iterable"() {
+ def array = new JSONArray(1, 2, false)
+
+ when:
+
+ def i = array.iterator()
+
+ then:
+
+ i.next() == 1
+ i.next() == 2
+ i.next() == false
+
+ !i.hasNext()
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3281925b/tapestry-json/src/test/groovy/json/specs/JSONObjectSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-json/src/test/groovy/json/specs/JSONObjectSpec.groovy b/tapestry-json/src/test/groovy/json/specs/JSONObjectSpec.groovy
new file mode 100644
index 0000000..940c012
--- /dev/null
+++ b/tapestry-json/src/test/groovy/json/specs/JSONObjectSpec.groovy
@@ -0,0 +1,595 @@
+package json.specs
+
+import org.apache.tapestry5.json.JSONArray
+import org.apache.tapestry5.json.JSONObject
+import org.apache.tapestry5.json.JSONString
+import spock.lang.Specification
+import spock.lang.Unroll
+import org.apache.tapestry5.json.JSONLiteral
+
+class JSONObjectSpec extends Specification {
+
+ def "copy an existing JSONObject"() {
+ def master = new JSONObject("fred", "flintstone", "barney", "rubble")
+
+ when:
+
+ def emptyCopy = new JSONObject(master)
+
+ then:
+
+ emptyCopy.keys().empty
+
+ when:
+
+ def limitedCopy = new JSONObject(master, "fred")
+
+ then:
+
+ limitedCopy.keys().size() == 1
+ limitedCopy.get("fred") == "flintstone"
+
+ when:
+
+ def fullCopy = new JSONObject(master, "fred", "barney")
+
+ then:
+
+ fullCopy.toCompactString() == /{"fred":"flintstone","barney":"rubble"}/
+ }
+
+ def "unknown keys when copying a JSONObject are ignored"() {
+ def master = new JSONObject("fred", "flintstone", "barney", "rubble")
+
+ when:
+
+ def copy = new JSONObject(master, "fred", "wilma")
+
+ then:
+
+ copy.keys().size() == 1
+ copy.get("fred") == "flintstone"
+ }
+
+ def "get with unknown key is an exception"() {
+ def master = new JSONObject("fred", "flintstone")
+
+ when:
+
+ master.get "barney"
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message == /JSONObject["barney"] not found./
+ }
+
+ @Unroll
+ def "ensure that stored value #typeName #value is #expectedTypeName #expected"() {
+
+ when:
+
+ def object = new JSONObject().put("key", value)
+
+ then:
+
+ object."get${expectedTypeName.capitalize()}"("key") == expected
+
+ where:
+
+ value | expected | expectedType
+ "true" | true | boolean
+ "TRUE" | true | boolean
+ "false" | false | boolean
+ "FALSE" | false | boolean
+ Boolean.TRUE | true | boolean
+ Boolean.FALSE | false | boolean
+ 3.5d | 3.5d | double
+ 1000l | 1000d | double
+ "-101.7" | -101.7d | double
+ "3" | 3 | int
+ 97l | 97 | int
+ "-8.76" | -8 | int
+ 92d | 92l | long
+ "-200" | -200l | long
+ 123 | "123" | String
+
+ typeName = value.class.simpleName
+ expectedTypeName = expectedType.simpleName
+ }
+
+ @Unroll
+ def "conversion of double #input to string should be '#expected'"() {
+ expect:
+
+ JSONObject.doubleToString(input) == expected
+
+ where:
+
+ input | expected
+ 3d | "3"
+ -22.5d | "-22.5"
+ 0d | "0"
+ Double.NaN | "null"
+ Double.NEGATIVE_INFINITY | "null"
+ Double.POSITIVE_INFINITY | "null"
+ }
+
+ def "exception when getBoolean() on a value that is not a boolean"() {
+
+ def object = new JSONObject().put("akey", 37)
+
+ when:
+
+ object.getBoolean "akey"
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message == /JSONObject["akey"] is not a Boolean./
+ }
+
+ def "accumulate simple values"() {
+ def object = new JSONObject()
+
+ def key = "acckey"
+
+ when:
+
+ object.accumulate key, "alpha"
+
+ then: "first value added is just stored"
+
+ object.toCompactString() == /{"acckey":"alpha"}/
+
+ when: "subsequent values added are accumulated in a JSONArray"
+
+ object.accumulate key, "beta"
+ object.accumulate key, "gamma"
+
+ then:
+
+ object.toCompactString() == /{"acckey":["alpha","beta","gamma"]}/
+
+ object.getJSONArray(key).length() == 3
+ }
+
+ def "accumulate when the stored value is already an array just appends the value"() {
+ def object = new JSONObject()
+
+ when:
+
+ object.accumulate "key", new JSONArray("fred", "barney")
+
+ then:
+
+ object.toCompactString() == /{"key":["fred","barney"]}/
+
+ when:
+
+ object.accumulate "key", "wilma"
+
+ then:
+
+ object.toCompactString() == /{"key":["fred","barney","wilma"]}/
+ }
+
+ def "can create a JSONObject from a JSON string"() {
+ when:
+
+ def object = new JSONObject(/ { fred: "flintstone", caveman: true, friends: ["barney"] }/)
+
+ then:
+
+ object.get("fred") == "flintstone"
+ object.getBoolean("caveman") == true
+
+ def friends = object.getJSONArray "friends"
+
+ friends.length() == 1
+ friends.get(0) == "barney"
+ }
+
+ def "append to an unknown key creates a JSONArray for the value"() {
+ def object = new JSONObject()
+
+ when:
+
+ object.append "friends", "barney"
+
+ then:
+
+ object.toCompactString() == /{"friends":["barney"]}/
+ }
+
+ def "append to an existing key containing a JSONArray appends to the array"() {
+ def object = new JSONObject(/{friends: ["barney"] }/)
+
+ when:
+
+ object.append "friends", "zaphod"
+
+ then:
+
+ object.toCompactString() == /{"friends":["barney","zaphod"]}/
+ }
+
+ def "appending to a key whose value is not a JSONArray is an exception"() {
+ def object = new JSONObject(/{friends: 0 }/)
+
+ when:
+
+ object.append "friends", "zaphod"
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message == /JSONObject["friends"] is not a JSONArray./
+ }
+
+ def "getDouble() with a non-numeric value is an exception"() {
+ def object = new JSONObject(/{notdouble: true}/)
+
+ when:
+
+ object.getDouble "notdouble"
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message == /JSONObject["notdouble"] is not a number./
+ }
+
+ def "getDouble() with a string that can not be parsed as a number is an exception"() {
+ def object = new JSONObject(/{notdouble: "this is a fact"}/)
+
+ when:
+
+ object.getDouble "notdouble"
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message == /JSONObject["notdouble"] is not a number./
+
+ }
+
+ def "has() will identify which keys have values and which do not"() {
+ def object = new JSONObject(/{fred: 'flintstone'}/)
+
+ expect:
+
+ object.has("fred")
+ !object.has("barney")
+ }
+
+ def "getJSONArray() for a value that is not a JSONArray is an exception"() {
+ def object = new JSONObject(/{notarray: 22.7}/)
+
+ when:
+
+ object.getJSONArray "notarray"
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message == /JSONObject["notarray"] is not a JSONArray./
+ }
+
+ def "length() of a JSONObject is the number of keys"() {
+ when:
+
+ def object = new JSONObject()
+
+ then:
+
+ object.length() == 0
+
+ when:
+
+ object.put "fred", "flintstone"
+
+ then:
+
+ object.length() == 1
+
+ when:
+
+ object.accumulate "fred", "murray"
+
+ then:
+
+ object.length() == 1
+
+ when:
+
+ object.put "barney", "rubble"
+
+ then:
+
+ object.length() == 2
+ }
+
+ def "names() returns the keys as a JSONArray"() {
+ def object = new JSONObject(/ {fred: 'flintstone', barney: 'rubble' }/)
+
+ when:
+
+ def names = object.names()
+
+ then:
+
+ names instanceof JSONArray
+ names.length() == 2
+
+ names.toArray().sort() == ["barney", "fred"]
+ }
+
+ def "names() with no properties returns null"() {
+
+ when:
+
+ def object = new JSONObject()
+
+ then:
+
+ object.names() == null
+ }
+
+ def "the null literal is the NULL object"() {
+ when:
+
+ def object = new JSONObject(/{nullkey: null}/)
+
+ then:
+
+ object.get("nullkey") is JSONObject.NULL
+ object.isNull("nullkey")
+ }
+
+ def "the NULL object is output as null literal"() {
+ when:
+
+ def object = new JSONObject().put("nullkey", JSONObject.NULL)
+
+ then:
+
+ object.isNull("nullkey")
+ object.toCompactString() == /{"nullkey":null}/
+ }
+
+ def "the NULL object matches Java's null"() {
+ expect:
+
+ JSONObject.NULL.equals(null)
+ }
+
+ @Unroll
+ def "#desc invalid input is an exception"() {
+ when:
+
+ new JSONObject(input)
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message.trim().startsWith expected
+
+ where:
+
+ input | expected | desc
+ "{ " | "A JSONObject text must end with '}' at character 3" | "unmatched open brace"
+ "fred" | "A JSONObject text must begin with '{' at character 1 of " | "missing open brace"
+ /{ "akey" }/ | /Expected a ':' after a key at character 10 of/ | "missing value after key"
+ /{ "fred" : 1 "barney" }/ | /Expected a ',' or '}' at character 14 of/ | "missing property separator"
+ /{ "list" : [1, 2/ | /Expected a ',' or ']' at character 16 of/ | "missing seperator or closing bracket"
+ }
+
+ def "can use ':' or '=>' as key seperator, and ';' as property separator"() {
+ def object = new JSONObject(/{ "fred" = 1; "barney" => 2}/)
+
+ expect:
+
+ object.getInt("fred") == 1
+ object.getInt("barney") == 2
+ }
+
+ @Unroll
+ def "conversion of #typeName #value to string is #expected"() {
+ expect:
+
+ JSONObject.numberToString(value) == expected
+
+ where:
+
+ value | expected
+ new BigDecimal("100.0000000") | "100"
+
+ typeName = value.class.simpleName
+ }
+
+ @Unroll
+ def "quote(): #desc"() {
+ expect:
+
+ JSONObject.quote(value) == expected
+
+ where:
+
+ value | expected | desc
+ null | /""/ | "null is empty string"
+ "" | /""/ | "empty string is empty string"
+ '''"/\b\t\n\f\r\u2001/a</''' | '''"\\"/\\b\\t\\n\\f\\r\\u2001/a<\\/"''' | "special characters"
+ }
+
+ def "non-finite numbers are not allowed"() {
+ def object = new JSONObject()
+
+ when:
+
+ object.put "nonfinite", value
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message == /JSON does not allow non-finite numbers./
+
+ where:
+
+ value << [Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Float.NaN,
+ Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY]
+
+ }
+
+ def "parse an empty object is empty"() {
+ when:
+
+ def object = new JSONObject(/{}/)
+
+ then:
+
+ object.length() == 0
+ }
+
+ def "put a Java null is a remove"() {
+ def object = new JSONObject(/{fred:'flintstone', barney:'rubble'}/)
+
+ when:
+
+ object.put("fred", null)
+
+ then:
+
+ object.toCompactString() == /{"barney":"rubble"}/
+ }
+
+ def "only specific object types may be added"() {
+ when:
+
+ JSONObject.testValidity([:])
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message == '''JSONObject properties may be one of Boolean, Number, String, org.apache.tapestry5.json.JSONArray, org.apache.tapestry5.json.JSONLiteral, org.apache.tapestry5.json.JSONObject, org.apache.tapestry5.json.JSONObject$Null, org.apache.tapestry5.json.JSONString. Type java.util.LinkedHashMap is not allowed.'''
+ }
+
+ def "JSONString can output anything it wants"() {
+ def string = { "*VALUE*" } as JSONString
+
+ def object = new JSONObject()
+
+ when:
+
+ object.put("key", string)
+
+ then:
+
+ object.toCompactString() == /{"key":*VALUE*}/
+ }
+
+ def "equals() implementation"() {
+ def json = /{ "key" : 99 }/
+
+ when:
+
+ def obj1 = new JSONObject(json)
+ def obj2 = new JSONObject(json)
+
+ then:
+
+ obj1 == obj2
+ obj2 == obj1
+
+ obj1 != null
+ obj1 != json
+
+ when:
+
+ obj2.put("screw", "the pooch")
+
+ then:
+
+ obj1 != obj2
+ }
+
+ def "escaped characters in the JSON are parsed correctly"() {
+ when:
+
+ def object = new JSONObject("{ \"key\" : \"\\\"/\\b\\t\\n\\f\\r\\u2001/a<\\/\\x20\" }")
+
+ then:
+
+ object.get("key") == '''"/\b\t\n\f\r\u2001/a</ '''
+ }
+
+ def "parse a nested object"() {
+ def object = new JSONObject(/ { key: { name: "inner" }}/)
+
+ expect:
+
+ object.getJSONObject("key").getString("name") == "inner"
+ }
+
+ def "parse boolean literals"() {
+ def object = new JSONObject(/{ t: true, f: false }/)
+
+ expect:
+
+ object.getBoolean("t") == true
+ object.getBoolean("f") == false
+ }
+
+ def "parse numeric forms"() {
+ def object = new JSONObject(/{ hex: 0x50, oct: 030, posInt: +50, negInt: -50,
+ long: 4294968530, float: -32.7 }/)
+
+ expect:
+
+ object.getInt("hex") == 80
+ object.getInt("oct") == 24
+ object.getInt("posInt") == 50
+ object.getInt("negInt") == -50
+ object.getLong("long") == 4294968530l
+ object.getDouble("float") == -32.7d
+ }
+
+ def "NULL toString() is null keyword"() {
+ expect:
+
+ JSONObject.NULL.toString() == "null"
+ }
+
+ def "JSONLiteral can output any content"() {
+ def literal = new JSONLiteral('''function(x) { $('bar').show(); }''')
+
+ when:
+
+ def object = new JSONObject().put("callback", literal)
+
+ then:
+
+ object.toCompactString() == '''{"callback":function(x) { $('bar').show(); }}'''
+ }
+
+ def "pretty print"() {
+ def object = new JSONObject("fred", "flintstone", "barney", "rubble")
+
+ expect:
+
+ object.toString() == '''{
+ "fred" : "flintstone",
+ "barney" : "rubble"
+}'''
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3281925b/tapestry-json/src/test/java/org/apache/tapestry5/json/JSONObjectTest.java
----------------------------------------------------------------------
diff --git a/tapestry-json/src/test/java/org/apache/tapestry5/json/JSONObjectTest.java b/tapestry-json/src/test/java/org/apache/tapestry5/json/JSONObjectTest.java
deleted file mode 100644
index 859626f..0000000
--- a/tapestry-json/src/test/java/org/apache/tapestry5/json/JSONObjectTest.java
+++ /dev/null
@@ -1,964 +0,0 @@
-// Copyright 2007, 2009, 2010 The Apache Software Foundation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package org.apache.tapestry5.json;
-
-import java.io.CharArrayWriter;
-import java.io.PrintWriter;
-import java.math.BigDecimal;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-
-import org.apache.tapestry5.ioc.test.TestUtils;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-/**
- * Tests JSONObject, particularly in terms of parsing and writing JSON streams.
- */
-public class JSONObjectTest extends TestUtils
-{
- @Test
- public void copy_from_object_constructor()
- {
- JSONObject master = new JSONObject().put("fred", "flintstone").put("barney", "rubble");
-
- JSONObject emptyCopy = new JSONObject(master);
-
- assertTrue(emptyCopy.keys().isEmpty(), "No properties should have been copied.");
-
- JSONObject limitedCopy = new JSONObject(master, "fred");
-
- assertEquals(limitedCopy.keys().size(), 1);
- assertEquals(limitedCopy.get("fred").toString(), "flintstone");
-
- JSONObject fullCopy = new JSONObject(master, "fred", "barney");
-
- assertEquals(fullCopy.toString(), "{\n \"fred\" : \"flintstone\",\n \"barney\" : \"rubble\"\n" + "}");
-
- JSONObject limitedCopy2 = new JSONObject(master, "fred", "wilma");
- assertEquals(limitedCopy2.keys().size(), 1);
- }
-
- @Test
- public void key_values_constructor()
- {
- JSONObject easy = new JSONObject("fred", "flintstone", "barney", "rubble");
-
- JSONObject hard = new JSONObject().put("fred", "flintstone").put("barney", "rubble");
-
- assertEquals(easy, hard);
- }
-
- @Test
- public void array_from_string()
- {
- JSONArray array = new JSONArray("[ 'foo', 'bar', \"baz\" ]");
-
- assertEquals(array.length(), 3);
- assertEquals(array.getString(0), "foo");
- assertEquals(array.getString(1), "bar");
- assertEquals(array.getString(2), "baz");
- }
-
- @Test
- public void get_not_found()
- {
- JSONObject master = new JSONObject().put("fred", "flintstone");
-
- assertEquals(master.get("fred"), "flintstone");
-
- try
- {
- master.get("barney");
- unreachable();
- }
- catch (RuntimeException ex)
- {
- assertEquals(ex.getMessage(), "JSONObject[\"barney\"] not found.");
- }
- }
-
- @Test(dataProvider = "boolean_inputs")
- public void get_boolean(Object value, boolean expected)
- {
- JSONObject object = new JSONObject().put("mykey", value);
-
- assertEquals(object.getBoolean("mykey"), expected);
- }
-
- @DataProvider
- public Object[][] boolean_inputs()
- {
- return new Object[][]
- {
- { "true", true },
- { "TRUE", true },
- { "false", false },
- { "FALSE", false },
- { Boolean.TRUE, true },
- { Boolean.FALSE, false } };
- }
-
- @Test
- public void not_a_boolean_value()
- {
- JSONObject object = new JSONObject().put("somekey", 37);
-
- try
- {
- object.getBoolean("somekey");
- unreachable();
- }
- catch (RuntimeException ex)
- {
- assertEquals(ex.getMessage(), "JSONObject[\"somekey\"] is not a Boolean.");
- }
- }
-
- @Test
- public void accumulate_simple_values()
- {
- JSONObject object = new JSONObject();
-
- String key = "key";
-
- object.accumulate(key, "alpha");
- object.accumulate(key, "beta");
- object.accumulate(key, "gamma");
-
- assertEquals(object.toString(), "{\n \"key\" : [\n \"alpha\",\n \"beta\",\n" + " \"gamma\"\n ]\n}");
-
- JSONArray array = object.getJSONArray(key);
-
- assertEquals(array.length(), 3);
- }
-
- @Test
- public void accumulate_with_initial_array()
- {
- JSONArray array = new JSONArray();
-
- array.put("alpha");
-
- String key = "key";
-
- JSONObject object = new JSONObject();
-
- object.accumulate(key, array);
- object.accumulate(key, "beta");
-
- array.put("gamma");
-
- assertEquals(object.toString(), "{\n \"key\" : [\n \"alpha\",\n \"beta\",\n" + " \"gamma\"\n ]\n}");
- }
-
- @Test
- public void object_from_string()
- {
- JSONObject object = new JSONObject("{ fred: \"flintstone\", caveman: true, friends: [\"barney\"] }");
-
- assertEquals(object.get("fred"), "flintstone");
- assertEquals(object.getBoolean("caveman"), true);
-
- JSONArray array = object.getJSONArray("friends");
-
- assertEquals(array.length(), 1);
- assertEquals(array.get(0), "barney");
- }
-
- @Test
- public void append()
- {
- JSONObject object = new JSONObject();
- String key = "fubar";
-
- object.append(key, "alpha");
-
- assertEquals(object.toString(), "{\n \"fubar\" : [\n \"alpha\"\n ]\n}");
-
- object.append(key, "beta");
-
- assertEquals(object.toString(), "{\n \"fubar\" : [\n \"alpha\",\n \"beta\"\n ]\n" + "}");
- }
-
- @Test
- public void append_existng_key_not_an_array()
- {
- JSONObject object = new JSONObject();
- String key = "fubar";
-
- object.put(key, "existing");
-
- try
- {
- object.append(key, "additional");
- unreachable();
- }
- catch (RuntimeException ex)
- {
- assertEquals(ex.getMessage(), "JSONObject[\"fubar\"] is not a JSONArray.");
- }
- }
-
- @Test(dataProvider = "double_to_string_data")
- public void double_to_string(double input, String expected)
- {
- String actual = JSONObject.doubleToString(input);
-
- assertEquals(actual, expected);
- }
-
- @DataProvider
- public Object[][] double_to_string_data()
- {
- return new Object[][]
- {
- { 3d, "3" },
- { -22.5d, "-22.5" },
- { 0d, "0" },
- { Double.NEGATIVE_INFINITY, "null" },
- { Double.POSITIVE_INFINITY, "null" },
- { Double.NaN, "null" }, };
- }
-
- @Test(dataProvider = "get_double_data")
- public void get_double(Object value, double expected)
- {
- JSONObject object = new JSONObject();
-
- object.put("key", value);
-
- assertEquals(object.getDouble("key"), expected);
- }
-
- @DataProvider
- public Object[][] get_double_data()
- {
- return new Object[][]
- {
- { new Double(3.5), 3.5d },
- { new Long(1000), 1000d },
- { "-101.7", -101.7d } };
- }
-
- @Test
- public void get_double_not_a_string()
- {
- JSONObject object = new JSONObject();
-
- object.put("notstring", Boolean.FALSE);
-
- try
- {
- object.getDouble("notstring");
- unreachable();
- }
- catch (RuntimeException ex)
- {
- assertEquals(ex.getMessage(), "JSONObject[\"notstring\"] is not a number.");
- }
- }
-
- @Test
- public void get_double_string_invalid_format()
- {
- JSONObject object = new JSONObject();
-
- object.put("badstring", "google");
-
- try
- {
- object.getDouble("badstring");
- unreachable();
- }
- catch (RuntimeException ex)
- {
- assertEquals(ex.getMessage(), "JSONObject[\"badstring\"] is not a number.");
- }
- }
-
- @Test(dataProvider = "get_int_inputs")
- public void get_int(Object value, int expected)
- {
- JSONObject object = new JSONObject();
-
- object.put("intkey", value);
-
- assertEquals(object.getInt("intkey"), expected);
- }
-
- @DataProvider
- public Object[][] get_int_inputs()
- {
- return new Object[][]
- {
- { "3", 3 },
- { new Long(97), 97 },
- { "-8.76", -8 } };
- }
-
- @Test
- public void has()
- {
- JSONObject object = new JSONObject();
-
- object.put("fred", "flintstone");
-
- assertTrue(object.has("fred"));
- assertFalse(object.has("barney"));
- }
-
- @Test
- public void get_json_array()
- {
- JSONArray array = new JSONArray();
-
- JSONObject object = new JSONObject();
-
- object.put("arraykey", array);
- object.put("boolkey", true);
-
- assertSame(object.getJSONArray("arraykey"), array);
-
- try
- {
- object.getJSONArray("boolkey");
- unreachable();
- }
- catch (RuntimeException ex)
- {
- assertEquals(ex.getMessage(), "JSONObject[\"boolkey\"] is not a JSONArray.");
- }
-
- }
-
- @Test
- public void get_json_object()
- {
- JSONObject child = new JSONObject();
- JSONObject root = new JSONObject();
-
- root.put("child", child);
- root.put("boolkey", false);
-
- assertSame(root.getJSONObject("child"), child);
-
- try
- {
- root.getJSONObject("boolkey");
- unreachable();
- }
- catch (RuntimeException ex)
- {
- assertEquals(ex.getMessage(), "JSONObject[\"boolkey\"] is not a JSONObject.");
- }
- }
-
- @Test
- public void boolean_as_value()
- {
- JSONObject object = new JSONObject().put("t", true).put("f", false);
-
- assertEquals(object.toString(), "{\n \"f\" : false,\n \"t\" : true\n}");
- }
-
- @Test
- public void length()
- {
- JSONObject object = new JSONObject();
-
- assertEquals(object.length(), 0);
-
- object.put("key", "fred");
-
- assertEquals(object.length(), 1);
-
- object.accumulate("key", "barney");
- assertEquals(object.length(), 1);
-
- object.put("key2", "wilma");
-
- assertEquals(object.length(), 2);
- }
-
- @Test
- public void names_is_null_if_no_properties()
- {
- JSONObject object = new JSONObject();
-
- assertNull(object.names());
- }
-
- @Test
- public void names()
- {
- JSONObject object = new JSONObject();
-
- object.put("fred", "flintstone");
- object.put("barney", "rubble");
-
- JSONArray array = object.names();
-
- assertEquals(array.length(), 2);
-
- Object[] names = array.toArray();
-
- Arrays.sort(names);
-
- assertEquals(names, new String[]
- { "barney", "fred" });
-
- }
-
- @Test
- public void parse_null()
- {
- JSONObject object = new JSONObject("{ \"nullkey\": null }");
-
- assertSame(object.get("nullkey"), JSONObject.NULL);
- }
-
- @Test
- public void emit_null()
- {
- JSONObject object = new JSONObject();
-
- object.put("nullkey", JSONObject.NULL);
-
- assertEquals(object.toString(), "{\n \"nullkey\" : null\n}");
-
- assertTrue(object.isNull("nullkey"));
- }
-
- @Test
- public void null_matches_java_null()
- {
- assertTrue(JSONObject.NULL.equals(null));
- }
-
- @DataProvider
- public final Object[][] bad_parse_data()
- {
- return new Object[][]
- {
- { "{ ", "A JSONObject text must end with '}' at character 3 of {" },
- { "fred", "A JSONObject text must begin with '{' at character 1 of fred" },
- { "{ \"akey\" }", "Expected a ':' after a key at character 10 of { \"akey\" }" },
- { "{ \"fred\" : 1 \"barney\" }", "Expected a ',' or '}' at character 14 of { \"fred\" : 1 \"barney\" }" },
- { "{ \"list\" : [1, 2", "Expected a ',' or ']' at character 16 of { \"list\" : [1, 2" } };
-
- }
-
- @Test(dataProvider = "bad_parse_data")
- public void jsonobject_parse_errors(String input, String expectedMessage)
- {
- try
- {
- new JSONObject(input);
- unreachable();
- }
- catch (RuntimeException ex)
- {
- assertEquals(ex.getMessage().trim(), expectedMessage);
- }
- }
-
- @Test
- public void alternate_key_value_seperators()
- {
- JSONObject object = new JSONObject("{ \"fred\" = 1; \"barney\" => 2 }");
-
- assertEquals(object.getInt("fred"), 1);
- assertEquals(object.getInt("barney"), 2);
- }
-
- @Test
- public void get_long_from_number()
- {
- JSONObject object = new JSONObject("{ \"key\": 92 }");
-
- assertEquals(object.getLong("key"), 92l);
- }
-
- @Test
- public void get_long_from_string()
- {
- JSONObject object = new JSONObject("{ \"key\": \"-200\" }");
-
- assertEquals(object.getLong("key"), -200l);
- }
-
- @Test
- public void get_string_from_number()
- {
- JSONObject object = new JSONObject("{ \"key\": 92 }");
-
- assertEquals(object.getString("key"), "92");
- }
-
- @Test
- public void number_to_string_conversion()
- {
- JSONObject object = new JSONObject();
-
- object.put("key", new BigDecimal("100.0000000"));
-
- assertEquals(object.toString(), "{\n \"key\" : 100\n}");
- }
-
- @Test
- public void parse_empty_object()
- {
- assertEquals(new JSONObject("{}").length(), 0);
- }
-
- @Test
- public void put_null_is_remove()
- {
- JSONObject object = new JSONObject();
-
- object.put("key", "value");
-
- object.put("key", null);
-
- assertEquals(object.toString(), "{}");
-
- assertTrue(object.keys().isEmpty());
- }
-
- @Test
- public void quote_null_is_empty_string()
- {
- assertEquals(JSONObject.quote(null), "\"\"");
- }
-
- @Test
- public void quote_empty_string_is_empty_string()
- {
- assertEquals(JSONObject.quote(""), "\"\"");
- }
-
- @Test
- public void character_escapes_in_quote()
- {
- assertEquals(JSONObject.quote("\"/\b\t\n\f\r\u2001/a</"), "\"\\\"/\\b\\t\\n\\f\\r\\u2001/a<\\/\"");
- }
-
- @DataProvider
- public Object[][] non_finite_data()
- {
- return new Object[][]
- {
- { Double.NaN },
- { Double.NEGATIVE_INFINITY },
- { Float.NEGATIVE_INFINITY },
- { Float.NaN } };
- }
-
- @Test(dataProvider = "non_finite_data")
- public void non_finite_numbers_not_allowed(Number nonfinite)
- {
- JSONObject object = new JSONObject();
-
- try
- {
- object.put("nonfinite", nonfinite);
- unreachable();
- }
- catch (RuntimeException ex)
- {
- assertEquals(ex.getMessage(), "JSON does not allow non-finite numbers.");
- }
- }
-
- @Test
- public void invalid_object_added()
- {
- try
- {
- JSONObject.testValidity(new HashMap());
- unreachable();
- }
- catch (RuntimeException ex)
- {
- assertEquals(
- ex.getMessage(),
- "JSONObject properties may be one of Boolean, Number, String, org.apache.tapestry5.json.JSONArray, org.apache.tapestry5.json.JSONLiteral, org.apache.tapestry5.json.JSONObject, org.apache.tapestry5.json.JSONObject$Null, org.apache.tapestry5.json.JSONString. Type java.util.HashMap is not allowed.");
- }
- }
-
- @Test
- public void output_json_string()
- {
- JSONString string = new JSONString()
- {
- public String toJSONString()
- {
- return "*VALUE*";
- }
- };
-
- JSONObject object = new JSONObject();
-
- object.put("key", string);
-
- // The implementation of this in Tapestry 5.1 put quotes around *VALUE*. That did not seem to
- // be in accordance with intent, so in 5.2 the toJSONString value is printed without quotes.
-
- assertEquals(object.toString(), "{\n \"key\" : *VALUE*\n}");
- }
-
- @Test
- public void equals_implementation()
- {
- String text = "{ \"key\" : 99 }";
-
- JSONObject obj1 = new JSONObject(text);
- JSONObject obj2 = new JSONObject(text);
-
- assertTrue(obj1.equals(obj1));
- assertTrue(obj1.equals(obj2));
- assertFalse(obj1.equals(null));
- assertFalse(obj1.equals(text));
-
- obj2.put("anotherkey", "something");
-
- assertFalse(obj1.equals(obj2));
- }
-
- @Test
- public void parse_escaped()
- {
- JSONObject object = new JSONObject("{ \"key\" : \"\\\"/\\b\\t\\n\\f\\r\\u2001/a<\\/\\x20\" }");
-
- assertEquals(object.get("key"), "\"/\b\t\n\f\r\u2001/a</ ");
- }
-
- @Test
- public void parse_nested_object()
- {
- JSONObject object = new JSONObject("{ \"key\" : { \"name\" : \"inner\" }}");
-
- JSONObject inner = object.getJSONObject("key");
- assertEquals(inner.getString("name"), "inner");
- }
-
- @Test
- public void parse_true_and_false()
- {
- JSONObject object = new JSONObject("{ \"t\" : true, \"f\" : false }");
-
- assertEquals(object.getBoolean("t"), true);
- assertEquals(object.getBoolean("f"), false);
- }
-
- @Test
- public void parse_number_forms()
- {
- JSONObject object = new JSONObject("{ \"hex\" : 0x50, \"oct\" : 030, \"posInt\" : +50, "
- + " \"negInt\" : -50, \"long\" : 4294968530, \"float\": -32.7 }");
-
- assertEquals(object.getInt("hex"), 80);
- assertEquals(object.getInt("oct"), 24);
- assertEquals(object.getInt("posInt"), 50);
- assertEquals(object.getInt("negInt"), -50);
- assertEquals(object.getLong("long"), 4294968530l);
- assertEquals(object.getDouble("float"), -32.7d);
- }
-
- @Test
- public void json_array_from_values()
- {
- assertEquals(new JSONArray("fred", "barney", "wilma").toString(), "[\n \"fred\",\n \"barney\",\n"
- + " \"wilma\"\n]");
- }
-
- @Test
- public void array_must_start_with_bracket()
- {
- try
- {
- new JSONArray("1, 2, 3]");
- unreachable();
- }
- catch (RuntimeException ex)
- {
- assertEquals(ex.getMessage(), "A JSONArray text must start with '[' at character 1 of 1, 2, 3]");
- }
- }
-
- @Test
- public void parse_empty_array()
- {
- assertEquals(new JSONArray("[]").length(), 0);
- }
-
- @Test
- public void empty_element_is_null()
- {
- JSONArray array = new JSONArray("[1,,3]");
-
- assertEquals(array.getInt(0), 1);
- assertTrue(array.isNull(1));
- assertEquals(array.getInt(2), 3);
- }
-
- @Test
- public void comma_at_end_of_list_is_ignored()
- {
- JSONArray array = new JSONArray("[1,2,]");
-
- assertEquals(array.length(), 2);
- assertEquals(array.getInt(0), 1);
- assertEquals(array.getInt(1), 2);
- }
-
- @Test
- public void not_a_boolean_at_index()
- {
- JSONArray array = new JSONArray("[alpha]");
-
- try
- {
- array.getBoolean(0);
- unreachable();
- }
- catch (RuntimeException ex)
- {
- assertEquals(ex.getMessage(), "JSONArray[0] is not a Boolean.");
- }
- }
-
- @Test
- public void boolean_values()
- {
- JSONArray array = new JSONArray(true, false, "True", "False");
-
- assertTrue(array.getBoolean(0));
- assertTrue(array.getBoolean(2));
-
- assertFalse(array.getBoolean(1));
- assertFalse(array.getBoolean(3));
- }
-
- @Test
- public void not_a_double_at_index()
- {
- JSONArray array = new JSONArray(true);
-
- try
- {
- array.getDouble(0);
- unreachable();
- }
- catch (RuntimeException ex)
- {
- assertEquals(ex.getMessage(), "JSONArray[0] is not a number.");
- }
- }
-
- @Test
- public void get_double_from_array()
- {
- JSONArray array = new JSONArray(400l, "95.5");
-
- assertEquals(array.getDouble(0), 400.d);
- assertEquals(array.getDouble(1), 95.5d);
- }
-
- @Test
- public void get_long_from_array()
- {
- JSONArray array = new JSONArray(400l, "95.5");
-
- assertEquals(array.getLong(0), 400l);
- assertEquals(array.getLong(1), 95l);
- }
-
- @Test
- public void not_a_nested_array_at_index()
- {
- JSONArray array = new JSONArray("fred", "barney");
-
- try
- {
- array.getJSONArray(1);
- unreachable();
- }
- catch (RuntimeException ex)
- {
- assertEquals(ex.getMessage(), "JSONArray[1] is not a JSONArray.");
- }
- }
-
- @Test
- public void get_nested_array()
- {
- JSONArray nested = new JSONArray();
- JSONArray outer = new JSONArray(nested);
-
- assertSame(outer.getJSONArray(0), nested);
- }
-
- @Test
- public void not_a_json_object_at_index()
- {
- JSONArray array = new JSONArray("fred", "barney", "wilma");
-
- try
- {
- array.getJSONObject(1);
- unreachable();
- }
- catch (RuntimeException ex)
- {
- assertEquals(ex.getMessage(), "JSONArray[1] is not a JSONObject.");
- }
- }
-
- @Test
- public void get_json_object_at_index()
- {
- JSONObject inner = new JSONObject();
-
- JSONArray array = new JSONArray("fred", true, inner);
-
- assertSame(array.getJSONObject(2), inner);
- }
-
- @Test
- public void put_at_negative_index_is_invalid()
- {
- JSONArray array = new JSONArray();
-
- try
- {
- array.put(-1, "fred");
- unreachable();
- }
- catch (RuntimeException ex)
- {
- assertEquals(ex.getMessage(), "JSONArray[-1] not found.");
- }
- }
-
- @Test
- public void put_overrides_existing_value_in_array()
- {
- JSONArray array = new JSONArray("fred", "barney", "wilma");
-
- array.put(2, "betty");
-
- assertEquals(array.getString(2), "betty");
- }
-
- @Test
- public void put_pads_short_array_with_nulls()
- {
- JSONArray array = new JSONArray("fred", "barney", "wilma");
-
- array.put(4, "bambam");
-
- assertTrue(array.isNull(3));
- assertEquals(array.getString(4), "bambam");
- }
-
- @Test
- public void array_equality()
- {
- JSONArray array1 = new JSONArray(1, 2, 3);
- JSONArray array2 = new JSONArray(1, 2, 3);
-
- assertTrue(array1.equals(array1));
- assertFalse(array1.equals(null));
- assertFalse(array1.equals(this));
-
- assertTrue(array1.equals(array2));
-
- array2.put(9, "stuff");
-
- assertFalse(array1.equals(array2));
- }
-
- @Test
- public void null_to_string()
- {
- assertEquals(JSONObject.NULL.toString(), "null");
- }
-
- @Test
- public void json_literal()
- {
- JSONObject obj = new JSONObject();
-
- obj.put("callback", new JSONLiteral("function(x) { $('bar').show(); }"));
-
- assertEquals(obj.toString(), "{\n \"callback\" : function(x) { $('bar').show(); }\n}");
- }
-
- @Test
- public void object_print_and_pretty_print()
- {
- JSONObject o = new JSONObject("fred", "flintstone", "barney", "rubble");
-
- assertEquals(o.toString(true), "{\"fred\":\"flintstone\",\"barney\":\"rubble\"}");
- assertEquals(o.toString(false), "{\n \"fred\" : \"flintstone\",\n \"barney\" : \"rubble\"\n}");
- }
-
- @Test
- public void array_print_and_pretty_print()
- {
- JSONArray a = new JSONArray("fred", "barney");
-
- CharArrayWriter caw = new CharArrayWriter();
- PrintWriter pw = new PrintWriter(caw);
-
- a.print(pw);
-
- String compact = caw.toString();
-
- caw.reset();
-
- a.prettyPrint(pw);
-
- String pretty = caw.toString();
-
- assertEquals(compact, "[\"fred\",\"barney\"]");
- assertEquals(pretty, "[\n \"fred\",\n \"barney\"\n]");
- }
-
- @Test
- public void nested_collection()
- {
- JSONObject outer = new JSONObject().put("coll", new JSONArray("fred", "barney"));
-
- assertEquals(outer.toCompactString(), "{\"coll\":[\"fred\",\"barney\"]}");
- }
-
- @Test
- public void json_array_is_iterable()
- {
- JSONArray array = new JSONArray(1, 2, false);
-
- Iterator<Object> iterator = array.iterator();
-
- assertEquals(iterator.next(), 1);
- assertEquals(iterator.next(), 2);
- assertEquals(iterator.next(), false);
-
- assertFalse(iterator.hasNext());
- }
-}