http://git-wip-us.apache.org/repos/asf/groovy/blob/13202599/subprojects/groovy-json/src/spec/test/json/JsonTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/spec/test/json/JsonTest.groovy 
b/subprojects/groovy-json/src/spec/test/json/JsonTest.groovy
index b320939..28067a6 100644
--- a/subprojects/groovy-json/src/spec/test/json/JsonTest.groovy
+++ b/subprojects/groovy-json/src/spec/test/json/JsonTest.groovy
@@ -94,6 +94,74 @@ class JsonTest extends GroovyTestCase {
         '''
     }
 
+    void testJsonOutputWithGenerator() {
+        assertScript '''
+        import groovy.json.*
+
+        // tag::json_output_generator[]
+        class Person {
+            String name
+            String title
+            int age
+            String password
+            Date dob
+            URL favoriteUrl
+        }
+
+        Person person = new Person(name: 'John', title: null, age: 21, 
password: 'secret',
+                                    dob: Date.parse('yyyy-MM-dd', 
'1984-12-15'),
+                                    favoriteUrl: new 
URL('http://groovy-lang.org/'))
+
+        def generator = new JsonGenerator.Options()
+            .excludeNulls()
+            .dateFormat('MM@dd@yyyy')
+            .excludeFieldsByName('age', 'password')
+            .excludeFieldsByType(URL)
+            .build()
+
+        assert generator.toJson(person) == '{"dob":"12@15@1984","name":"John"}'
+        // end::json_output_generator[]
+        '''
+    }
+
+    void testJsonOutputConverter() {
+        assertScript '''
+        import groovy.json.*
+        import static groovy.test.GroovyAssert.shouldFail
+
+        // tag::json_output_converter[]
+        class Person {
+            String name
+            URL favoriteUrl
+        }
+
+        Person person = new Person(name: 'John', favoriteUrl: new 
URL('http://groovy-lang.org/json.html#_jsonoutput'))
+
+        def generator = new JsonGenerator.Options()
+            .addConverter(URL) { URL u, String key ->
+                if (key == 'favoriteUrl') {
+                    '"' + u.getHost() + '"'
+                } else {
+                    JsonOutput.toJson(u)
+                }
+            }
+            .build()
+
+        assert generator.toJson(person) == 
'{"favoriteUrl":"groovy-lang.org","name":"John"}'
+
+        // No key available when generating a JSON Array
+        def list = [new URL('http://groovy-lang.org/json.html#_jsonoutput')]
+        assert generator.toJson(list) == 
'["http://groovy-lang.org/json.html#_jsonoutput";]'
+
+        // First parameter to the converter must match the type for which it 
is registered
+        shouldFail(IllegalArgumentException) {
+            new JsonGenerator.Options()
+                .addConverter(Date) { Calendar cal -> }
+        }
+        // end::json_output_converter[]
+        '''
+    }
+
     void testPrettyPrint() {
         // tag::pretty_print[]
         def json = JsonOutput.toJson([name: 'John Doe', age: 42])

http://git-wip-us.apache.org/repos/asf/groovy/blob/13202599/subprojects/groovy-json/src/spec/test/json/StreamingJsonBuilderTest.groovy
----------------------------------------------------------------------
diff --git 
a/subprojects/groovy-json/src/spec/test/json/StreamingJsonBuilderTest.groovy 
b/subprojects/groovy-json/src/spec/test/json/StreamingJsonBuilderTest.groovy
index c9bb0fe..7deb2ae 100644
--- a/subprojects/groovy-json/src/spec/test/json/StreamingJsonBuilderTest.groovy
+++ b/subprojects/groovy-json/src/spec/test/json/StreamingJsonBuilderTest.groovy
@@ -18,8 +18,6 @@
  */
 package json
 
-import groovy.util.GroovyTestCase
-
 class StreamingJsonBuilderTest extends GroovyTestCase {
 
     void testStreamingJsonBuilder() {
@@ -72,4 +70,37 @@ class StreamingJsonBuilderTest extends GroovyTestCase {
             // end::json_assert[]
        """
     }
+
+    void testStreamingJsonBuilderWithGenerator() {
+        assertScript '''
+            import groovy.json.*
+            // tag::streaming_json_builder_generator[]
+            def generator = new JsonGenerator.Options()
+                    .excludeNulls()
+                    .excludeFieldsByName('make', 'country', 'record')
+                    .excludeFieldsByType(Number)
+                    .addConverter(URL) { url -> '"http://groovy-lang.org";' }
+                    .build()
+
+            StringWriter writer = new StringWriter()
+            StreamingJsonBuilder builder = new StreamingJsonBuilder(writer, 
generator)
+
+            builder.records {
+              car {
+                    name 'HSV Maloo'
+                    make 'Holden'
+                    year 2006
+                    country 'Australia'
+                    homepage new URL('http://example.org')
+                    record {
+                        type 'speed'
+                        description 'production pickup truck with speed of 
271kph'
+                    }
+              }
+            }
+
+            assert writer.toString() == '{"records":{"car":{"name":"HSV 
Maloo","homepage":"http://groovy-lang.org"}}}'
+            // end::streaming_json_builder_generator[]
+        '''
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/groovy/blob/13202599/subprojects/groovy-json/src/test/groovy/groovy/json/CharBufTest.groovy
----------------------------------------------------------------------
diff --git 
a/subprojects/groovy-json/src/test/groovy/groovy/json/CharBufTest.groovy 
b/subprojects/groovy-json/src/test/groovy/groovy/json/CharBufTest.groovy
index d19718e..8915f55 100644
--- a/subprojects/groovy-json/src/test/groovy/groovy/json/CharBufTest.groovy
+++ b/subprojects/groovy-json/src/test/groovy/groovy/json/CharBufTest.groovy
@@ -63,6 +63,17 @@ class CharBufTest extends GroovyTestCase {
         assert str == '" \\\\ "'
     }
 
+    void testDisableUnicodeEscaping() {
+        String str = CharBuf.create(0).addJsonEscapedString("Éric").toString()
+        assert str == '"\\u00c9ric"'
+
+        str = CharBuf.create(0).addJsonEscapedString("Éric", false).toString()
+        assert str == '"\\u00c9ric"'
+
+        str = CharBuf.create(0).addJsonEscapedString("Éric", true).toString()
+        assert str == '"Éric"'
+    }
+
     /**
      * https://issues.apache.org/jira/browse/GROOVY-6937
      * https://issues.apache.org/jira/browse/GROOVY-6852
@@ -84,4 +95,28 @@ class CharBufTest extends GroovyTestCase {
         result = new JsonBuilder(obj).toString()
         assert result == /["${'\\u20ac' * 20_000}"]/
     }
+
+    void testRemoveLastChar() {
+        CharBuf buffer
+
+        buffer = CharBuf.create(8).add('value1,')
+        buffer.removeLastChar()
+        assert buffer.toString() == 'value1'
+
+        buffer = CharBuf.create(4)
+        buffer.removeLastChar()
+        assert buffer.toString() == ''
+
+        buffer = CharBuf.create(8).add('[]')
+        buffer.removeLastChar((char)',')
+        assert buffer.toString() == '[]'
+
+        buffer = CharBuf.create(8).add('[val,')
+        buffer.removeLastChar((char)',')
+        assert buffer.toString() == '[val'
+
+        buffer = CharBuf.create(32).add('[one,two,three,four,')
+        buffer.removeLastChar((char)',')
+        assert buffer.toString() == '[one,two,three,four'
+    }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/13202599/subprojects/groovy-json/src/test/groovy/groovy/json/CustomJsonGeneratorTest.groovy
----------------------------------------------------------------------
diff --git 
a/subprojects/groovy-json/src/test/groovy/groovy/json/CustomJsonGeneratorTest.groovy
 
b/subprojects/groovy-json/src/test/groovy/groovy/json/CustomJsonGeneratorTest.groovy
new file mode 100644
index 0000000..38a73fa
--- /dev/null
+++ 
b/subprojects/groovy-json/src/test/groovy/groovy/json/CustomJsonGeneratorTest.groovy
@@ -0,0 +1,89 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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 groovy.json
+
+import groovy.json.JsonGenerator.Converter
+import groovy.json.JsonGenerator.Options
+import groovy.json.internal.CharBuf
+
+/**
+ * Tests extensibility of JsonGenerator and associated classes
+ */
+class CustomJsonGeneratorTest extends GroovyTestCase {
+
+    void testCustomGenerator() {
+        def generator = new CustomJsonOptions()
+                            .excludeNulls()
+                            .lowerCaseFieldNames()
+                            .addCustomConverter(new CustomJsonConverter())
+                            .build()
+
+        assert generator.toJson(['one', null, 'two', null]) == '["one","two"]'
+        assert generator.toJson(['Foo':'test1', 'BAR':'test2']) == 
'{"foo":"test1","bar":"test2"}'
+        assert generator.toJson(['foo': new CustomFoo()]) == 
'{"foo":"CustomFoo from CustomJsonConverter"}'
+    }
+
+    static class CustomJsonOptions extends Options {
+        boolean lowerCaseFieldNames
+        CustomJsonOptions lowerCaseFieldNames() {
+            lowerCaseFieldNames = true
+            return this
+        }
+        CustomJsonOptions addCustomConverter(Converter converter) {
+            converters.add(converter)
+            return this
+        }
+        @Override
+        CustomJsonGenerator build() {
+            return new CustomJsonGenerator(this)
+        }
+    }
+
+    static class CustomJsonGenerator extends DefaultJsonGenerator {
+        boolean lowerCaseFieldNames
+        CustomJsonGenerator(CustomJsonOptions opts) {
+            super(opts)
+            lowerCaseFieldNames = opts.lowerCaseFieldNames
+        }
+        @Override
+        protected void writeMapEntry(String key, Object value, CharBuf buffer) 
{
+            String newKey = (lowerCaseFieldNames) ? key.toLowerCase() : key
+            super.writeMapEntry(newKey, value, buffer)
+        }
+    }
+
+    static class CustomJsonConverter implements Converter {
+        @Override
+        boolean handles(Class<?> type) {
+            return CustomFoo.isAssignableFrom(type)
+        }
+
+        @Override
+        CharSequence convert(Object value) {
+            return convert(value, null)
+        }
+
+        @Override
+        CharSequence convert(Object value, String key) {
+            return '"CustomFoo from CustomJsonConverter"'
+        }
+    }
+
+    static class CustomFoo {}
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/13202599/subprojects/groovy-json/src/test/groovy/groovy/json/DefaultJsonGeneratorTest.groovy
----------------------------------------------------------------------
diff --git 
a/subprojects/groovy-json/src/test/groovy/groovy/json/DefaultJsonGeneratorTest.groovy
 
b/subprojects/groovy-json/src/test/groovy/groovy/json/DefaultJsonGeneratorTest.groovy
new file mode 100644
index 0000000..167ce31
--- /dev/null
+++ 
b/subprojects/groovy-json/src/test/groovy/groovy/json/DefaultJsonGeneratorTest.groovy
@@ -0,0 +1,283 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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 groovy.json
+
+class DefaultJsonGeneratorTest extends GroovyTestCase {
+
+    void testExcludesNullValues() {
+        def generator = new JsonGenerator.Options()
+                .excludeNulls()
+                .build()
+
+        def json = generator.toJson(new JsonObject(name: 'test', properties: 
null))
+        assert json == '{"name":"test"}'
+
+        json = generator.toJson([field1: null, field2: "test"])
+        assert json == '{"field2":"test"}'
+
+        assert generator.toJson([null]) == '[]'
+        assert generator.toJson(['a','b','c','d', null]) == '["a","b","c","d"]'
+        assert generator.toJson(['a', null, null, null, null]) == '["a"]'
+        assert generator.toJson(['a', null, null, null, 'e']) == '["a","e"]'
+
+        def jsonArray = ["foo", null, "bar"]
+        def jsonExpected = '["foo","bar"]'
+        assert generator.toJson(jsonArray) == jsonExpected
+        assert generator.toJson(jsonArray as Object[]) == jsonExpected
+        assert generator.toJson(jsonArray.iterator()) == jsonExpected
+        assert generator.toJson((Iterable)jsonArray) == jsonExpected
+
+        assert generator.toJson((Boolean)null) == ''
+        assert generator.toJson((Number)null) == ''
+        assert generator.toJson((Character)null) == ''
+        assert generator.toJson((String)null) == ''
+        assert generator.toJson((Date)null) == ''
+        assert generator.toJson((Calendar)null) == ''
+        assert generator.toJson((UUID)null) == ''
+        assert generator.toJson((Closure)null) == ''
+        assert generator.toJson((Expando)null) == ''
+        assert generator.toJson((Object)null) == ''
+        assert generator.toJson((Map)null) == ''
+    }
+
+    void testCustomDateFormat() {
+        def generator = new JsonGenerator.Options()
+                .dateFormat('yyyy-MM')
+                .build()
+
+        Date aDate = Date.parse('yyyy-MM-dd', '2016-07-04')
+        assert generator.toJson(aDate) == '"2016-07"'
+
+        def jsonObject = new JsonObject(name: 'test', properties: [startDate: 
aDate])
+        def json = generator.toJson(jsonObject)
+        assert json.contains('{"startDate":"2016-07"}')
+
+        def jsonArray = ["foo", aDate, "bar"]
+        def jsonExpected = '["foo","2016-07","bar"]'
+        assert generator.toJson(jsonArray) == jsonExpected
+        assert generator.toJson(jsonArray as Object[]) == jsonExpected
+        assert generator.toJson(jsonArray.iterator()) == jsonExpected
+        assert generator.toJson((Iterable)jsonArray) == jsonExpected
+    }
+
+    void testDateFormatBadInput() {
+        shouldFail(NullPointerException) {
+            new JsonGenerator.Options().dateFormat(null)
+        }
+        shouldFail(IllegalArgumentException) {
+            new JsonGenerator.Options().dateFormat('abcde')
+        }
+        shouldFail(NullPointerException) {
+            new JsonGenerator.Options().timezone(null)
+        }
+    }
+
+    void testConverters() {
+        def generator = new JsonGenerator.Options()
+                .addConverter(JsonCyclicReference) { object, key ->
+            return '"JsonCyclicReference causes a stackoverflow"'
+        }
+        .addConverter(Date) { object ->
+            return '"4 score and 7 years ago"'
+        }
+        .addConverter(Calendar) { object ->
+            return '"22 days ago"'
+        }
+        .build()
+
+        assert generator.toJson(new Date()) == '"4 score and 7 years ago"'
+
+        def ref = new JsonBar('bar', new Date())
+        def json = generator.toJson(ref)
+        assert json.contains('"lastVisit":"4 score and 7 years ago"')
+        assert json.contains('"cycle":"JsonCyclicReference causes a 
stackoverflow"')
+
+        def jsonArray = ["foo", new JsonCyclicReference(), "bar", new Date()]
+        def jsonExpected = '["foo","JsonCyclicReference causes a 
stackoverflow","bar","4 score and 7 years ago"]'
+        assert generator.toJson(jsonArray) == jsonExpected
+        assert generator.toJson(jsonArray as Object[]) == jsonExpected
+        assert generator.toJson(jsonArray.iterator()) == jsonExpected
+        assert generator.toJson((Iterable)jsonArray) == jsonExpected
+
+        assert generator.toJson([timeline: Calendar.getInstance()]) == 
'{"timeline":"22 days ago"}'
+    }
+
+    void testConverterAddedLastTakesPrecedence() {
+        def options = new JsonGenerator.Options()
+        def c1 = { 'c1' }
+        def c2 = { 'c2' }
+        options.addConverter(URL, {})
+        options.addConverter(Date, c1)
+        options.addConverter(Calendar, {})
+        options.addConverter(Date, c2)
+        options.addConverter(java.sql.Date, {})
+
+        assert optio...@converters.size() == 4
+        assert options.@converters[2].convert(null) == 'c2'
+        assert !optio...@converters.find { it.convert(null) == 'c1' }
+    }
+
+    void testConvertersBadInput() {
+        shouldFail(NullPointerException) {
+            new JsonGenerator.Options().addConverter(null, null)
+        }
+        shouldFail(NullPointerException) {
+            new JsonGenerator.Options().addConverter(Date, null)
+        }
+        shouldFail(IllegalArgumentException) {
+            new JsonGenerator.Options().addConverter(Date, {-> 'no args 
closure'})
+        }
+        shouldFail(IllegalArgumentException) {
+            new JsonGenerator.Options().addConverter(Date, { UUID obj -> 
'mis-matched types'})
+        }
+        shouldFail(IllegalArgumentException) {
+            new JsonGenerator.Options().addConverter(Date, { Date obj, UUID cs 
-> 'mis-matched types'})
+        }
+    }
+
+    void testExcludesFieldsByName() {
+        def generator = new JsonGenerator.Options()
+                .excludeFieldsByName('name')
+                .build()
+
+        def ref = new JsonObject(name: 'Jason', properties: ['foo': 'bar'])
+        def json = generator.toJson(ref)
+        assert json == '{"properties":{"foo":"bar"}}'
+
+        def jsonArray = ["foo", ["bar":"test","name":"Jane"], "baz"]
+        def jsonExpected = '["foo",{"bar":"test"},"baz"]'
+        assert generator.toJson(jsonArray) == jsonExpected
+        assert generator.toJson(jsonArray as Object[]) == jsonExpected
+        assert generator.toJson(jsonArray.iterator()) == jsonExpected
+        assert generator.toJson((Iterable)jsonArray) == jsonExpected
+
+        def excludeList = ['foo', 'bar', "${'zoo'}"]
+        generator = new JsonGenerator.Options()
+                .excludeFieldsByName(excludeList)
+                .build()
+
+        json = generator.toJson([foo: 'one', bar: 'two', baz: 'three', zoo: 
'four'])
+        assert json == '{"baz":"three"}'
+    }
+
+    void testExcludeFieldsByNameBadInput() {
+        shouldFail(NullPointerException) {
+            new JsonGenerator.Options().excludeFieldsByName(null)
+        }
+    }
+
+    void testExcludeFieldsByNameShouldIgnoreNulls() {
+        def opts = new JsonGenerator.Options()
+                .excludeFieldsByName('foo', null, "${'bar'}")
+                .excludeFieldsByName([new StringBuilder('one'), null, 'two'])
+
+        assert op...@excludedfieldnames.size() == 4
+        assert !opts.@excludedFieldNames.contains(null)
+    }
+
+    void testExcludesFieldsByType() {
+        def generator = new JsonGenerator.Options()
+                .excludeFieldsByType(Date)
+                .build()
+
+        def ref = [name: 'Jason', dob: new Date(), location: 'Los Angeles']
+        assert generator.toJson(ref) == '{"name":"Jason","location":"Los 
Angeles"}'
+
+        def jsonArray = ["foo", "bar", new Date()]
+        def jsonExpected = '["foo","bar"]'
+        assert generator.toJson(jsonArray) == jsonExpected
+        assert generator.toJson(jsonArray as Object[]) == jsonExpected
+        assert generator.toJson(jsonArray.iterator()) == jsonExpected
+        assert generator.toJson((Iterable)jsonArray) == jsonExpected
+
+        generator = new JsonGenerator.Options()
+                .excludeFieldsByType(Integer)
+                .excludeFieldsByType(Boolean)
+                .excludeFieldsByType(Character)
+                .excludeFieldsByType(Calendar)
+                .excludeFieldsByType(UUID)
+                .excludeFieldsByType(URL)
+                .excludeFieldsByType(Closure)
+                .excludeFieldsByType(Expando)
+                .excludeFieldsByType(TreeMap)
+                .excludeFieldsByType(Date)
+                .build()
+
+        assert generator.toJson(Integer.valueOf(7)) == ''
+        assert generator.toJson(Boolean.TRUE) == ''
+        assert generator.toJson((Character)'c') == ''
+        assert generator.toJson(Calendar.getInstance()) == ''
+        assert generator.toJson(UUID.randomUUID()) == ''
+        assert generator.toJson(new URL('http://groovy-lang.org')) == ''
+        assert generator.toJson({ url new URL('http://groovy-lang.org') }) == 
''
+        assert generator.toJson(new Expando()) == ''
+        assert generator.toJson(new TreeMap()) == ''
+        assert generator.toJson(new java.sql.Date(new Date().getTime())) == ''
+
+        def excludeList = [URL, Date]
+        generator = new JsonGenerator.Options()
+                .excludeFieldsByType(excludeList)
+                .build()
+
+        def json = generator.toJson([foo: new Date(), bar: 'two', baz: new 
URL('http://groovy-lang.org')])
+        assert json == '{"bar":"two"}'
+    }
+
+    void testExcludeFieldsByTypeBadInput() {
+        shouldFail(NullPointerException) {
+            new JsonGenerator.Options().excludeFieldsByType(null)
+        }
+    }
+
+    void testExcludeFieldsByTypeShouldIgnoreNulls() {
+        def opts = new JsonGenerator.Options()
+                .excludeFieldsByType(Date, null, URL)
+                .excludeFieldsByType([Calendar, null, TreeMap])
+
+        assert op...@excludedfieldtypes.size() == 4
+        assert !opts.@excludedFieldTypes.contains(null)
+    }
+
+    void testDisableUnicodeEscaping() {
+        def json = new JsonGenerator.Options()
+                .disableUnicodeEscaping()
+                .build()
+
+        String unicodeString = 'ΚΡΕΩΠΟΛΕΙΟ'
+        assert json.toJson([unicodeString]) == """["${unicodeString}"]"""
+
+        assert json.toJson(['KÉY':'VALUE']) == '{"KÉY":"VALUE"}'
+    }
+
+}
+
+class JsonBar {
+    String favoriteDrink
+    Date lastVisit
+    JsonCyclicReference cycle = new JsonCyclicReference()
+    JsonBar(String favoriteDrink, Date lastVisit) {
+        this.favoriteDrink = favoriteDrink
+        this.lastVisit = lastVisit
+    }
+}
+
+class JsonCyclicReference {
+    static final DEFAULT = new JsonCyclicReference()
+    JsonCyclicReference() { }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/13202599/subprojects/groovy-json/src/test/groovy/groovy/json/JsonBuilderTest.groovy
----------------------------------------------------------------------
diff --git 
a/subprojects/groovy-json/src/test/groovy/groovy/json/JsonBuilderTest.groovy 
b/subprojects/groovy-json/src/test/groovy/groovy/json/JsonBuilderTest.groovy
index ec643f0..79c88e3 100644
--- a/subprojects/groovy-json/src/test/groovy/groovy/json/JsonBuilderTest.groovy
+++ b/subprojects/groovy-json/src/test/groovy/groovy/json/JsonBuilderTest.groovy
@@ -402,4 +402,31 @@ class JsonBuilderTest extends GroovyTestCase {
         assert new JsonBuilder({'\1' 0}).toString() == '{"\\u0001":0}'
         assert new JsonBuilder({'\u0002' 0}).toString() == '{"\\u0002":0}'
     }
+
+    void testWithGenerator() {
+        def generator = new JsonGenerator.Options()
+                .excludeNulls()
+                .dateFormat('yyyyMM')
+                .excludeFieldsByName('secretKey', 'creditCardNumber')
+                .excludeFieldsByType(URL)
+                .addConverter(java.util.concurrent.atomic.AtomicBoolean) { ab 
-> ab.toString() }
+                .build()
+
+        def json = new JsonBuilder(generator)
+
+        json.payload {
+            id 'YT-1234'
+            location null
+            secretKey 'J79-A25'
+            creditCardNumber '123-444-789-2233'
+            site new URL('http://groovy-lang.org')
+            isActive new java.util.concurrent.atomic.AtomicBoolean(true)
+        }
+
+        assert json.toString() == 
'{"payload":{"id":"YT-1234","isActive":true}}'
+
+        json = new JsonBuilder(['foo', null, 'bar', new 
URL('http://groovy-lang.org')], generator)
+        assert json.toString() == '["foo","bar"]'
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/13202599/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy
----------------------------------------------------------------------
diff --git 
a/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy
 
b/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy
index 25ac0ae..a3cf4d8 100644
--- 
a/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy
+++ 
b/subprojects/groovy-json/src/test/groovy/groovy/json/StreamingJsonBuilderTest.groovy
@@ -496,4 +496,54 @@ class StreamingJsonBuilderTest extends GroovyTestCase {
             }
         }
     }
+
+    void testWithGenerator() {
+        def generator = new JsonGenerator.Options()
+                .excludeNulls()
+                .dateFormat('yyyyMM')
+                .excludeFieldsByName('secretKey', 'creditCardNumber')
+                .excludeFieldsByType(URL)
+                .addConverter(java.util.concurrent.atomic.AtomicBoolean) { ab 
-> ab.toString() }
+                .build()
+
+        new StringWriter().with { w ->
+            def builder = new StreamingJsonBuilder(w, generator)
+
+            builder.payload {
+                id 'YT-1234'
+                location null
+                secretKey 'J79-A25'
+                creditCardNumber '123-444-789-2233'
+                site new URL('http://groovy-lang.org')
+                isActive new java.util.concurrent.atomic.AtomicBoolean(true)
+            }
+
+            assert w.toString() == 
'{"payload":{"id":"YT-1234","isActive":true}}'
+        }
+    }
+
+    @CompileStatic
+    void testWithGeneratorCompileStatic() {
+        def generator = new JsonGenerator.Options()
+                .excludeNulls()
+                .dateFormat('yyyyMM')
+                .excludeFieldsByName('secretKey', 'creditCardNumber')
+                .excludeFieldsByType(URL)
+                .addConverter(java.util.concurrent.atomic.AtomicBoolean) { ab 
-> ab.toString() }
+                .build()
+
+        new StringWriter().with { w ->
+            def builder = new StreamingJsonBuilder(w, generator)
+            builder.call('payload') {
+                call 'id', 'YT-1234'
+                call 'location', (String)null
+                call 'secretKey', 'J79-A25'
+                call 'creditCardNumber', '123-444-789-2233'
+                call 'site', new URL('http://groovy-lang.org')
+                call 'isActive', new 
java.util.concurrent.atomic.AtomicBoolean(true)
+            }
+
+            assert w.toString() == 
'{"payload":{"id":"YT-1234","isActive":true}}'
+        }
+    }
 }

Reply via email to