Create Jackson Middleware (#60)
* Create Jackson string parser * Create Jackson BufferedSource parser * Create Jackson Reader parser
This commit is contained in:
parent
cbcd9794e0
commit
9db2456118
16 changed files with 759 additions and 1 deletions
|
@ -42,6 +42,7 @@ ext.versions = [
|
|||
googlePlayServices : '9.6.1',
|
||||
gson : '2.6.2',
|
||||
moshi : '1.3.1',
|
||||
jackson : '2.8.6',
|
||||
guava : '19.0',
|
||||
javapoet : '1.7.0',
|
||||
immutables : '2.2.1',
|
||||
|
@ -99,6 +100,8 @@ ext.libraries = [
|
|||
okio : "com.squareup.okio:okio:$versions.okio",
|
||||
gson : "com.google.code.gson:gson:$versions.gson",
|
||||
moshi : "com.squareup.moshi:moshi:$versions.moshi",
|
||||
jacksonCore : "com.fasterxml.jackson.core:jackson-core:$versions.jackson",
|
||||
jacksonDatabind : "com.fasterxml.jackson.core:jackson-databind:$versions.jackson",
|
||||
guava : "com.google.guava:guava:$versions.guava",
|
||||
googlePlayServices : "com.google.android.gms:play-services-base:$versions.googlePlayServices",
|
||||
googleMessagingCloud : "com.google.android.gms:play-services-gcm:$versions.googlePlayServices",
|
||||
|
|
1
middleware-jackson/.gitignore
vendored
Normal file
1
middleware-jackson/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/build
|
55
middleware-jackson/build.gradle
Normal file
55
middleware-jackson/build.gradle
Normal file
|
@ -0,0 +1,55 @@
|
|||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'com.getkeepsafe.dexcount'
|
||||
|
||||
group = GROUP
|
||||
version = VERSION_NAME
|
||||
|
||||
android {
|
||||
compileSdkVersion versions.compileSdk
|
||||
buildToolsVersion versions.buildTools
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion versions.minSdk
|
||||
targetSdkVersion versions.targetSdk
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
minifyEnabled false
|
||||
zipAlignEnabled false
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError true
|
||||
disable 'InvalidPackage'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(path: ':store')
|
||||
compile libraries.jacksonCore
|
||||
compile libraries.jacksonDatabind
|
||||
compile libraries.rxJava
|
||||
compile libraries.okio
|
||||
compile libraries.dagger
|
||||
compile libraries.supportAnnotations
|
||||
testCompile libraries.mockito
|
||||
testCompile libraries.junit
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar) {
|
||||
from android.sourceSets.main.java.srcDirs
|
||||
classifier = 'sources'
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives sourcesJar
|
||||
}
|
||||
apply from: rootProject.file("gradle/maven-push.gradle")
|
||||
apply from: rootProject.file("gradle/checkstyle.gradle")
|
||||
apply from: rootProject.file("gradle/pmd.gradle")
|
3
middleware-jackson/gradle.properties
Normal file
3
middleware-jackson/gradle.properties
Normal file
|
@ -0,0 +1,3 @@
|
|||
POM_NAME=com.nytimes.android
|
||||
POM_ARTIFACT_ID=middleware-jackson
|
||||
POM_PACKAGING=aar
|
11
middleware-jackson/src/main/AndroidManifest.xml
Normal file
11
middleware-jackson/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.nytimes.android.external.store.middleware.jackson">
|
||||
|
||||
<application android:allowBackup="true"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -0,0 +1,119 @@
|
|||
package com.nytimes.android.external.store.middleware.jackson;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.nytimes.android.external.cache.Preconditions;
|
||||
import com.nytimes.android.external.store.base.Parser;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import okio.BufferedSource;
|
||||
|
||||
/**
|
||||
* Factory which returns various Jackson {@link Parser} implementations.
|
||||
*/
|
||||
public final class JacksonParserFactory {
|
||||
|
||||
private JacksonParserFactory() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Parser which parses from a String to the specified type, using
|
||||
* the provided {@link JsonFactory} instance.
|
||||
*/
|
||||
@NonNull
|
||||
public static <T> Parser<String, T> createStringParser(@NonNull JsonFactory jsonFactory, @NonNull Type type) {
|
||||
Preconditions.checkNotNull(jsonFactory, "jsonFactory cannot be null.");
|
||||
Preconditions.checkNotNull(type, "type cannot be null.");
|
||||
return new JacksonStringParser<>(jsonFactory, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Parser which parses from a String to the specified type, using
|
||||
* the provided {@link ObjectMapper} instance.
|
||||
*/
|
||||
@NonNull
|
||||
public static <T> Parser<String, T> createStringParser(@NonNull ObjectMapper objectMapper, @NonNull Type type) {
|
||||
Preconditions.checkNotNull(objectMapper, "objectMapper cannot be null.");
|
||||
Preconditions.checkNotNull(type, "type cannot be null.");
|
||||
return new JacksonStringParser<>(objectMapper, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Parser which parses from a String to the specified type, using
|
||||
* a new default {@link ObjectMapper} instance.
|
||||
*/
|
||||
@NonNull
|
||||
public static <T> Parser<String, T> createStringParser(@NonNull Class<T> type) {
|
||||
return createStringParser(new ObjectMapper(), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Parser which parses from {@link BufferedSource} to the specified type, using
|
||||
* the provided {@link JsonFactory} instance.
|
||||
*/
|
||||
@NonNull
|
||||
public static <T> Parser<BufferedSource, T> createSourceParser(@NonNull JsonFactory jsonFactory,
|
||||
@NonNull Type type) {
|
||||
Preconditions.checkNotNull(jsonFactory, "jsonFactory cannot be null.");
|
||||
Preconditions.checkNotNull(type, "type cannot be null.");
|
||||
return new JacksonSourceParser<T>(jsonFactory, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Parser which parses from {@link BufferedSource} to the specified type, using
|
||||
* the provided {@link ObjectMapper} instance.
|
||||
*/
|
||||
@NonNull
|
||||
public static <T> Parser<BufferedSource, T> createSourceParser(@NonNull ObjectMapper objectMapper,
|
||||
@NonNull Type type) {
|
||||
Preconditions.checkNotNull(objectMapper, "objectMapper cannot be null.");
|
||||
Preconditions.checkNotNull(type, "type cannot be null.");
|
||||
return new JacksonSourceParser<T>(objectMapper, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Parser which parses from {@link BufferedSource} to the specified type, using
|
||||
* a new default configured {@link ObjectMapper} instance.
|
||||
*/
|
||||
@NonNull
|
||||
public static <T> Parser<BufferedSource, T> createSourceParser(@NonNull Type type) {
|
||||
return createSourceParser(new ObjectMapper(), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Parser which parses from {@link Reader} to the specified type, using
|
||||
* the provided {@link JsonFactory} instance.
|
||||
*/
|
||||
@NonNull
|
||||
public static <T> Parser<Reader, T> createReaderParser(@NonNull JsonFactory jsonFactory,
|
||||
@NonNull Type type) {
|
||||
Preconditions.checkNotNull(jsonFactory, "jsonFactory cannot be null.");
|
||||
Preconditions.checkNotNull(type, "type cannot be null.");
|
||||
return new JacksonReaderParser<>(jsonFactory, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Parser which parses from {@link Reader} to the specified type, using
|
||||
* the provided {@link ObjectMapper} instance.
|
||||
*/
|
||||
@NonNull
|
||||
public static <T> Parser<Reader, T> createReaderParser(@NonNull ObjectMapper objectMapper,
|
||||
@NonNull Type type) {
|
||||
Preconditions.checkNotNull(objectMapper, "objectMapper cannot be null.");
|
||||
Preconditions.checkNotNull(type, "type cannot be null.");
|
||||
return new JacksonReaderParser<T>(objectMapper, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Parser which parses from {@link Reader} to the specified type, using
|
||||
* a new default configured {@link ObjectMapper} instance.
|
||||
*/
|
||||
@NonNull
|
||||
public static <T> Parser<Reader, T> createReaderParser(@NonNull Type type) {
|
||||
return createReaderParser(new ObjectMapper(), type);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.nytimes.android.external.store.middleware.jackson;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.nytimes.android.external.store.base.Parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class JacksonReaderParser<Parsed> implements Parser<Reader, Parsed> {
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
private final JavaType parsedType;
|
||||
|
||||
@Inject
|
||||
public JacksonReaderParser(@NonNull JsonFactory jsonFactory, @NonNull Type type) {
|
||||
objectMapper = new ObjectMapper(jsonFactory);
|
||||
parsedType = objectMapper.constructType(type);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public JacksonReaderParser(@NonNull ObjectMapper objectMapper, @NonNull Type type) {
|
||||
this.objectMapper = objectMapper;
|
||||
parsedType = objectMapper.constructType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parsed call(@NonNull Reader reader) {
|
||||
try {
|
||||
return objectMapper.readValue(reader, parsedType);
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.nytimes.android.external.store.middleware.jackson;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.nytimes.android.external.store.base.Parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import okio.BufferedSource;
|
||||
|
||||
public class JacksonSourceParser<Parsed> implements Parser<BufferedSource, Parsed> {
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
private final JavaType parsedType;
|
||||
|
||||
@Inject
|
||||
public JacksonSourceParser(@NonNull JsonFactory jsonFactory, @NonNull Type type) {
|
||||
objectMapper = new ObjectMapper(jsonFactory);
|
||||
parsedType = objectMapper.constructType(type);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public JacksonSourceParser(@NonNull ObjectMapper objectMapper, @NonNull Type type) {
|
||||
this.objectMapper = objectMapper;
|
||||
parsedType = objectMapper.constructType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
@SuppressWarnings("PMD.EmptyCatchBlock")
|
||||
public Parsed call(@NonNull BufferedSource source) {
|
||||
InputStream inputStream = source.inputStream();
|
||||
try {
|
||||
return objectMapper.readValue(inputStream, parsedType);
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
} finally {
|
||||
try {
|
||||
if (inputStream != null) {
|
||||
inputStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.nytimes.android.external.store.middleware.jackson;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.nytimes.android.external.store.base.Parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class JacksonStringParser<Parsed> implements Parser<String, Parsed> {
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
private final JavaType parsedType;
|
||||
|
||||
@Inject
|
||||
public JacksonStringParser(@NonNull JsonFactory jsonFactory, @NonNull Type type) {
|
||||
objectMapper = new ObjectMapper(jsonFactory);
|
||||
parsedType = objectMapper.constructType(type);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public JacksonStringParser(@NonNull ObjectMapper objectMapper, @NonNull Type type) {
|
||||
this.objectMapper = objectMapper;
|
||||
parsedType = objectMapper.constructType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Parsed call(@NonNull String source) {
|
||||
try {
|
||||
return objectMapper.readValue(source, parsedType);
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
3
middleware-jackson/src/main/res/values/strings.xml
Normal file
3
middleware-jackson/src/main/res/values/strings.xml
Normal file
|
@ -0,0 +1,3 @@
|
|||
<resources>
|
||||
<string name="app_name">middleware-jackson</string>
|
||||
</resources>
|
|
@ -0,0 +1,131 @@
|
|||
package com.nytimes.android.external.store.middleware.jackson;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.nytimes.android.external.store.base.Fetcher;
|
||||
import com.nytimes.android.external.store.base.Parser;
|
||||
import com.nytimes.android.external.store.base.Persister;
|
||||
import com.nytimes.android.external.store.base.Store;
|
||||
import com.nytimes.android.external.store.base.impl.BarCode;
|
||||
import com.nytimes.android.external.store.base.impl.ParsingStoreBuilder;
|
||||
import com.nytimes.android.external.store.middleware.jackson.data.Foo;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
|
||||
import rx.Observable;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class JacksonReaderParserStoreTest {
|
||||
|
||||
private static final String KEY = "key";
|
||||
private static final String sourceString =
|
||||
"{\"number\":123,\"string\":\"abc\",\"bars\":[{\"string\":\"def\"},{\"string\":\"ghi\"}]}";
|
||||
|
||||
@Rule
|
||||
public ExpectedException expectedException = ExpectedException.none();
|
||||
|
||||
@Mock
|
||||
Fetcher<Reader> fetcher;
|
||||
@Mock
|
||||
Persister<Reader> persister;
|
||||
|
||||
private final BarCode barCode = new BarCode("value", KEY);
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
Reader source = new StringReader(sourceString);
|
||||
when(fetcher.fetch(barCode))
|
||||
.thenReturn(Observable.just(source));
|
||||
|
||||
when(persister.read(barCode))
|
||||
.thenReturn(Observable.<Reader>empty())
|
||||
.thenReturn(Observable.just(source));
|
||||
|
||||
when(persister.write(barCode, source))
|
||||
.thenReturn(Observable.just(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultJacksonReaderParser() {
|
||||
Parser<Reader, Foo> parser = JacksonParserFactory.createReaderParser(Foo.class);
|
||||
Store<Foo> store = ParsingStoreBuilder.<Reader, Foo>builder()
|
||||
.persister(persister)
|
||||
.fetcher(fetcher)
|
||||
.parser(parser)
|
||||
.open();
|
||||
|
||||
Foo result = store.get(barCode).toBlocking().first();
|
||||
|
||||
validateFoo(result);
|
||||
|
||||
verify(fetcher, times(1)).fetch(barCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomJsonFactoryReaderParser() {
|
||||
JsonFactory jsonFactory = new JsonFactory();
|
||||
|
||||
Parser<Reader, Foo> parser = JacksonParserFactory.createReaderParser(jsonFactory, Foo.class);
|
||||
|
||||
Store<Foo> store = ParsingStoreBuilder.<Reader, Foo>builder()
|
||||
.persister(persister)
|
||||
.fetcher(fetcher)
|
||||
.parser(parser)
|
||||
.open();
|
||||
|
||||
Foo result = store.get(barCode).toBlocking().first();
|
||||
|
||||
validateFoo(result);
|
||||
|
||||
verify(fetcher, times(1)).fetch(barCode);
|
||||
}
|
||||
|
||||
private void validateFoo(Foo foo) {
|
||||
assertNotNull(foo);
|
||||
assertEquals(foo.number, 123);
|
||||
assertEquals(foo.string, "abc");
|
||||
assertEquals(foo.bars.size(), 2);
|
||||
assertEquals(foo.bars.get(0).string, "def");
|
||||
assertEquals(foo.bars.get(1).string, "ghi");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullJsonFactory() {
|
||||
expectedException.expect(NullPointerException.class);
|
||||
JacksonParserFactory.createReaderParser((JsonFactory) null, Foo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullTypeWithValidJsonFactory() {
|
||||
expectedException.expect(NullPointerException.class);
|
||||
JacksonParserFactory.createReaderParser(new JsonFactory(), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullObjectMapper() {
|
||||
expectedException.expect(NullPointerException.class);
|
||||
JacksonParserFactory.createReaderParser((ObjectMapper) null, Foo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullType() {
|
||||
expectedException.expect(NullPointerException.class);
|
||||
JacksonParserFactory.createStringParser(null);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
package com.nytimes.android.external.store.middleware.jackson;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.nytimes.android.external.store.base.Fetcher;
|
||||
import com.nytimes.android.external.store.base.Parser;
|
||||
import com.nytimes.android.external.store.base.Persister;
|
||||
import com.nytimes.android.external.store.base.Store;
|
||||
import com.nytimes.android.external.store.base.impl.BarCode;
|
||||
import com.nytimes.android.external.store.base.impl.ParsingStoreBuilder;
|
||||
import com.nytimes.android.external.store.middleware.jackson.data.Foo;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import okio.BufferedSource;
|
||||
import okio.Okio;
|
||||
import rx.Observable;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class JacksonSourceParserStoreTest {
|
||||
|
||||
private static final String KEY = "key";
|
||||
private static final String sourceString =
|
||||
"{\"number\":123,\"string\":\"abc\",\"bars\":[{\"string\":\"def\"},{\"string\":\"ghi\"}]}";
|
||||
|
||||
@Rule
|
||||
public ExpectedException expectedException = ExpectedException.none();
|
||||
|
||||
@Mock
|
||||
Fetcher<BufferedSource> fetcher;
|
||||
@Mock
|
||||
Persister<BufferedSource> persister;
|
||||
|
||||
private final BarCode barCode = new BarCode("value", KEY);
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
BufferedSource bufferedSource = source(sourceString);
|
||||
assertNotNull(bufferedSource);
|
||||
|
||||
when(fetcher.fetch(barCode))
|
||||
.thenReturn(Observable.just(bufferedSource));
|
||||
|
||||
when(persister.read(barCode))
|
||||
.thenReturn(Observable.<BufferedSource>empty())
|
||||
.thenReturn(Observable.just(bufferedSource));
|
||||
|
||||
when(persister.write(barCode, bufferedSource))
|
||||
.thenReturn(Observable.just(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultJacksonSourceParser() {
|
||||
Parser<BufferedSource, Foo> parser = JacksonParserFactory.createSourceParser(Foo.class);
|
||||
Store<Foo> store = ParsingStoreBuilder.<BufferedSource, Foo>builder()
|
||||
.persister(persister)
|
||||
.fetcher(fetcher)
|
||||
.parser(parser)
|
||||
.open();
|
||||
|
||||
Foo result = store.get(barCode).toBlocking().first();
|
||||
|
||||
validateFoo(result);
|
||||
|
||||
verify(fetcher, times(1)).fetch(barCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomJsonFactorySourceParser() {
|
||||
JsonFactory jsonFactory = new JsonFactory();
|
||||
|
||||
Parser<BufferedSource, Foo> parser = JacksonParserFactory.createSourceParser(jsonFactory, Foo.class);
|
||||
|
||||
Store<Foo> store = ParsingStoreBuilder.<BufferedSource, Foo>builder()
|
||||
.persister(persister)
|
||||
.fetcher(fetcher)
|
||||
.parser(parser)
|
||||
.open();
|
||||
|
||||
Foo result = store.get(barCode).toBlocking().first();
|
||||
|
||||
validateFoo(result);
|
||||
|
||||
verify(fetcher, times(1)).fetch(barCode);
|
||||
}
|
||||
|
||||
private void validateFoo(Foo foo) {
|
||||
assertNotNull(foo);
|
||||
assertEquals(foo.number, 123);
|
||||
assertEquals(foo.string, "abc");
|
||||
assertEquals(foo.bars.size(), 2);
|
||||
assertEquals(foo.bars.get(0).string, "def");
|
||||
assertEquals(foo.bars.get(1).string, "ghi");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullJsonFactory() {
|
||||
expectedException.expect(NullPointerException.class);
|
||||
JacksonParserFactory.createStringParser((JsonFactory) null, Foo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullTypeWithValidJsonFactory() {
|
||||
expectedException.expect(NullPointerException.class);
|
||||
JacksonParserFactory.createStringParser(new JsonFactory(), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullObjectMapper() {
|
||||
expectedException.expect(NullPointerException.class);
|
||||
JacksonParserFactory.createStringParser((ObjectMapper) null, Foo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullType() {
|
||||
expectedException.expect(NullPointerException.class);
|
||||
JacksonParserFactory.createStringParser(null);
|
||||
}
|
||||
|
||||
private static BufferedSource source(String data) {
|
||||
return Okio.buffer(Okio.source(new ByteArrayInputStream(data.getBytes(Charset.defaultCharset()))));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
package com.nytimes.android.external.store.middleware.jackson;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.nytimes.android.external.store.base.Fetcher;
|
||||
import com.nytimes.android.external.store.base.Parser;
|
||||
import com.nytimes.android.external.store.base.Persister;
|
||||
import com.nytimes.android.external.store.base.Store;
|
||||
import com.nytimes.android.external.store.base.impl.BarCode;
|
||||
import com.nytimes.android.external.store.base.impl.ParsingStoreBuilder;
|
||||
import com.nytimes.android.external.store.middleware.jackson.data.Foo;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import rx.Observable;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class JacksonStringParserStoreTest {
|
||||
|
||||
private static final String KEY = "key";
|
||||
private static final String source =
|
||||
"{\"number\":123,\"string\":\"abc\",\"bars\":[{\"string\":\"def\"},{\"string\":\"ghi\"}]}";
|
||||
|
||||
@Rule
|
||||
public ExpectedException expectedException = ExpectedException.none();
|
||||
|
||||
@Mock
|
||||
Fetcher<String> fetcher;
|
||||
@Mock
|
||||
Persister<String> persister;
|
||||
|
||||
private final BarCode barCode = new BarCode("value", KEY);
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
when(fetcher.fetch(barCode))
|
||||
.thenReturn(Observable.just(source));
|
||||
|
||||
when(persister.read(barCode))
|
||||
.thenReturn(Observable.<String>empty())
|
||||
.thenReturn(Observable.just(source));
|
||||
|
||||
when(persister.write(barCode, source))
|
||||
.thenReturn(Observable.just(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultJacksonStringParser() {
|
||||
Store<Foo> store = ParsingStoreBuilder.<String, Foo>builder()
|
||||
.persister(persister)
|
||||
.fetcher(fetcher)
|
||||
.parser(JacksonParserFactory.createStringParser(Foo.class))
|
||||
.open();
|
||||
|
||||
Foo result = store.get(barCode).toBlocking().first();
|
||||
|
||||
validateFoo(result);
|
||||
|
||||
verify(fetcher, times(1)).fetch(barCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomJsonFactoryStringParser() {
|
||||
JsonFactory jsonFactory = new JsonFactory();
|
||||
|
||||
Parser<String, Foo> parser = JacksonParserFactory.createStringParser(jsonFactory, Foo.class);
|
||||
|
||||
Store<Foo> store = ParsingStoreBuilder.<String, Foo>builder()
|
||||
.persister(persister)
|
||||
.fetcher(fetcher)
|
||||
.parser(parser)
|
||||
.open();
|
||||
|
||||
Foo result = store.get(barCode).toBlocking().first();
|
||||
|
||||
validateFoo(result);
|
||||
|
||||
verify(fetcher, times(1)).fetch(barCode);
|
||||
}
|
||||
|
||||
private void validateFoo(Foo foo) {
|
||||
assertNotNull(foo);
|
||||
assertEquals(foo.number, 123);
|
||||
assertEquals(foo.string, "abc");
|
||||
assertEquals(foo.bars.size(), 2);
|
||||
assertEquals(foo.bars.get(0).string, "def");
|
||||
assertEquals(foo.bars.get(1).string, "ghi");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullJsonFactory() {
|
||||
expectedException.expect(NullPointerException.class);
|
||||
JacksonParserFactory.createStringParser((JsonFactory) null, Foo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullTypeWithValidJsonFactory() {
|
||||
expectedException.expect(NullPointerException.class);
|
||||
JacksonParserFactory.createStringParser(new JsonFactory(), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullObjectMapper() {
|
||||
expectedException.expect(NullPointerException.class);
|
||||
JacksonParserFactory.createStringParser((ObjectMapper) null, Foo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullType() {
|
||||
expectedException.expect(NullPointerException.class);
|
||||
JacksonParserFactory.createStringParser(null);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.nytimes.android.external.store.middleware.jackson.data;
|
||||
|
||||
public class Bar {
|
||||
public String string;
|
||||
|
||||
public Bar() {
|
||||
}
|
||||
|
||||
public Bar(String string) {
|
||||
this.string = string;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.nytimes.android.external.store.middleware.jackson.data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Foo {
|
||||
public int number;
|
||||
public String string;
|
||||
public List<Bar> bars;
|
||||
|
||||
public Foo() {
|
||||
}
|
||||
|
||||
public Foo(int number, String string, List<Bar> bars) {
|
||||
this.number = number;
|
||||
this.string = string;
|
||||
this.bars = bars;
|
||||
}
|
||||
}
|
|
@ -1 +1 @@
|
|||
include ':app', ':store', ':middleware', ':cache', ':filesystem', ':middleware-moshi'
|
||||
include ':app', ':store', ':middleware', ':cache', ':filesystem', ':middleware-moshi', ':middleware-jackson'
|
||||
|
|
Loading…
Reference in a new issue