diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/BaseJavaModule.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/BaseJavaModule.java index afa121acb..fc0c0b285 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/BaseJavaModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/BaseJavaModule.java @@ -9,8 +9,6 @@ package com.facebook.react.bridge; -import com.fasterxml.jackson.core.JsonGenerator; - import com.facebook.infer.annotation.Assertions; import com.facebook.systrace.Systrace; @@ -325,20 +323,18 @@ public abstract class BaseJavaModule implements NativeModule { } @Override - public final void writeConstantsField(JsonGenerator jg, String fieldName) throws IOException { + public final void writeConstantsField(JsonWriter writer, String fieldName) throws IOException { Map constants = getConstants(); if (constants == null || constants.isEmpty()) { return; } - jg.writeObjectFieldStart(fieldName); + writer.name(fieldName).beginObject(); for (Map.Entry constant : constants.entrySet()) { - JsonGeneratorHelper.writeObjectField( - jg, - constant.getKey(), - constant.getValue()); + writer.name(constant.getKey()); + JsonWriterHelper.value(writer, constant.getValue()); } - jg.writeEndObject(); + writer.endObject(); } @Override diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java index db990b2e7..9107fcae7 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java @@ -31,9 +31,6 @@ import com.facebook.react.common.futures.SimpleSettableFuture; import com.facebook.systrace.Systrace; import com.facebook.systrace.TraceListener; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; - /** * This provides an implementation of the public CatalystInstance instance. It is public because * it is built by ReactInstanceManager which is in a different package. @@ -358,21 +355,24 @@ public class CatalystInstanceImpl implements CatalystInstance { private String buildModulesConfigJSONProperty( NativeModuleRegistry nativeModuleRegistry, JavaScriptModulesConfig jsModulesConfig) { - JsonFactory jsonFactory = new JsonFactory(); - StringWriter writer = new StringWriter(); + StringWriter stringWriter = new StringWriter(); + JsonWriter writer = new JsonWriter(stringWriter); try { - JsonGenerator jg = jsonFactory.createGenerator(writer); - jg.writeStartObject(); - jg.writeFieldName("remoteModuleConfig"); - nativeModuleRegistry.writeModuleDescriptions(jg); - jg.writeFieldName("localModulesConfig"); - jsModulesConfig.writeModuleDescriptions(jg); - jg.writeEndObject(); - jg.close(); + writer.beginObject(); + writer.name("remoteModuleConfig"); + nativeModuleRegistry.writeModuleDescriptions(writer); + writer.name("localModulesConfig"); + jsModulesConfig.writeModuleDescriptions(writer); + writer.endObject(); + return stringWriter.toString(); } catch (IOException ioe) { throw new RuntimeException("Unable to serialize JavaScript module declaration", ioe); + } finally { + try { + writer.close(); + } catch (IOException ignored) { + } } - return writer.getBuffer().toString(); } private void incrementPendingJSCalls() { diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaScriptModulesConfig.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaScriptModulesConfig.java index 30739aa13..fb50c0102 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaScriptModulesConfig.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaScriptModulesConfig.java @@ -14,8 +14,6 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; -import com.fasterxml.jackson.core.JsonGenerator; - /** * Class stores configuration of javascript modules that can be used across the bridge */ @@ -31,29 +29,29 @@ public class JavaScriptModulesConfig { return mModules; } - public void writeModuleDescriptions(JsonGenerator jg) throws IOException { - jg.writeStartObject(); + public void writeModuleDescriptions(JsonWriter writer) throws IOException { + writer.beginObject(); for (JavaScriptModuleRegistration registration : mModules) { - jg.writeObjectFieldStart(registration.getName()); - appendJSModuleToJSONObject(jg, registration); - jg.writeEndObject(); + writer.name(registration.getName()).beginObject(); + appendJSModuleToJSONObject(writer, registration); + writer.endObject(); } - jg.writeEndObject(); + writer.endObject(); } private void appendJSModuleToJSONObject( - JsonGenerator jg, + JsonWriter writer, JavaScriptModuleRegistration registration) throws IOException { - jg.writeObjectField("moduleID", registration.getModuleId()); - jg.writeObjectFieldStart("methods"); + writer.name("moduleID").value(registration.getModuleId()); + writer.name("methods").beginObject(); for (Method method : registration.getMethods()) { - jg.writeObjectFieldStart(method.getName()); - jg.writeObjectField("methodID", registration.getMethodId(method)); - jg.writeEndObject(); + writer.name(method.getName()).beginObject(); + writer.name("methodID").value(registration.getMethodId(method)); + writer.endObject(); } - jg.writeEndObject(); + writer.endObject(); if (registration.getModuleInterface().isAnnotationPresent(SupportsWebWorkers.class)) { - jg.writeBooleanField("supportsWebWorkers", true); + writer.name("supportsWebWorkers").value(true); } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/JsonGeneratorHelper.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/JsonGeneratorHelper.java deleted file mode 100644 index 551ca5ac2..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/JsonGeneratorHelper.java +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -package com.facebook.react.bridge; - -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.fasterxml.jackson.core.JsonGenerator; - -/** - * Helper for generating JSON for lists and maps. - */ -public class JsonGeneratorHelper { - - /** - * Like {@link JsonGenerator#writeObjectField(String, Object)} but supports Maps and Lists. - */ - public static void writeObjectField(JsonGenerator jg, String name, Object object) - throws IOException { - if (object instanceof Map) { - writeMap(jg, name, (Map) object); - } else if (object instanceof List) { - writeList(jg, name, (List) object); - } else { - jg.writeObjectField(name, object); - } - } - - private static void writeMap(JsonGenerator jg, String name, Map map) throws IOException { - jg.writeObjectFieldStart(name); - Set entries = map.entrySet(); - for (Map.Entry entry : entries) { - writeObjectField(jg, entry.getKey().toString(), entry.getValue()); - } - jg.writeEndObject(); - } - - private static void writeList(JsonGenerator jg, String name, List list) throws IOException { - jg.writeArrayFieldStart(name); - for (Object item : list) { - jg.writeObject(item); - } - jg.writeEndArray(); - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/JsonWriter.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/JsonWriter.java new file mode 100644 index 000000000..664a7a273 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/JsonWriter.java @@ -0,0 +1,218 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.facebook.react.bridge; + +import java.io.Closeable; +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * Simple Json generator that does no validation. + */ +public class JsonWriter implements Closeable { + private final Writer mWriter; + private final Deque mScopes; + + public JsonWriter(Writer writer) { + mWriter = writer; + mScopes = new ArrayDeque<>(); + } + + public JsonWriter beginArray() throws IOException { + open(Scope.EMPTY_ARRAY, '['); + return this; + } + + public JsonWriter endArray() throws IOException { + close(']'); + return this; + } + + public JsonWriter beginObject() throws IOException { + open(Scope.EMPTY_OBJECT, '{'); + return this; + } + + public JsonWriter endObject() throws IOException { + close('}'); + return this; + } + + public JsonWriter name(String name) throws IOException { + if (name == null) { + throw new NullPointerException("name can not be null"); + } + beforeName(); + string(name); + mWriter.write(':'); + return this; + } + + public JsonWriter value(String value) throws IOException { + if (value == null) { + return nullValue(); + } + beforeValue(); + string(value); + return this; + } + + public JsonWriter nullValue() throws IOException { + beforeValue(); + mWriter.write("null"); + return this; + } + + public JsonWriter rawValue(String json) throws IOException { + beforeValue(); + mWriter.write(json); + return this; + } + + public JsonWriter value(boolean value) throws IOException { + beforeValue(); + mWriter.write(value ? "true" : "false"); + return this; + } + + public JsonWriter value(double value) throws IOException { + beforeValue(); + mWriter.append(Double.toString(value)); + return this; + } + + public JsonWriter value(long value) throws IOException { + beforeValue(); + mWriter.write(Long.toString(value)); + return this; + } + + public JsonWriter value(Number value) throws IOException { + if (value == null) { + return nullValue(); + } + beforeValue(); + mWriter.append(value.toString()); + return this; + } + + @Override + public void close() throws IOException { + mWriter.close(); + } + + private void beforeValue() throws IOException { + Scope scope = mScopes.peek(); + switch (scope) { + case EMPTY_ARRAY: + replace(Scope.ARRAY); + break; + case EMPTY_OBJECT: + throw new IllegalArgumentException(Scope.EMPTY_OBJECT.name()); + case ARRAY: + mWriter.write(','); + break; + case OBJECT: + break; + default: + throw new IllegalStateException("Unknown scope: " + scope); + } + } + + private void beforeName() throws IOException { + Scope scope = mScopes.peek(); + switch (scope) { + case EMPTY_ARRAY: + case ARRAY: + throw new IllegalStateException("name not allowed in array"); + case EMPTY_OBJECT: + replace(Scope.OBJECT); + break; + case OBJECT: + mWriter.write(','); + break; + default: + throw new IllegalStateException("Unknown scope: " + scope); + } + } + + private void open(Scope scope, char bracket) throws IOException { + mScopes.push(scope); + mWriter.write(bracket); + } + + private void close(char bracket) throws IOException { + mScopes.pop(); + mWriter.write(bracket); + } + + private void string(String string) throws IOException { + mWriter.write('"'); + for (int i = 0, length = string.length(); i < length; i++) { + char c = string.charAt(i); + switch (c) { + case '\t': + mWriter.write("\\t"); + break; + + case '\b': + mWriter.write("\\b"); + break; + + case '\n': + mWriter.write("\\n"); + break; + + case '\r': + mWriter.write("\\r"); + break; + + case '\f': + mWriter.write("\\f"); + break; + + case '"': + case '\\': + mWriter.write('\\'); + mWriter.write(c); + break; + + case '\u2028': + case '\u2029': + mWriter.write(String.format("\\u%04x", (int) c)); + break; + + default: + if (c <= 0x1F) { + mWriter.write(String.format("\\u%04x", (int) c)); + } else { + mWriter.write(c); + } + break; + } + + } + mWriter.write('"'); + } + + private void replace(Scope scope) { + mScopes.pop(); + mScopes.push(scope); + } + + private enum Scope { + EMPTY_OBJECT, + OBJECT, + EMPTY_ARRAY, + ARRAY + } +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/JsonWriterHelper.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/JsonWriterHelper.java new file mode 100644 index 000000000..99b6593a2 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/JsonWriterHelper.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.facebook.react.bridge; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * Helper for generating JSON for lists and maps. + */ +class JsonWriterHelper { + public static void value(JsonWriter writer, Object value) throws IOException { + if (value instanceof Map) { + mapValue(writer, (Map) value); + } else if (value instanceof List) { + listValue(writer, (List) value); + } else { + objectValue(writer, value); + } + } + + private static void mapValue(JsonWriter writer, Map map) throws IOException { + writer.beginObject(); + for (Map.Entry entry : map.entrySet()) { + writer.name(entry.getKey().toString()); + value(writer, entry.getValue()); + } + writer.endObject(); + } + + private static void listValue(JsonWriter writer, List list) throws IOException { + writer.beginArray(); + for (Object item : list) { + objectValue(writer, item); + } + writer.endArray(); + } + + private static void objectValue(JsonWriter writer, Object value) throws IOException { + if (value == null) { + writer.nullValue(); + } else if (value instanceof String) { + writer.value((String) value); + } else if (value instanceof Number) { + writer.value((Number) value); + } else if (value instanceof Boolean) { + writer.value((Boolean) value); + } else { + throw new IllegalArgumentException("Unknown value: " + value); + } + } +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeModule.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeModule.java index e954bc901..86cb740d5 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeModule.java @@ -12,8 +12,6 @@ package com.facebook.react.bridge; import java.io.IOException; import java.util.Map; -import com.fasterxml.jackson.core.JsonGenerator; - /** * A native module whose API can be provided to JS catalyst instances. {@link NativeModule}s whose * implementation is written in Java should extend {@link BaseJavaModule} or {@link @@ -42,7 +40,7 @@ public interface NativeModule { * Append a field which represents the constants this module exports * to JS. If no constants are exported this should do nothing. */ - void writeConstantsField(JsonGenerator jg, String fieldName) throws IOException; + void writeConstantsField(JsonWriter writer, String fieldName) throws IOException; /** * This is called at the end of {@link CatalystApplicationFragment#createCatalystInstance()} diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeModuleRegistry.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeModuleRegistry.java index adb48a364..2179a4b7a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeModuleRegistry.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeModuleRegistry.java @@ -20,8 +20,6 @@ import com.facebook.react.common.MapBuilder; import com.facebook.infer.annotation.Assertions; import com.facebook.systrace.Systrace; -import com.fasterxml.jackson.core.JsonGenerator; - /** * A set of Java APIs to expose to a particular JavaScript instance. */ @@ -64,27 +62,27 @@ public class NativeModuleRegistry { definition.call(catalystInstance, executorToken, methodId, parameters); } - /* package */ void writeModuleDescriptions(JsonGenerator jg) throws IOException { + /* package */ void writeModuleDescriptions(JsonWriter writer) throws IOException { Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "CreateJSON"); try { - jg.writeStartObject(); + writer.beginObject(); for (ModuleDefinition moduleDef : mModuleTable) { - jg.writeObjectFieldStart(moduleDef.name); - jg.writeNumberField("moduleID", moduleDef.id); - jg.writeBooleanField("supportsWebWorkers", moduleDef.target.supportsWebWorkers()); - jg.writeObjectFieldStart("methods"); + writer.name(moduleDef.name).beginObject(); + writer.name("moduleID").value(moduleDef.id); + writer.name("supportsWebWorkers").value(moduleDef.target.supportsWebWorkers()); + writer.name("methods").beginObject(); for (int i = 0; i < moduleDef.methods.size(); i++) { MethodRegistration method = moduleDef.methods.get(i); - jg.writeObjectFieldStart(method.name); - jg.writeNumberField("methodID", i); - jg.writeStringField("type", method.method.getType()); - jg.writeEndObject(); + writer.name(method.name).beginObject(); + writer.name("methodID").value(i); + writer.name("type").value(method.method.getType()); + writer.endObject(); } - jg.writeEndObject(); - moduleDef.target.writeConstantsField(jg, "constants"); - jg.writeEndObject(); + writer.endObject(); + moduleDef.target.writeConstantsField(writer, "constants"); + writer.endObject(); } - jg.writeEndObject(); + writer.endObject(); } finally { Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); } diff --git a/ReactAndroid/src/test/java/com/facebook/react/bridge/BUCK b/ReactAndroid/src/test/java/com/facebook/react/bridge/BUCK index 83b2c81f8..9bfa0288c 100644 --- a/ReactAndroid/src/test/java/com/facebook/react/bridge/BUCK +++ b/ReactAndroid/src/test/java/com/facebook/react/bridge/BUCK @@ -8,12 +8,12 @@ android_library( name = 'testhelpers', srcs = glob(['*.java'], excludes = STANDARD_TEST_SRCS), deps = [ - react_native_target('java/com/facebook/react/bridge:bridge'), - react_native_target('java/com/facebook/react/uimanager:uimanager'), react_native_dep('third-party/java/mockito:mockito'), react_native_dep('third-party/java/robolectric3/robolectric:robolectric'), + react_native_target('java/com/facebook/react/bridge:bridge'), + react_native_target('java/com/facebook/react/uimanager:uimanager'), react_native_tests_target('java/org/mockito/configuration:configuration'), -], + ], visibility = [ 'PUBLIC' ], @@ -26,19 +26,18 @@ robolectric3_test( srcs = glob(STANDARD_TEST_SRCS), deps = [ ':testhelpers', - react_native_target('java/com/facebook/react/bridge:bridge'), - react_native_target('java/com/facebook/react/common:common'), - react_native_target('java/com/facebook/react/uimanager:uimanager'), - - react_native_dep('third-party/java/robolectric3/robolectric:robolectric'), + react_native_dep('libraries/fbcore/src/test/java/com/facebook/powermock:powermock'), + react_native_dep('libraries/soloader/java/com/facebook/soloader:soloader'), react_native_dep('third-party/java/fest:fest'), - react_native_dep('third-party/java/junit:junit'), - react_native_dep('third-party/java/mockito:mockito'), react_native_dep('third-party/java/jackson:core'), react_native_dep('third-party/java/jackson:jackson'), react_native_dep('third-party/java/jsr-305:jsr-305'), - react_native_dep('libraries/fbcore/src/test/java/com/facebook/powermock:powermock'), - react_native_dep('libraries/soloader/java/com/facebook/soloader:soloader'), + react_native_dep('third-party/java/junit:junit'), + react_native_dep('third-party/java/mockito:mockito'), + react_native_dep('third-party/java/robolectric3/robolectric:robolectric'), + react_native_target('java/com/facebook/react/bridge:bridge'), + react_native_target('java/com/facebook/react/common:common'), + react_native_target('java/com/facebook/react/uimanager:uimanager'), ], visibility = [ 'PUBLIC' diff --git a/ReactAndroid/src/test/java/com/facebook/react/bridge/JavaScriptModuleConfigTest.java b/ReactAndroid/src/test/java/com/facebook/react/bridge/JavaScriptModuleConfigTest.java index 6b2b9ea7b..e87ad92f1 100644 --- a/ReactAndroid/src/test/java/com/facebook/react/bridge/JavaScriptModuleConfigTest.java +++ b/ReactAndroid/src/test/java/com/facebook/react/bridge/JavaScriptModuleConfigTest.java @@ -12,8 +12,6 @@ package com.facebook.react.bridge; import java.io.IOException; import java.io.StringWriter; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; @@ -82,12 +80,11 @@ public class JavaScriptModuleConfigTest { private static String getModuleDescriptions(JavaScriptModulesConfig jsModulesConfig) throws IOException { - JsonFactory jsonFactory = new JsonFactory(); - StringWriter writer = new StringWriter(); - JsonGenerator jg = jsonFactory.createGenerator(writer); - jsModulesConfig.writeModuleDescriptions(jg); - jg.close(); - return writer.getBuffer().toString(); + StringWriter stringWriter = new StringWriter(); + JsonWriter writer = new JsonWriter(stringWriter); + jsModulesConfig.writeModuleDescriptions(writer); + writer.close(); + return stringWriter.getBuffer().toString(); } private JsonNode parse(String json) throws Exception { diff --git a/ReactAndroid/src/test/java/com/facebook/react/bridge/JsonWriterTest.java b/ReactAndroid/src/test/java/com/facebook/react/bridge/JsonWriterTest.java new file mode 100644 index 000000000..2e6466a88 --- /dev/null +++ b/ReactAndroid/src/test/java/com/facebook/react/bridge/JsonWriterTest.java @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.facebook.react.bridge; + +import java.io.IOException; +import java.io.StringWriter; + +import org.junit.Test; + +import static org.fest.assertions.api.Assertions.assertThat; + +public class JsonWriterTest { + private final StringWriter mStringWriter; + private final JsonWriter mWriter; + + public JsonWriterTest() { + mStringWriter = new StringWriter(); + mWriter = new JsonWriter(mStringWriter); + } + + @Test + public void emptyObject() throws IOException { + mWriter.beginObject(); + mWriter.endObject(); + verify("{}"); + } + + @Test + public void emptyNestedObject() throws IOException { + mWriter.beginObject(); + mWriter.beginObject(); + mWriter.endObject(); + mWriter.endObject(); + verify("{{}}"); + } + + @Test + public void emptyArray() throws IOException { + mWriter.beginArray(); + mWriter.endArray(); + verify("[]"); + } + + @Test + public void emptyNestedArray() throws IOException { + mWriter.beginArray(); + mWriter.beginArray(); + mWriter.endArray(); + mWriter.endArray(); + verify("[[]]"); + } + + @Test + public void smallObject() throws IOException { + mWriter.beginObject(); + mWriter.name("hello").value(true); + mWriter.name("hello_again").value("hi!"); + mWriter.endObject(); + verify("{\"hello\":true,\"hello_again\":\"hi!\"}"); + } + + @Test + public void smallArray() throws IOException { + mWriter.beginArray(); + mWriter.value(true); + mWriter.value(1); + mWriter.value(1.0); + mWriter.value("hi!"); + mWriter.endArray(); + verify("[true,1,1.0,\"hi!\"]"); + } + + @Test + public void string() throws IOException { + mWriter.beginObject(); + mWriter.name("string").value("hello!"); + mWriter.endObject(); + verify("{\"string\":\"hello!\"}"); + } + + @Test + public void complexString() throws IOException { + mWriter.beginObject(); + mWriter.name("string").value("\t\uD83D\uDCA9"); + mWriter.endObject(); + verify("{\"string\":\"\\t\uD83D\uDCA9\"}"); + } + + private void verify(String expected) throws IOException { + mWriter.close(); + assertThat(mStringWriter.getBuffer().toString()).isEqualTo(expected); + } +} diff --git a/ReactAndroid/src/test/java/com/facebook/react/bridge/NativeModuleRegistryTest.java b/ReactAndroid/src/test/java/com/facebook/react/bridge/NativeModuleRegistryTest.java index 813120c21..4f54a12e8 100644 --- a/ReactAndroid/src/test/java/com/facebook/react/bridge/NativeModuleRegistryTest.java +++ b/ReactAndroid/src/test/java/com/facebook/react/bridge/NativeModuleRegistryTest.java @@ -20,8 +20,6 @@ import java.util.Map; import com.facebook.react.common.MapBuilder; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.TextNode; @@ -189,12 +187,11 @@ public class NativeModuleRegistryTest { private static String getModuleDescriptions(NativeModuleRegistry registry) throws IOException { - JsonFactory jsonFactory = new JsonFactory(); - StringWriter writer = new StringWriter(); - JsonGenerator jg = jsonFactory.createGenerator(writer); - registry.writeModuleDescriptions(jg); - jg.close(); - return writer.getBuffer().toString(); + StringWriter stringWriter = new StringWriter(); + JsonWriter writer = new JsonWriter(stringWriter); + registry.writeModuleDescriptions(writer); + writer.close(); + return stringWriter.getBuffer().toString(); } private static class MethodsModule extends BaseJavaModule {