From 1ee6eb4db42d79876870a28c574efd9e90a59cb5 Mon Sep 17 00:00:00 2001 From: amanarora12 Date: Tue, 28 Jun 2022 13:47:31 +0530 Subject: [PATCH 1/7] Remove unused classes --- .../java/com/serjltt/moshi/adapters/Data.java | 41 -- .../serjltt/moshi/adapters/DataFactories.java | 27 -- .../DeserializeOnlyAutoValueTest.java | 40 -- .../adapters/LazyAdaptersAutoValueTest.java | 65 --- .../adapters/LazyAdaptersRetrofitTest.java | 157 ------- .../adapters/LazyAdaptersRxJavaTest.java | 64 --- .../com/serjltt/moshi/adapters/Nullable.java | 5 - .../adapters/SerializeOnlyAutoValueTest.java | 40 -- .../adapters/TransientAutoValueTest.java | 53 --- .../DefaultOnDataMismatchAdapter.java | 73 ---- .../com/serjltt/moshi/adapters/ElementAt.java | 93 ----- .../moshi/adapters/ElementAtJsonAdapter.java | 56 --- .../serjltt/moshi/adapters/FallbackEnum.java | 69 --- .../adapters/FallbackEnumJsonAdapter.java | 68 --- .../serjltt/moshi/adapters/FilterNulls.java | 52 --- .../adapters/FilterNullsJsonAdapter.java | 45 -- .../serjltt/moshi/adapters/FirstElement.java | 80 ---- .../serjltt/moshi/adapters/LastElement.java | 65 --- .../adapters/LastElementJsonAdapter.java | 38 -- .../moshi/adapters/SerializeNulls.java | 60 --- .../serjltt/moshi/adapters/SerializeOnly.java | 44 -- .../moshi/adapters/SerializeOnlyNonEmpty.java | 70 ---- .../SerializeOnlyNonEmptyJsonAdapter.java | 51 --- .../com/serjltt/moshi/adapters/Transient.java | 44 -- .../com/serjltt/moshi/adapters/Wrapped.java | 150 ------- .../moshi/adapters/WrappedJsonAdapter.java | 129 ------ .../DefaultOnDataMismatchAdapterTest.java | 92 ---- .../adapters/ElementAtJsonAdapterTest.java | 203 --------- .../adapters/FallbackEnumJsonAdapterTest.java | 111 ----- .../adapters/FilterNullsJsonAdapterTest.java | 61 --- .../adapters/FirstElementJsonAdapterTest.java | 151 ------- .../adapters/LastElementJsonAdapterTest.java | 137 ------ .../SerializeNullsJsonAdapterTest.java | 92 ---- .../SerializeOnlyJsonAdapterTest.java | 56 --- .../SerializeOnlyNonEmptyJsonAdapterTest.java | 250 ----------- .../adapters/WrappedJsonAdapterTest.java | 392 ------------------ 36 files changed, 3224 deletions(-) delete mode 100644 src/integrationTest/java/com/serjltt/moshi/adapters/Data.java delete mode 100644 src/integrationTest/java/com/serjltt/moshi/adapters/DataFactories.java delete mode 100644 src/integrationTest/java/com/serjltt/moshi/adapters/DeserializeOnlyAutoValueTest.java delete mode 100644 src/integrationTest/java/com/serjltt/moshi/adapters/LazyAdaptersAutoValueTest.java delete mode 100644 src/integrationTest/java/com/serjltt/moshi/adapters/LazyAdaptersRetrofitTest.java delete mode 100644 src/integrationTest/java/com/serjltt/moshi/adapters/LazyAdaptersRxJavaTest.java delete mode 100644 src/integrationTest/java/com/serjltt/moshi/adapters/Nullable.java delete mode 100644 src/integrationTest/java/com/serjltt/moshi/adapters/SerializeOnlyAutoValueTest.java delete mode 100644 src/integrationTest/java/com/serjltt/moshi/adapters/TransientAutoValueTest.java delete mode 100644 src/main/java/com/serjltt/moshi/adapters/DefaultOnDataMismatchAdapter.java delete mode 100644 src/main/java/com/serjltt/moshi/adapters/ElementAt.java delete mode 100644 src/main/java/com/serjltt/moshi/adapters/ElementAtJsonAdapter.java delete mode 100644 src/main/java/com/serjltt/moshi/adapters/FallbackEnum.java delete mode 100644 src/main/java/com/serjltt/moshi/adapters/FallbackEnumJsonAdapter.java delete mode 100644 src/main/java/com/serjltt/moshi/adapters/FilterNulls.java delete mode 100644 src/main/java/com/serjltt/moshi/adapters/FilterNullsJsonAdapter.java delete mode 100644 src/main/java/com/serjltt/moshi/adapters/FirstElement.java delete mode 100644 src/main/java/com/serjltt/moshi/adapters/LastElement.java delete mode 100644 src/main/java/com/serjltt/moshi/adapters/LastElementJsonAdapter.java delete mode 100644 src/main/java/com/serjltt/moshi/adapters/SerializeNulls.java delete mode 100644 src/main/java/com/serjltt/moshi/adapters/SerializeOnly.java delete mode 100644 src/main/java/com/serjltt/moshi/adapters/SerializeOnlyNonEmpty.java delete mode 100644 src/main/java/com/serjltt/moshi/adapters/SerializeOnlyNonEmptyJsonAdapter.java delete mode 100644 src/main/java/com/serjltt/moshi/adapters/Transient.java delete mode 100644 src/main/java/com/serjltt/moshi/adapters/Wrapped.java delete mode 100644 src/main/java/com/serjltt/moshi/adapters/WrappedJsonAdapter.java delete mode 100644 src/unitTest/java/com/serjltt/moshi/adapters/DefaultOnDataMismatchAdapterTest.java delete mode 100644 src/unitTest/java/com/serjltt/moshi/adapters/ElementAtJsonAdapterTest.java delete mode 100644 src/unitTest/java/com/serjltt/moshi/adapters/FallbackEnumJsonAdapterTest.java delete mode 100644 src/unitTest/java/com/serjltt/moshi/adapters/FilterNullsJsonAdapterTest.java delete mode 100644 src/unitTest/java/com/serjltt/moshi/adapters/FirstElementJsonAdapterTest.java delete mode 100644 src/unitTest/java/com/serjltt/moshi/adapters/LastElementJsonAdapterTest.java delete mode 100644 src/unitTest/java/com/serjltt/moshi/adapters/SerializeNullsJsonAdapterTest.java delete mode 100644 src/unitTest/java/com/serjltt/moshi/adapters/SerializeOnlyJsonAdapterTest.java delete mode 100644 src/unitTest/java/com/serjltt/moshi/adapters/SerializeOnlyNonEmptyJsonAdapterTest.java delete mode 100644 src/unitTest/java/com/serjltt/moshi/adapters/WrappedJsonAdapterTest.java diff --git a/src/integrationTest/java/com/serjltt/moshi/adapters/Data.java b/src/integrationTest/java/com/serjltt/moshi/adapters/Data.java deleted file mode 100644 index a60ec0c..0000000 --- a/src/integrationTest/java/com/serjltt/moshi/adapters/Data.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2016 Serj Lotutovici - * - * 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 com.serjltt.moshi.adapters; - -import com.google.auto.value.AutoValue; -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.Moshi; - -/** Data class for testing auto-value-moshi integration. */ -@AutoValue -abstract class Data { - public static JsonAdapter jsonAdapter(Moshi moshi) { - return new AutoValue_Data.MoshiJsonAdapter(moshi); - } - - abstract String name(); - - /** - * The name of the method will be taken as the first key, then the path provided with the - * annotation. - */ - @Wrapped(path = {"1"}) abstract Meta meta(); - - static class Meta { - String value1; - int value2; - } -} diff --git a/src/integrationTest/java/com/serjltt/moshi/adapters/DataFactories.java b/src/integrationTest/java/com/serjltt/moshi/adapters/DataFactories.java deleted file mode 100644 index ba9aa0f..0000000 --- a/src/integrationTest/java/com/serjltt/moshi/adapters/DataFactories.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2016 Serj Lotutovici - * - * 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 com.serjltt.moshi.adapters; - -import com.ryanharter.auto.value.moshi.MoshiAdapterFactory; -import com.squareup.moshi.JsonAdapter; - -/** Provided the factory for generated adapters. */ -@MoshiAdapterFactory -abstract class DataFactories implements JsonAdapter.Factory { - public static JsonAdapter.Factory create() { - return new AutoValueMoshi_DataFactories(); - } -} diff --git a/src/integrationTest/java/com/serjltt/moshi/adapters/DeserializeOnlyAutoValueTest.java b/src/integrationTest/java/com/serjltt/moshi/adapters/DeserializeOnlyAutoValueTest.java deleted file mode 100644 index deb408f..0000000 --- a/src/integrationTest/java/com/serjltt/moshi/adapters/DeserializeOnlyAutoValueTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.serjltt.moshi.adapters; - -import com.google.auto.value.AutoValue; -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.Moshi; -import java.io.IOException; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public final class DeserializeOnlyAutoValueTest { - private final Moshi moshi = new Moshi.Builder() - .add(DeserializeOnly.ADAPTER_FACTORY) - .add(DataFactories.create()) - .build(); - - @Test public void serialize() { - final String json = AutoValueClass.jsonAdapter(moshi) - .toJson(new AutoValue_DeserializeOnlyAutoValueTest_AutoValueClass(1, 2)); - assertThat(json).isEqualTo("{\"foo\":1}"); - } - - @Test public void deserialize() throws IOException { - final AutoValueClass autoValueClass = - AutoValueClass.jsonAdapter(moshi).fromJson("{\"foo\": 1,\"bar\": 2}"); - - assertThat(autoValueClass.foo()).isEqualTo(1); - assertThat(autoValueClass.bar()).isEqualTo(2); - } - - @AutoValue abstract static class AutoValueClass { - public static JsonAdapter jsonAdapter(Moshi moshi) { - return new AutoValue_DeserializeOnlyAutoValueTest_AutoValueClass.MoshiJsonAdapter(moshi); - } - - abstract Integer foo(); - - @DeserializeOnly abstract Integer bar(); - } -} diff --git a/src/integrationTest/java/com/serjltt/moshi/adapters/LazyAdaptersAutoValueTest.java b/src/integrationTest/java/com/serjltt/moshi/adapters/LazyAdaptersAutoValueTest.java deleted file mode 100644 index d05df38..0000000 --- a/src/integrationTest/java/com/serjltt/moshi/adapters/LazyAdaptersAutoValueTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2016 Serj Lotutovici - * - * 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 com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.Moshi; -import java.util.Collections; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** Test all lazy adapters to work in integration with AutoValue extensions. */ -public class LazyAdaptersAutoValueTest { - private final Moshi moshi = new Moshi.Builder() - .add(Wrapped.ADAPTER_FACTORY) - .add(DataFactories.create()) - .build(); - - @Test public void unwrap() throws Exception { - JsonAdapter adapter = moshi.adapter(Data.class); - - Data fromJson = adapter.fromJson("{\n" - + " \"name\": \"data_name\",\n" - + " \"meta\": {\n" - + " \"1\": {\n" - + " \"value1\": \"value1\",\n" - + " \"value2\": 2\n" - + " }\n" - + " }\n" - + "}"); - - assertThat(fromJson.name()).isEqualTo("data_name"); - assertThat(fromJson.meta().value1).isEqualTo("value1"); - assertThat(fromJson.meta().value2).isEqualTo(2); - } - - @Test - public void wrap() throws Exception { - JsonAdapter adapter = moshi.adapter(Data.class, - Collections.singleton(Wrapped.Factory.create("foo"))); - - Data.Meta meta = new Data.Meta(); - meta.value1 = "value1"; - meta.value2 = 2; - Data data = new AutoValue_Data("data_name", meta); - - String toJson = adapter.toJson(data); - assertThat(toJson).isEqualTo( - "{\"foo\":{\"name\":\"data_name\"," - + "\"meta\":{\"1\":{\"value1\":\"value1\",\"value2\":2}}}}"); - } -} diff --git a/src/integrationTest/java/com/serjltt/moshi/adapters/LazyAdaptersRetrofitTest.java b/src/integrationTest/java/com/serjltt/moshi/adapters/LazyAdaptersRetrofitTest.java deleted file mode 100644 index f7cff68..0000000 --- a/src/integrationTest/java/com/serjltt/moshi/adapters/LazyAdaptersRetrofitTest.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2016 Serj Lotutovici - * - * 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 com.serjltt.moshi.adapters; - -import com.squareup.moshi.Json; -import com.squareup.moshi.Moshi; -import java.io.IOException; -import okhttp3.ResponseBody; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import okhttp3.mockwebserver.RecordedRequest; -import org.junit.Rule; -import org.junit.Test; -import retrofit2.Call; -import retrofit2.Response; -import retrofit2.Retrofit; -import retrofit2.converter.moshi.MoshiConverterFactory; -import retrofit2.http.Body; -import retrofit2.http.GET; -import retrofit2.http.POST; - -import static org.assertj.core.api.Assertions.assertThat; - -/** Test all lazy adapters to work in integration with retrofit. */ -public final class LazyAdaptersRetrofitTest { - @Rule public final MockWebServer server = new MockWebServer(); - - private final Moshi moshi = new Moshi.Builder() - .add(Wrapped.ADAPTER_FACTORY) - .add(FirstElement.ADAPTER_FACTORY) - .add(ElementAt.ADAPTER_FACTORY) - .build(); - - private final Retrofit retrofit = new Retrofit.Builder() - .addConverterFactory(MoshiConverterFactory.create(moshi)) - .baseUrl(server.url("/")) - .build(); - - private final Service service = retrofit.create(Service.class); - - @Test public void unwrapJsonAdapter() throws Exception { - assertResponse(service.unwrap(), "{\n" - + " \"one\": {\n" - + " \"two\": \"works!\"\n" - + " }\n" - + "}", "works!"); - } - - @Test public void unwrapNestedJsonAdapter() throws Exception { - server.enqueue(new MockResponse().setBody("{\n" - + " \"one\": {\n" - + " \"two\": {\n" - + " \"item\": {\n" - + " \"foo\": \"this\"\n" - + " },\n" - + " \"item2\": {\n" - + " \"bar\": 1234\n" - + " },\n" - + " \"foobar\": 567\n" - + " }\n" - + " }\n" - + "}")); - - Response response = service.unwrapNested().execute(); - - assertThat(response.body().foobar).isEqualTo(567); - assertThat(response.body().foo).isEqualTo("this"); - assertThat(response.body().bar).isEqualTo(1234); - } - - @Test public void wrapPostBody() throws Exception { - server.enqueue(new MockResponse()); - - Call call = service.wrappedPost("one"); - call.execute(); - - RecordedRequest recorded = server.takeRequest(); - assertThat(recorded.getBody() - .readUtf8()) - .isEqualTo("{\"1\":{\"2\":\"one\"}}"); - } - - @Test public void firstElementJsonAdapter() throws Exception { - assertResponse(service.firstElement(), "[\n" - + " \"expected\",\n" - + " \"ignored\"\n" - + "]", "expected"); - } - - @Test public void elementAtJsonAdapter() throws Exception { - assertResponse(service.elementAt(), "[\n" - + " \"one\",\n" - + " \"two\",\n" - + " \"three\"\n" - + "]", "three"); - } - - @Test public void unwrapFirstElement() throws Exception { - assertResponse(service.unwrapFirstElement(), "{\n" - + " \"one\": {\n" - + " \"two\": [\n" - + " \"first\"\n" - + " ]\n" - + " }\n" - + "}", "first"); - } - - private void assertResponse(Call call, String input, T expected) throws IOException { - server.enqueue(new MockResponse().setBody(input)); - - Response response = call.execute(); - assertThat(response.body()).isEqualTo(expected); - } - - /** Test service for all lazy adapters. */ - private interface Service { - /** Helps to test the unwrap adapter. */ - @GET("/") - @Wrapped(path = {"one", "two"}) Call unwrap(); - - @GET("/") - @Wrapped(path = {"one", "two"}) Call unwrapNested(); - - @POST("/") Call wrappedPost(@Body @Wrapped(path = {"1", "2"}) String value); - - /** Helps to test the first element json adapter. */ - @GET("/") - @FirstElement Call firstElement(); - - /** Helps to test the first element json adapter. */ - @GET("/") - @Wrapped(path = {"one", "two"}) - @FirstElement Call unwrapFirstElement(); - - @GET("/") - @ElementAt(index = 2) Call elementAt(); - } - - static class Nested { - @Json(name = "item") @Wrapped(path = "foo") String foo; - @Json(name = "item2") @Wrapped(path = "bar") int bar; - int foobar; - } -} diff --git a/src/integrationTest/java/com/serjltt/moshi/adapters/LazyAdaptersRxJavaTest.java b/src/integrationTest/java/com/serjltt/moshi/adapters/LazyAdaptersRxJavaTest.java deleted file mode 100644 index 701da3e..0000000 --- a/src/integrationTest/java/com/serjltt/moshi/adapters/LazyAdaptersRxJavaTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonDataException; -import com.squareup.moshi.Moshi; -import io.reactivex.Flowable; -import io.reactivex.Maybe; -import io.reactivex.Observable; -import io.reactivex.Single; -import io.reactivex.observers.BaseTestConsumer; -import java.lang.annotation.Annotation; -import java.util.Collections; -import java.util.Set; -import java.util.concurrent.Callable; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -/** Tests if specific adapters behave properly with RxJava2. */ -@RunWith(Parameterized.class) -public final class LazyAdaptersRxJavaTest { - private static final Moshi MOSHI = new Moshi.Builder() - .add(Wrapped.ADAPTER_FACTORY) - .build(); - - private static Callable failingCallable() { - Set annotations = - Collections.singleton(Wrapped.Factory.create(true, "one", "two", "three")); - final JsonAdapter adapter = MOSHI.adapter(String.class, annotations); - - return new Callable() { - @Override public String call() throws Exception { - return adapter.fromJson("{\n" - + " \"one\": {\n" - + " \"two\": null\n" - + " }\n" - + "}"); - } - }; - } - - @Parameterized.Parameters - public static BaseTestConsumer[] testData() { - return new BaseTestConsumer[] { - Single.fromCallable(failingCallable()).test(), - Observable.fromCallable(failingCallable()).test(), - Maybe.fromCallable(failingCallable()).test(), - Flowable.fromCallable(failingCallable()).test() - }; - } - - private final BaseTestConsumer testConsumer; - - public LazyAdaptersRxJavaTest(BaseTestConsumer testConsumer) { - this.testConsumer = testConsumer; - } - - @Test public void reactiveTypeYieldsAppropriateError() throws Exception { - //noinspection unchecked - testConsumer - .assertFailureAndMessage(JsonDataException.class, - "Wrapped Json expected at path: [one, two, three]. Found null at $.one.two"); - } -} diff --git a/src/integrationTest/java/com/serjltt/moshi/adapters/Nullable.java b/src/integrationTest/java/com/serjltt/moshi/adapters/Nullable.java deleted file mode 100644 index 3578062..0000000 --- a/src/integrationTest/java/com/serjltt/moshi/adapters/Nullable.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.serjltt.moshi.adapters; - -/** For testing purposes. */ -public @interface Nullable { -} diff --git a/src/integrationTest/java/com/serjltt/moshi/adapters/SerializeOnlyAutoValueTest.java b/src/integrationTest/java/com/serjltt/moshi/adapters/SerializeOnlyAutoValueTest.java deleted file mode 100644 index cd10d38..0000000 --- a/src/integrationTest/java/com/serjltt/moshi/adapters/SerializeOnlyAutoValueTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.serjltt.moshi.adapters; - -import com.google.auto.value.AutoValue; -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.Moshi; -import java.io.IOException; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public final class SerializeOnlyAutoValueTest { - private final Moshi moshi = new Moshi.Builder() - .add(SerializeOnly.ADAPTER_FACTORY) - .add(DataFactories.create()) - .build(); - - @Test public void serialize() { - final String json = AutoValueClass.jsonAdapter(moshi) - .toJson(new AutoValue_SerializeOnlyAutoValueTest_AutoValueClass(1, 2)); - assertThat(json).isEqualTo("{\"foo\":1,\"bar\":2}"); - } - - @Test public void deserialize() throws IOException { - final AutoValueClass autoValueClass = - AutoValueClass.jsonAdapter(moshi).fromJson("{\"foo\": 1,\"bar\": 2}"); - - assertThat(autoValueClass.foo()).isEqualTo(1); - assertThat(autoValueClass.bar()).isNull(); - } - - @AutoValue abstract static class AutoValueClass { - public static JsonAdapter jsonAdapter(Moshi moshi) { - return new AutoValue_SerializeOnlyAutoValueTest_AutoValueClass.MoshiJsonAdapter(moshi); - } - - abstract Integer foo(); - - @SerializeOnly @Nullable abstract Integer bar(); - } -} diff --git a/src/integrationTest/java/com/serjltt/moshi/adapters/TransientAutoValueTest.java b/src/integrationTest/java/com/serjltt/moshi/adapters/TransientAutoValueTest.java deleted file mode 100644 index 41a44dc..0000000 --- a/src/integrationTest/java/com/serjltt/moshi/adapters/TransientAutoValueTest.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.serjltt.moshi.adapters; - -import com.google.auto.value.AutoValue; -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.Moshi; -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.util.Collections; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public final class TransientAutoValueTest { - private final Moshi moshi = new Moshi.Builder() - .add(Transient.ADAPTER_FACTORY) - .add(DataFactories.create()) - .build(); - - @Test public void serialize() { - final String json = AutoValueClass.jsonAdapter(moshi) - .toJson(new AutoValue_TransientAutoValueTest_AutoValueClass(1, 2)); - assertThat(json).isEqualTo("{\"foo\":1}"); - } - - @Test public void deserialize() throws IOException { - final AutoValueClass autoValueClass = - AutoValueClass.jsonAdapter(moshi).fromJson("{\"foo\": 1,\"bar\": 2}"); - - assertThat(autoValueClass.foo()).isEqualTo(1); - assertThat(autoValueClass.bar()).isNull(); - } - - @Test public void toStringReflectsInnerAdapter() throws Exception { - JsonAdapter adapter = - moshi.adapter(String.class, Collections.singleton(new SerializeOnly() { - @Override public Class annotationType() { - return Transient.class; - } - })); - - assertThat(adapter.toString()).isEqualTo("JsonAdapter(String).nullSafe().transient()"); - } - - @AutoValue abstract static class AutoValueClass { - public static JsonAdapter jsonAdapter(Moshi moshi) { - return new AutoValue_TransientAutoValueTest_AutoValueClass.MoshiJsonAdapter(moshi); - } - - abstract Integer foo(); - - @Transient @Nullable abstract Integer bar(); - } -} diff --git a/src/main/java/com/serjltt/moshi/adapters/DefaultOnDataMismatchAdapter.java b/src/main/java/com/serjltt/moshi/adapters/DefaultOnDataMismatchAdapter.java deleted file mode 100644 index 9c965b7..0000000 --- a/src/main/java/com/serjltt/moshi/adapters/DefaultOnDataMismatchAdapter.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2017 Square, Inc. - * - * 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 com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonDataException; -import com.squareup.moshi.JsonReader; -import com.squareup.moshi.JsonWriter; -import com.squareup.moshi.Moshi; -import com.squareup.moshi.Types; -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; -import java.util.Set; - -/** - * Adapter that fallbacks to a default value in case there's a mismatch. - */ -public final class DefaultOnDataMismatchAdapter extends JsonAdapter { - private final JsonAdapter delegate; - private final T defaultValue; - - DefaultOnDataMismatchAdapter(JsonAdapter delegate, T defaultValue) { - this.delegate = delegate; - this.defaultValue = defaultValue; - } - - @Override public T fromJson(JsonReader reader) throws IOException { - Object jsonValue = reader.readJsonValue(); - - try { - return delegate.fromJsonValue(jsonValue); - } catch (JsonDataException ignore) { - return defaultValue; - } - } - - @Override public void toJson(JsonWriter writer, T value) throws IOException { - delegate.toJson(writer, value); - } - - @Override public String toString() { - return delegate + ".defaultOnDatMisMatch(" + defaultValue + ')'; - } - - /** Builds an adapter that fallbacks to a default value in case there's a mismatch. */ - public static JsonAdapter.Factory newFactory(final Type type, final T defaultValue) { - return new Factory() { - @Override public JsonAdapter create(Type requestedType, - Set annotations, Moshi moshi) { - if (Types.equals(type, requestedType)) { - JsonAdapter delegate = moshi.nextAdapter(this, type, annotations); - return new DefaultOnDataMismatchAdapter<>(delegate, defaultValue); - } - - return null; - } - }; - } -} diff --git a/src/main/java/com/serjltt/moshi/adapters/ElementAt.java b/src/main/java/com/serjltt/moshi/adapters/ElementAt.java deleted file mode 100644 index aa9ebba..0000000 --- a/src/main/java/com/serjltt/moshi/adapters/ElementAt.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2016 Serj Lotutovici - * - * 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 com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonQualifier; -import com.squareup.moshi.Moshi; -import java.lang.annotation.Annotation; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Type; -import java.util.Set; - -import static com.serjltt.moshi.adapters.Util.nextAnnotations; - -/** - * Indicates that the annotated type/field is expected to be the element - * at the given index of a json array. - * - *

For example if a json object is: - *

- *   [
- *    {
- *      "some_field": "some_value",
- *      "other_field": "other_value"
- *    },
- *    {
- *      "some_field": "some_value_2",
- *      "other_field": "other_value_2"
- *    }
- *   ]
- * 
- * And the consumer only cares about the second element, if using retrofit a service method would - * look like: - * - *

- *   {@literal @}GET("path/")
- *   {@literal @}ElementAt(index = 1) Call<DataObject> getData();
- * 
- * - * The resulting response returned by {@code response.body()} will be an instance of {@code - * DataObject} with the respective values set. - * - *

To leverage from {@link ElementAt} {@link ElementAt#ADAPTER_FACTORY} - * must be added to your {@linkplain Moshi Moshi instance}: - * - *


- *   Moshi moshi = new Moshi.Builder()
- *      .add(ElementAt.ADAPTER_FACTORY)
- *      .build();
- * 
- */ -@Documented -@JsonQualifier -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE }) -public @interface ElementAt { - /** - * Represents the index location at which the element will be expected to be. - * If the size of the array will be less then the provided index, - * the companion adapter will return {@code null}. - */ - int index(); - - /** Builds an adapter that can process a types annotated with {@link ElementAt}. */ - JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() { - @Override public JsonAdapter create(Type type, Set annotations, - Moshi moshi) { - Pair> nextAnnotations = - nextAnnotations(annotations, ElementAt.class); - if (nextAnnotations == null || !nextAnnotations.second.isEmpty()) return null; - - return new ElementAtJsonAdapter<>(type, moshi, nextAnnotations.first.index()); - } - }; -} diff --git a/src/main/java/com/serjltt/moshi/adapters/ElementAtJsonAdapter.java b/src/main/java/com/serjltt/moshi/adapters/ElementAtJsonAdapter.java deleted file mode 100644 index c26253e..0000000 --- a/src/main/java/com/serjltt/moshi/adapters/ElementAtJsonAdapter.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2016 Serj Lotutovici - * - * 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 com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonReader; -import com.squareup.moshi.JsonWriter; -import com.squareup.moshi.Moshi; -import com.squareup.moshi.Types; -import java.io.IOException; -import java.lang.reflect.Type; -import java.util.Collections; -import java.util.List; - -/** - * {@linkplain JsonAdapter} that extracts the element at the given index - * of an array of (a field) type annotated with {@linkplain ElementAt}. - */ -final class ElementAtJsonAdapter extends JsonAdapter { - private final JsonAdapter> delegate; - private final int index; - - ElementAtJsonAdapter(Type type, Moshi moshi, int index) { - Type listType = Types.newParameterizedType(List.class, type); - delegate = moshi.adapter(listType); - this.index = index; - } - - @Override public T fromJson(JsonReader reader) throws IOException { - List fromJson = delegate.fromJson(reader); - if (fromJson != null && index < fromJson.size()) return fromJson.get(index); - return null; - } - - @Override public void toJson(JsonWriter writer, T value) throws IOException { - delegate.toJson(writer, Collections.singletonList(value)); - } - - @Override public String toString() { - return delegate + ".elementAt(" + index + ")"; - } -} diff --git a/src/main/java/com/serjltt/moshi/adapters/FallbackEnum.java b/src/main/java/com/serjltt/moshi/adapters/FallbackEnum.java deleted file mode 100644 index 0f4f284..0000000 --- a/src/main/java/com/serjltt/moshi/adapters/FallbackEnum.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2016 Serj Lotutovici - * - * 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 com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.Moshi; -import com.squareup.moshi.Types; -import java.lang.annotation.Annotation; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Type; -import java.util.Set; - -/** - * Indicates that the annotated enum has a fallback value. The fallback must be set via - * {@link #name()}. If no enum constant with the provided name is declared in the annotated - * enum type an {@linkplain AssertionError assertion error} will be thrown. - * - *

To leverage from {@link FallbackEnum} {@link FallbackEnum#ADAPTER_FACTORY} must be added to - * your {@linkplain Moshi moshi instance}: - * - *


- *   Moshi moshi = new Moshi.Builder()
- *      .add(FallbackEnum.ADAPTER_FACTORY)
- *      .build();
- * 
- */ -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface FallbackEnum { - String name(); - - /** Builds an adapter that can process enums annotated with {@link FallbackEnum}. */ - JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() { - @Override public JsonAdapter create(Type type, Set annotations, - Moshi moshi) { - if (!annotations.isEmpty()) return null; - - Class rawType = Types.getRawType(type); - if (rawType.isEnum()) { - FallbackEnum annotation = rawType.getAnnotation(FallbackEnum.class); - if (annotation == null) return null; - - //noinspection unchecked - return new FallbackEnumJsonAdapter<>((Class) rawType, annotation.name()) - .nullSafe(); - } - - return null; - } - }; -} diff --git a/src/main/java/com/serjltt/moshi/adapters/FallbackEnumJsonAdapter.java b/src/main/java/com/serjltt/moshi/adapters/FallbackEnumJsonAdapter.java deleted file mode 100644 index 771cd86..0000000 --- a/src/main/java/com/serjltt/moshi/adapters/FallbackEnumJsonAdapter.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2016 Serj Lotutovici - * Copyright (C) 2014 Square, Inc. - * - * 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 com.serjltt.moshi.adapters; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonReader; -import com.squareup.moshi.JsonWriter; -import java.io.IOException; - -/** - * {@linkplain JsonAdapter} that fallbacks to a default enum constant declared in the enum type - * annotated with {@linkplain FallbackEnum}. - */ -final class FallbackEnumJsonAdapter> extends JsonAdapter { - private final Class enumType; - private final String[] nameStrings; - private final T[] constants; - private final JsonReader.Options options; - private final T fallbackConstant; - - FallbackEnumJsonAdapter(Class enumType, String fallback) { - fallbackConstant = Enum.valueOf(enumType, fallback); - this.enumType = enumType; - try { - constants = enumType.getEnumConstants(); - nameStrings = new String[constants.length]; - for (int i = 0; i < constants.length; i++) { - T constant = constants[i]; - Json annotation = enumType.getField(constant.name()).getAnnotation(Json.class); - String name = annotation != null ? annotation.name() : constant.name(); - nameStrings[i] = name; - } - options = JsonReader.Options.of(nameStrings); - } catch (NoSuchFieldException e) { - throw new AssertionError(e); - } - } - - @Override public T fromJson(JsonReader reader) throws IOException { - int index = reader.selectString(options); - if (index != -1) return constants[index]; - reader.nextString(); - return fallbackConstant; - } - - @Override public void toJson(JsonWriter writer, T value) throws IOException { - writer.value(nameStrings[value.ordinal()]); - } - - @Override public String toString() { - return "JsonAdapter(" + enumType.getName() + ").fallbackEnum(" + fallbackConstant + ")"; - } -} diff --git a/src/main/java/com/serjltt/moshi/adapters/FilterNulls.java b/src/main/java/com/serjltt/moshi/adapters/FilterNulls.java deleted file mode 100644 index c4d7a14..0000000 --- a/src/main/java/com/serjltt/moshi/adapters/FilterNulls.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonQualifier; -import com.squareup.moshi.Moshi; -import com.squareup.moshi.Types; -import java.lang.annotation.Annotation; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Type; -import java.util.Collection; -import java.util.Set; - -/** - * Indicates that the annotated field may not contain any null values. - * This annotation is applicable to all Collections. - * - *

To leverage from {@link FilterNulls} {@link FilterNulls#ADAPTER_FACTORY} must be - * added to your {@linkplain Moshi Moshi instance}: - * - *


- *   Moshi moshi = new Moshi.Builder()
- *      .add(FilterNulls.ADAPTER_FACTORY)
- *      .build();
- * 
- */ -@Documented -@JsonQualifier -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.FIELD, ElementType.METHOD }) -public @interface FilterNulls { - /** Builds an adapter that can process types annotated with {@link FilterNulls}. */ - JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() { - @Override public JsonAdapter create(Type type, Set annotations, - Moshi moshi) { - Set nextAnnotations = - Types.nextAnnotations(annotations, FilterNulls.class); - if (nextAnnotations == null || !nextAnnotations.isEmpty()) return null; - - Class rawType = Types.getRawType(type); - - if (Collection.class.isAssignableFrom(rawType)) { - return new FilterNullsJsonAdapter<>(moshi.adapter(type, nextAnnotations)); - } - - return null; - } - }; -} diff --git a/src/main/java/com/serjltt/moshi/adapters/FilterNullsJsonAdapter.java b/src/main/java/com/serjltt/moshi/adapters/FilterNullsJsonAdapter.java deleted file mode 100644 index 707b8a8..0000000 --- a/src/main/java/com/serjltt/moshi/adapters/FilterNullsJsonAdapter.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonReader; -import com.squareup.moshi.JsonWriter; -import java.io.IOException; -import java.util.Collection; -import java.util.Iterator; - -/** - * {@link JsonAdapter} that filters null values out. - */ -final class FilterNullsJsonAdapter extends JsonAdapter { - private final JsonAdapter delegate; - - FilterNullsJsonAdapter(JsonAdapter delegate) { - this.delegate = delegate; - } - - @Override public T fromJson(JsonReader reader) throws IOException { - return removeNulls(delegate.fromJson(reader)); - } - - @Override public void toJson(JsonWriter writer, T value) throws IOException { - delegate.toJson(writer, removeNulls(value)); - } - - @Override public String toString() { - return delegate + ".filterNulls()"; - } - - private T removeNulls(final T value) { - if (value != null) { - final Iterator it = ((Collection) value).iterator(); - - while (it.hasNext()) { - if (it.next() == null) { - it.remove(); - } - } - } - - return value; - } -} diff --git a/src/main/java/com/serjltt/moshi/adapters/FirstElement.java b/src/main/java/com/serjltt/moshi/adapters/FirstElement.java deleted file mode 100644 index b1751c6..0000000 --- a/src/main/java/com/serjltt/moshi/adapters/FirstElement.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2016 Serj Lotutovici - * - * 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 com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonQualifier; -import com.squareup.moshi.Moshi; -import com.squareup.moshi.Types; -import java.lang.annotation.Annotation; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Type; -import java.util.Set; - -/** - * Indicates that the annotated type/field is expected to be the first element of a - * json array. - * - *

For example if a json object is returned as: - *

- *   [
- *    {
- *      "some_field": "some_value",
- *      "other_field": "other_value"
- *    }
- *   ]
- * 
- * And the consumer only cares about the actual element, in the case of using a retrofit service - * method the code would look like: - * - *

- *   {@literal @}GET("path/")
- *   {@literal @}FirstElement Call<DataObject> getData();
- * 
- * - * The resulting response returned by {@code response.body()} will be an instance of {@code - * DataObject} with the respective values set. - * - *

To leverage from {@link FirstElement} {@linkplain FirstElement#ADAPTER_FACTORY} - * must be added to a {@linkplain Moshi Moshi instance}: - * - *


- *   Moshi moshi = new Moshi.Builder()
- *      .add(FirstElement.ADAPTER_FACTORY)
- *      .build();
- * 
- */ -@Documented -@JsonQualifier -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.FIELD, ElementType.METHOD }) -public @interface FirstElement { - /** Builds an adapter that can process a types annotated with {@link FirstElement}. */ - JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() { - @Override public JsonAdapter create(Type type, Set annotations, - Moshi moshi) { - Set nextAnnotations = - Types.nextAnnotations(annotations, FirstElement.class); - if (nextAnnotations == null || !nextAnnotations.isEmpty()) return null; - - return new ElementAtJsonAdapter<>(type, moshi, 0); - } - }; -} diff --git a/src/main/java/com/serjltt/moshi/adapters/LastElement.java b/src/main/java/com/serjltt/moshi/adapters/LastElement.java deleted file mode 100644 index 37168d4..0000000 --- a/src/main/java/com/serjltt/moshi/adapters/LastElement.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonQualifier; -import com.squareup.moshi.Moshi; -import com.squareup.moshi.Types; -import java.lang.annotation.Annotation; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Type; -import java.util.Set; - -/** - * Indicates that the annotated type/field is expected to be the last element of a - * json array. - * - *

For example if a json object is returned as: - *

- *   [
- *    {
- *      "some_field": "some_value",
- *      "other_field": "other_value"
- *    }
- *   ]
- * 
- * And the consumer only cares about the last element, in the case of using a retrofit service - * method the code would look like: - * - *

- *   {@literal @}GET("path/")
- *   {@literal @}LastElement Call<DataObject> getData();
- * 
- * - * The resulting response returned by {@code response.body()} will be an instance of {@code - * DataObject} with the respective values set. - * - *

To leverage from {@link LastElement} {@linkplain LastElement#ADAPTER_FACTORY} - * must be added to a {@linkplain Moshi Moshi instance}: - * - *


- *   Moshi moshi = new Moshi.Builder()
- *      .add(LastElement.ADAPTER_FACTORY)
- *      .build();
- * 
- */ -@Documented -@JsonQualifier -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.FIELD, ElementType.METHOD }) -public @interface LastElement { - /** Builds an adapter that can process a type/field annotated with {@link LastElement}. */ - JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() { - @Override public JsonAdapter create(Type type, Set annotations, - Moshi moshi) { - Set nextAnnotations = - Types.nextAnnotations(annotations, LastElement.class); - if (nextAnnotations == null || !nextAnnotations.isEmpty()) return null; - - return new LastElementJsonAdapter<>(type, moshi); - } - }; -} diff --git a/src/main/java/com/serjltt/moshi/adapters/LastElementJsonAdapter.java b/src/main/java/com/serjltt/moshi/adapters/LastElementJsonAdapter.java deleted file mode 100644 index af5c1cb..0000000 --- a/src/main/java/com/serjltt/moshi/adapters/LastElementJsonAdapter.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonReader; -import com.squareup.moshi.JsonWriter; -import com.squareup.moshi.Moshi; -import com.squareup.moshi.Types; -import java.io.IOException; -import java.lang.reflect.Type; -import java.util.Collections; -import java.util.List; - -/** - * {@linkplain JsonAdapter} that extracts the last element - * of an array of (a field) type or a method annotated with {@linkplain LastElement}. - */ -final class LastElementJsonAdapter extends JsonAdapter { - private final JsonAdapter> delegate; - - LastElementJsonAdapter(Type type, Moshi moshi) { - Type listType = Types.newParameterizedType(List.class, type); - delegate = moshi.adapter(listType); - } - - @Override public T fromJson(JsonReader reader) throws IOException { - List fromJson = delegate.fromJson(reader); - if (fromJson != null && !fromJson.isEmpty()) return fromJson.get(fromJson.size() - 1); - return null; - } - - @Override public void toJson(JsonWriter writer, T value) throws IOException { - delegate.toJson(writer, Collections.singletonList(value)); - } - - @Override public String toString() { - return delegate + ".lastElement()"; - } -} diff --git a/src/main/java/com/serjltt/moshi/adapters/SerializeNulls.java b/src/main/java/com/serjltt/moshi/adapters/SerializeNulls.java deleted file mode 100644 index 9e873b9..0000000 --- a/src/main/java/com/serjltt/moshi/adapters/SerializeNulls.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2016 Serj Lotutovici - * - * 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 com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonQualifier; -import com.squareup.moshi.Moshi; -import com.squareup.moshi.Types; -import java.lang.annotation.Annotation; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Type; -import java.util.Set; - -/** - * Indicates that the annotated type/field should be serialized as {@code null} in case of a - * empty/null value. - * - *

To leverage from {@link SerializeNulls} {@link SerializeNulls#ADAPTER_FACTORY} - * must be added to a {@linkplain Moshi Moshi instance}: - * - *


- *   Moshi moshi = new Moshi.Builder()
- *      .add(SerializeNulls.ADAPTER_FACTORY)
- *      .build();
- * 
- */ -@Documented -@JsonQualifier -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.FIELD, ElementType.METHOD }) -public @interface SerializeNulls { - /** Builds an adapter that can process a types annotated with {@link SerializeNulls}. */ - JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() { - @Override public JsonAdapter create(Type type, Set annotations, - Moshi moshi) { - Set nextAnnotations = - Types.nextAnnotations(annotations, SerializeNulls.class); - if (nextAnnotations == null) return null; - - return moshi.adapter(type, nextAnnotations).serializeNulls(); - } - }; -} diff --git a/src/main/java/com/serjltt/moshi/adapters/SerializeOnly.java b/src/main/java/com/serjltt/moshi/adapters/SerializeOnly.java deleted file mode 100644 index 3dff1cc..0000000 --- a/src/main/java/com/serjltt/moshi/adapters/SerializeOnly.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonQualifier; -import com.squareup.moshi.Moshi; -import com.squareup.moshi.Types; -import java.lang.annotation.Annotation; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Type; -import java.util.Set; - -/** - * Indicates that the annotated field may only be serialized. - * - *

To leverage from {@link SerializeOnly} {@link SerializeOnly#ADAPTER_FACTORY} must be added - * to your {@linkplain Moshi Moshi instance}: - * - *


- *   Moshi moshi = new Moshi.Builder()
- *      .add(SerializeOnly.ADAPTER_FACTORY)
- *      .build();
- * 
- */ -@Documented -@JsonQualifier -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.FIELD, ElementType.METHOD }) -public @interface SerializeOnly { - /** Builds an adapter that can process a types annotated with {@link SerializeOnly}. */ - JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() { - @Override public JsonAdapter create(Type type, Set annotations, - Moshi moshi) { - Set nextAnnotations = - Types.nextAnnotations(annotations, SerializeOnly.class); - if (nextAnnotations == null) return null; - - return new TransientJsonAdapter<>(moshi.adapter(type, nextAnnotations), true, false); - } - }; -} diff --git a/src/main/java/com/serjltt/moshi/adapters/SerializeOnlyNonEmpty.java b/src/main/java/com/serjltt/moshi/adapters/SerializeOnlyNonEmpty.java deleted file mode 100644 index 8e40204..0000000 --- a/src/main/java/com/serjltt/moshi/adapters/SerializeOnlyNonEmpty.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2016 Serj Lotutovici - * - * 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 com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonQualifier; -import com.squareup.moshi.Moshi; -import com.squareup.moshi.Types; -import java.lang.annotation.Annotation; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Type; -import java.util.Collection; -import java.util.Map; -import java.util.Set; - -/** - * Indicates that the annotated type/field should not be serialized in case of an - * empty value. - * - *

To leverage from {@link SerializeOnlyNonEmpty} {@link SerializeOnlyNonEmpty#ADAPTER_FACTORY} - * must be added to your {@linkplain Moshi Moshi instance}: - * - *


- *   Moshi moshi = new Moshi.Builder()
- *      .add(SerializeOnlyNonEmpty.ADAPTER_FACTORY)
- *      .build();
- * 
- */ -@Documented -@JsonQualifier -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.FIELD, ElementType.METHOD }) -public @interface SerializeOnlyNonEmpty { - /** Builds an adapter that can process a types annotated with {@link SerializeOnlyNonEmpty}. */ - JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() { - @Override public JsonAdapter create(Type type, Set annotations, - Moshi moshi) { - Set nextAnnotations = - Types.nextAnnotations(annotations, SerializeOnlyNonEmpty.class); - if (nextAnnotations == null) return null; - - Class rawType = Types.getRawType(type); - - if (rawType.isArray() || Collection.class.isAssignableFrom(rawType) - || Map.class.isAssignableFrom(rawType)) { - return new SerializeOnlyNonEmptyJsonAdapter<>(moshi.adapter(type, nextAnnotations)); - } - - return null; - } - }; -} diff --git a/src/main/java/com/serjltt/moshi/adapters/SerializeOnlyNonEmptyJsonAdapter.java b/src/main/java/com/serjltt/moshi/adapters/SerializeOnlyNonEmptyJsonAdapter.java deleted file mode 100644 index 941b958..0000000 --- a/src/main/java/com/serjltt/moshi/adapters/SerializeOnlyNonEmptyJsonAdapter.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonReader; -import com.squareup.moshi.JsonWriter; -import java.io.IOException; -import java.lang.reflect.Array; -import java.util.Collection; -import java.util.Map; - -/** - * {@linkplain JsonAdapter} that will not serialize {@code T} when the passed value is empty. - */ -final class SerializeOnlyNonEmptyJsonAdapter extends JsonAdapter { - private final JsonAdapter delegate; - - SerializeOnlyNonEmptyJsonAdapter(JsonAdapter delegate) { - this.delegate = delegate; - } - - @Override public T fromJson(JsonReader reader) throws IOException { - return delegate.fromJson(reader); - } - - @Override public void toJson(JsonWriter writer, T value) throws IOException { - if (isNotEmpty(value)) { - delegate.toJson(writer, value); - } else { - // We'll need to consume this property otherwise we'll get an IllegalArgumentException. - delegate.toJson(writer, null); - } - } - - private boolean isNotEmpty(final T value) { - if (value instanceof Collection) { - Collection collection = (Collection) value; - return collection.size() > 0; - } else if (value instanceof Map) { - Map map = (Map) value; - return map.size() > 0; - } else if (value != null) { - return Array.getLength(value) > 0; - } - - return false; - } - - @Override public String toString() { - return delegate + ".serializeOnlyNonEmpty()"; - } -} diff --git a/src/main/java/com/serjltt/moshi/adapters/Transient.java b/src/main/java/com/serjltt/moshi/adapters/Transient.java deleted file mode 100644 index b50ffd1..0000000 --- a/src/main/java/com/serjltt/moshi/adapters/Transient.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonQualifier; -import com.squareup.moshi.Moshi; -import com.squareup.moshi.Types; -import java.lang.annotation.Annotation; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Type; -import java.util.Set; - -/** - * Indicates that the annotated method is transient. - * - *

To leverage from {@link Transient} {@link Transient#ADAPTER_FACTORY} must be added - * to your {@linkplain Moshi Moshi instance}: - * - *


- *   Moshi moshi = new Moshi.Builder()
- *      .add(Transient.ADAPTER_FACTORY)
- *      .build();
- * 
- */ -@Documented -@JsonQualifier -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.METHOD }) -public @interface Transient { - /** Builds an adapter that can process a type annotated with {@link Transient}. */ - JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() { - @Override public JsonAdapter create(Type type, Set annotations, - Moshi moshi) { - Set nextAnnotations = - Types.nextAnnotations(annotations, Transient.class); - if (nextAnnotations == null) return null; - - return new TransientJsonAdapter<>(moshi.adapter(type, nextAnnotations), false, false); - } - }; -} diff --git a/src/main/java/com/serjltt/moshi/adapters/Wrapped.java b/src/main/java/com/serjltt/moshi/adapters/Wrapped.java deleted file mode 100644 index 078a86e..0000000 --- a/src/main/java/com/serjltt/moshi/adapters/Wrapped.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2016 Serj Lotutovici - * - * 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 com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonQualifier; -import com.squareup.moshi.Moshi; -import java.lang.annotation.Annotation; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Type; -import java.util.Arrays; -import java.util.Set; - -import static com.serjltt.moshi.adapters.Util.nextAnnotations; - -/** - * Indicates that the annotated type/field should be unwrapped from the provided {@code path}. - * - *

For example if a json object is: - *

- *   {
- *     "response": {
- *       "status": "OK"
- *     }
- *   }
- * 
- * And the consumer only cares about the value of {@code status}, if using retrofit, a service - * method would look like: - * - *

- *   {@literal @}GET("path/")
- *   {@literal @}Wrapped({"response", "status"}) Call<String> getStatus();
- * 
- * - * The resulting response returned by {@code response.body()} will be a {@code String} with the - * value {@code "OK"}. - * - *

To leverage from {@link Wrapped} {@link Wrapped#ADAPTER_FACTORY} must be - * added to your {@linkplain Moshi Moshi instance}: - * - *


- *   Moshi moshi = new Moshi.Builder()
- *      .add(Wrapped.ADAPTER_FACTORY)
- *      .build();
- * 
- * - * DISCLAIMER: The order of {@linkplain JsonAdapter added json adapters} matters, to ensure - * {@linkplain Wrapped correct un-wrapping} behaviour the adapter factory must be the - * first custom adapter added to the {@link Moshi.Builder}. - */ -@Documented -@JsonQualifier -@Retention(RetentionPolicy.RUNTIME) -@Target({ - ElementType.FIELD, - ElementType.METHOD, - ElementType.PARAMETER, - ElementType.ANNOTATION_TYPE -}) -public @interface Wrapped { - /** The path to the wrapped json path. */ - String[] path(); - - /** - * Indicates if the adapter should fail when the json object was not found at the indicated path. - * Default {@code true}. - */ - boolean failOnNotFound() default true; - - /** Builds an adapter that can process a types annotated with {@link Wrapped}. */ - JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() { - @Override public JsonAdapter create(Type type, Set annotations, - Moshi moshi) { - Pair> nextAnnotations = nextAnnotations(annotations, Wrapped.class); - if (nextAnnotations == null) return null; - - JsonAdapter adapter = moshi.adapter(type, nextAnnotations.second); - Wrapped wrapped = nextAnnotations.first; - return new WrappedJsonAdapter<>(adapter, wrapped.path(), wrapped.failOnNotFound()); - } - }; - - /** Allows to easily create a new instance of {@link Wrapped} annotation. */ - final class Factory { - /** Create a new instance of {@link Wrapped} with the specified JSON path. */ - public static Wrapped create(final String... path) { - return create(true, path); - } - - /** Create a new instance of {@link Wrapped} with the specified JSON path. */ - public static Wrapped create(final boolean failOnNotFound, final String... path) { - return new Wrapped() { - @Override public Class annotationType() { - return Wrapped.class; - } - - @Override public String[] path() { - return path; - } - - @Override public boolean failOnNotFound() { - return failOnNotFound; - } - - @Override public int hashCode() { - int result = Arrays.hashCode(path); - result = 43 * result + (failOnNotFound ? 1 : 0); - return result; - } - - @Override public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null || getClass() != obj.getClass()) return false; - - Wrapped wrapped = (Wrapped) obj; - return Arrays.equals(path, wrapped.path()) - && failOnNotFound == wrapped.failOnNotFound(); - } - - @Override public String toString() { - return "Wrapped(" - + "path=" + Arrays.asList(path) - + ", failOnNotFound=" + failOnNotFound - + ")"; - } - }; - } - - private Factory() { - throw new AssertionError("No instances."); - } - } -} diff --git a/src/main/java/com/serjltt/moshi/adapters/WrappedJsonAdapter.java b/src/main/java/com/serjltt/moshi/adapters/WrappedJsonAdapter.java deleted file mode 100644 index 6ebd7a4..0000000 --- a/src/main/java/com/serjltt/moshi/adapters/WrappedJsonAdapter.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2016 Serj Lotutovici - * - * 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 com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonDataException; -import com.squareup.moshi.JsonReader; -import com.squareup.moshi.JsonWriter; -import java.io.IOException; -import java.util.Arrays; - -/** {@linkplain JsonAdapter} that unwraps the type/field annotated with {@linkplain Wrapped}. */ -final class WrappedJsonAdapter extends JsonAdapter { - private final JsonAdapter delegate; - private final String[] path; - private final boolean failOnNotFound; - - WrappedJsonAdapter(JsonAdapter delegate, String[] path, boolean failOnNotFound) { - this.delegate = delegate; - this.path = path; - this.failOnNotFound = failOnNotFound; - } - - @Override public T fromJson(JsonReader reader) throws IOException { - return fromJson(delegate, reader, path, 0, failOnNotFound); - } - - @Override public void toJson(JsonWriter writer, T value) throws IOException { - toJson(delegate, writer, value, path, 0); - } - - @Override public String toString() { - return delegate + String.format(".wrapped(%s)", Arrays.asList(path)) - + (failOnNotFound ? ".failOnNotFound()" : ""); - } - - /** - * Recursively goes through the json and finds the given root. Returns the object wrapped by the - * provided {@code path}. - */ - private static T fromJson(JsonAdapter adapter, JsonReader reader, String[] path, - int index, boolean failOnNotFound) throws IOException { - if (index == path.length) { - //noinspection unchecked This puts full responsibility on the caller. - return adapter.fromJson(reader); - } else { - reader.beginObject(); - Exception caughtException = null; - try { - String root = path[index]; - while (reader.hasNext()) { - if (reader.nextName().equals(root)) { - if (reader.peek() == JsonReader.Token.NULL) { - // Consumer expects a value, not a null. - if (failOnNotFound) { - throw new JsonDataException(String.format( - "Wrapped Json expected at path: %s. Found null at %s", - Arrays.asList(path), reader.getPath() - )); - } - - return reader.nextNull(); - } - return fromJson(adapter, reader, path, ++index, failOnNotFound); - } else { - reader.skipValue(); - } - } - } catch (Exception e) { - caughtException = e; - } finally { - // If the try block throw an exception, rethrow it up the stack. - if (caughtException instanceof IOException) { - //noinspection ThrowFromFinallyBlock - throw (IOException) caughtException; - } else if (caughtException instanceof JsonDataException) { - //noinspection ThrowFromFinallyBlock - throw (JsonDataException) caughtException; - } else if (caughtException != null) { - //noinspection ThrowFromFinallyBlock - throw new AssertionError(caughtException); - } - // If the json has an additional key, that was not red, we ignore it. - while (reader.hasNext()) { - reader.skipValue(); - } - // End object, so that other adapters (if any) can proceed. - reader.endObject(); - } - throw new JsonDataException(String.format( - "Wrapped Json expected at path: %s. Actual: %s", - Arrays.asList(path), reader.getPath())); - } - } - - /** - * Recursively writes the respective roots forming a json object that resembles the {@code path} - * wrapping the type of the {@code adapter}. - */ - private static void toJson(JsonAdapter adapter, JsonWriter writer, T value, - String[] path, int index) throws IOException { - if (value != null || writer.getSerializeNulls()) { - if (index == path.length) { - adapter.toJson(writer, value); - } else { - writer.beginObject(); - writer.name(path[index]); - toJson(adapter, writer, value, path, ++index); - writer.endObject(); - } - } else { - // If we don't propagate the null value the writer will throw. - writer.nullValue(); - } - } -} diff --git a/src/unitTest/java/com/serjltt/moshi/adapters/DefaultOnDataMismatchAdapterTest.java b/src/unitTest/java/com/serjltt/moshi/adapters/DefaultOnDataMismatchAdapterTest.java deleted file mode 100644 index fbd7397..0000000 --- a/src/unitTest/java/com/serjltt/moshi/adapters/DefaultOnDataMismatchAdapterTest.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.serjltt.moshi.adapters; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonDataException; -import com.squareup.moshi.JsonReader; -import com.squareup.moshi.JsonWriter; -import com.squareup.moshi.Moshi; -import com.squareup.moshi.Types; -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import org.junit.Test; - -import static com.serjltt.moshi.adapters.DefaultOnDataMismatchAdapterTest.Fruit.APPLE; -import static com.serjltt.moshi.adapters.DefaultOnDataMismatchAdapterTest.Fruit.BANANA; -import static org.assertj.core.api.Java6Assertions.assertThat; - -public final class DefaultOnDataMismatchAdapterTest { - @Test public void deserializeMismatch() throws IOException { - Fruit fruit = buildMoshi(newFruitFactory()).adapter(Fruit.class).fromJson("\"mango\""); - assertThat(fruit).isNull(); - } - - @Test public void deserializeMatch() throws IOException { - Fruit fruit = buildMoshi(newFruitFactory()).adapter(Fruit.class).fromJson("\"banana\""); - assertThat(fruit).isEqualTo(BANANA); - } - - @Test public void serialize() { - String fruit = buildMoshi(newFruitFactory()).adapter(Fruit.class).toJson(APPLE); - assertThat(fruit).isEqualTo("\"apple\""); - } - - @Test public void factorySupportsType() throws Exception { - Type parameterized = Types.newParameterizedType(List.class, String.class); - List fallback = Collections.singletonList("test"); - - // Build a moshi instance using the adapter under test and one that will throw on each read. - Moshi moshi = buildMoshi(DefaultOnDataMismatchAdapter.newFactory(parameterized, fallback)) - .newBuilder() - .add(new JsonAdapter.Factory() { - @Override public JsonAdapter create(Type type, Set annotations, - Moshi moshi) { - final JsonAdapter next = moshi.nextAdapter(this, type, annotations); - return new JsonAdapter() { - @Override public Object fromJson(JsonReader reader) throws IOException { - throw new JsonDataException("Fail for all types"); - } - - @Override public void toJson(JsonWriter writer, Object value) throws IOException { - next.toJson(writer, value); - } - }; - } - }) - .build(); - JsonAdapter> adapter = moshi.adapter(parameterized); - - List fromJson = adapter.fromJson("[]"); - assertThat(fromJson) - .isEqualTo(fallback) - .containsExactly("test"); - - String toJson = adapter.toJson(fromJson); - assertThat(toJson).isEqualTo("[\"test\"]"); - } - - @Test public void toStringReflectsInner() { - assertThat(buildMoshi(newFruitFactory()).adapter(Fruit.class).toString()) - .isEqualTo("JsonAdapter(com.serjltt.moshi.adapters.DefaultOnDataMismatchAdapterTest$Fruit)" - + ".nullSafe().defaultOnDatMisMatch(null)"); - } - - private JsonAdapter.Factory newFruitFactory() { - return DefaultOnDataMismatchAdapter.newFactory(Fruit.class, null); - } - - private Moshi buildMoshi(JsonAdapter.Factory factory) { - return new Moshi.Builder() - .add(factory) - .build(); - } - - enum Fruit { - @Json(name = "banana")BANANA, - @Json(name = "apple")APPLE - } -} diff --git a/src/unitTest/java/com/serjltt/moshi/adapters/ElementAtJsonAdapterTest.java b/src/unitTest/java/com/serjltt/moshi/adapters/ElementAtJsonAdapterTest.java deleted file mode 100644 index b632241..0000000 --- a/src/unitTest/java/com/serjltt/moshi/adapters/ElementAtJsonAdapterTest.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2016 Serj Lotutovici - * - * 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 com.serjltt.moshi.adapters; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonDataException; -import com.squareup.moshi.JsonQualifier; -import com.squareup.moshi.Moshi; -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Set; -import org.junit.Ignore; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; - -public final class ElementAtJsonAdapterTest { - // Lazy adapters work only within the context of moshi. - private final Moshi moshi = new Moshi.Builder() - .add(ElementAt.ADAPTER_FACTORY) - .add(new Custom.CustomAdapter()) // We need to check that other annotations are not lost. - .build(); - - @Test public void elementAt() throws Exception { - JsonAdapter adapter = moshi.adapter(Data.class); - - Data fromJson = adapter.fromJson("{\n" - + " \"obj\": [\n" - + " \"one\",\n" - + " \"two\"\n" - + " ]\n" - + "}"); - assertThat(fromJson.str).isEqualTo("two"); - - String toJson = adapter.toJson(fromJson); - // The excluded data is lost during parsing - // Adapter under test assumes that the consumer doesn't need that data - assertThat(toJson).isEqualTo("{\"obj\":[\"two\"]}"); - } - - @Test public void fromJsonOnEmptyArrayReturnsNull() throws Exception { - assertNullReturn("{\n" - + " \"obj\": []\n" - + "}"); - } - - @Test public void fromJsonOnArrayOfSizeOneReturnsNull() throws Exception { - assertNullReturn("{\n" - + " \"obj\": [\"test\"]\n" - + "}"); - } - - @Test public void fromJsonOnNullArrayReturnsNull() throws Exception { - assertNullReturn("{\n" - + " \"obj\": null\n" - + "}"); - } - - @Test public void fromJsonExpectsAnArray() throws Exception { - JsonAdapter adapter = moshi.adapter(Data.class); - - try { - adapter.fromJson("{\n" - + " \"obj\": \"this_will_throw\"\n" - + "}"); - fail(); - } catch (JsonDataException e) { - // Moshi's Collection adapter will throw - assertThat(e).hasMessage("Expected BEGIN_ARRAY but was STRING at path $.obj"); - } - } - - // Currently there is no way to create an adapter - @Test @Ignore public void factoryMaintainsOtherAnnotations() throws Exception { - JsonAdapter adapter = moshi.adapter(Data2.class); - - Data2 fromJson = adapter.fromJson("{\n" - + " \"str\": [\n" - + " \"test\"\n" - + " ]\n" - + "}"); - assertThat(fromJson.str).isEqualTo("testCustom"); - - String toJson = adapter.toJson(fromJson); - assertThat(toJson).isEqualTo("{\"str\":[\"test\"]}"); - } - - // This one is redundant, but keeps JaCoCo quiet - @Test public void factoryExpectsOnlyOneAnnotation() { - // A list of fake annotations. - Set annotations = new LinkedHashSet() { - { - add(new Annotation() { - @Override public Class annotationType() { - return Test.class; - } - }); - add(new Annotation() { - @Override public Class annotationType() { - return Custom.class; - } - }); - } - }; - assertThat(ElementAt.ADAPTER_FACTORY.create(String.class, annotations, moshi)).isNull(); - - // Emulate existing annotation (should also return null). - annotations.add(new ElementAt() { - @Override public Class annotationType() { - return ElementAt.class; - } - - @Override public int index() { - return 0; - } - }); - assertThat(ElementAt.ADAPTER_FACTORY.create(String.class, annotations, moshi)).isNull(); - } - - @Test public void toStringReflectsInnerAdapter() throws Exception { - JsonAdapter adapter = moshi.adapter(String.class, - Collections.singleton(new ElementAt() { - @Override public Class annotationType() { - return ElementAt.class; - } - - @Override public int index() { - return 2; - } - })); - - assertThat(adapter.toString()) - .isEqualTo("JsonAdapter(String).nullSafe().collection().nullSafe().elementAt(2)"); - } - - @Test public void elementAtDelegated() throws Exception { - JsonAdapter adapter = moshi.adapter(Data3.class); - - Data3 fromJson = adapter.fromJson("{\n" - + " \"obj\": [\n" - + " \"one\",\n" - + " \"two\"\n" - + " ]\n" - + "}"); - assertThat(fromJson.str).isEqualTo("two"); - - String toJson = adapter.toJson(fromJson); - assertThat(toJson).isEqualTo("{\"obj\":[\"two\"]}"); - } - - @JsonQualifier - @ElementAt(index = 1) - @Retention(RetentionPolicy.RUNTIME) - @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER }) - @interface AlwaysElementAtIndexOne { } - - private void assertNullReturn(String string) throws IOException { - JsonAdapter adapter = moshi.adapter(Data.class); - - Data fromJson = adapter.fromJson(string); - assertThat(fromJson.str).isNull(); - - String toJson = adapter.toJson(fromJson); - assertThat(toJson).isEqualTo("{\"obj\":[null]}"); - } - - private static class Data { - @ElementAt(index = 1) - @Json(name = "obj") String str; - } - - private static class Data2 { - @ElementAt(index = 0) - @Custom String str; - } - - private static class Data3 { - @AlwaysElementAtIndexOne - @Json(name = "obj") String str; - } -} diff --git a/src/unitTest/java/com/serjltt/moshi/adapters/FallbackEnumJsonAdapterTest.java b/src/unitTest/java/com/serjltt/moshi/adapters/FallbackEnumJsonAdapterTest.java deleted file mode 100644 index caa164d..0000000 --- a/src/unitTest/java/com/serjltt/moshi/adapters/FallbackEnumJsonAdapterTest.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2016 Serj Lotutovici - * Copyright (C) 2014 Square, Inc. - * - * 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 com.serjltt.moshi.adapters; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonDataException; -import com.squareup.moshi.Moshi; -import java.lang.annotation.Annotation; -import java.util.Collections; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; - -public final class FallbackEnumJsonAdapterTest { - // Lazy adapters work only within the context of moshi. - private final Moshi moshi = new Moshi.Builder() - .add(FallbackEnum.ADAPTER_FACTORY) - .build(); - - @Test public void asRegularEnumAdapter() throws Exception { - JsonAdapter adapter = moshi.adapter(Roshambo.class).lenient(); - assertThat(adapter.fromJson("\"ROCK\"")).isEqualTo(Roshambo.ROCK); - assertThat(adapter.toJson(Roshambo.PAPER)).isEqualTo("\"PAPER\""); - // Check annotated value - assertThat(adapter.fromJson("\"scr\"")).isEqualTo(Roshambo.SCISSORS); - assertThat(adapter.toJson(Roshambo.SCISSORS)).isEqualTo("\"scr\""); - } - - @Test public void fallbackEnum() throws Exception { - JsonAdapter adapter = moshi.adapter(Roshambo.class).lenient(); - assertThat(adapter.fromJson("\"SPOCK\"")).isEqualTo(Roshambo.UNKNOWN); - } - - @Test public void nullEnum() throws Exception { - JsonAdapter adapter = moshi.adapter(Roshambo.class).lenient(); - assertThat(adapter.fromJson("null")).isNull(); - assertThat(adapter.toJson(null)).isEqualTo("null"); - } - - @Test public void throwsOnInvalidFallback() throws Exception { - try { - moshi.adapter(Value.class); - fail(); - } catch (IllegalArgumentException expected) { - assertThat(expected).hasMessage( - "No enum constant com.serjltt.moshi.adapters.FallbackEnumJsonAdapterTest.Value.UNK"); - } - } - - @Test public void toStringReflectsInnerAdapter() throws Exception { - JsonAdapter adapter = moshi.adapter(Roshambo.class); - - assertThat(adapter.toString()).isEqualTo( - "JsonAdapter(com.serjltt.moshi.adapters.FallbackEnumJsonAdapterTest$Roshambo)" - + ".fallbackEnum(UNKNOWN).nullSafe()"); - } - - @Test public void ignoresUnannotatedEnums() throws Exception { - JsonAdapter adapter = moshi.adapter(Regular.class).lenient(); - assertThat(adapter.fromJson("\"ONE\"")).isEqualTo(Regular.ONE); - - try { - adapter.fromJson("\"TWO\""); - fail(); - } catch (JsonDataException expected) { - assertThat(expected).hasMessage( - "Expected one of [ONE] but was TWO at path $"); - } - } - - @Test public void factoryIgnoresUnsupportedTypes() throws Exception { - JsonAdapter adapter1 = FallbackEnum.ADAPTER_FACTORY - .create(String.class, Collections.emptySet(), moshi); - assertThat(adapter1).isNull(); - - JsonAdapter adapter2 = FallbackEnum.ADAPTER_FACTORY - .create(Roshambo.class, Collections.singleton(Wrapped.Factory.create("")), moshi); - assertThat(adapter2).isNull(); - } - - @FallbackEnum(name = "UNKNOWN") enum Roshambo { - ROCK, - PAPER, - @Json(name = "scr") SCISSORS, - UNKNOWN - } - - @FallbackEnum(name = "UNK") enum Value { - @SuppressWarnings("unused") UNKNOWN - } - - enum Regular { - ONE - } -} diff --git a/src/unitTest/java/com/serjltt/moshi/adapters/FilterNullsJsonAdapterTest.java b/src/unitTest/java/com/serjltt/moshi/adapters/FilterNullsJsonAdapterTest.java deleted file mode 100644 index e912c05..0000000 --- a/src/unitTest/java/com/serjltt/moshi/adapters/FilterNullsJsonAdapterTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.Moshi; -import com.squareup.moshi.Types; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import org.junit.Test; - -import static java.util.Arrays.asList; -import static org.assertj.core.api.Java6Assertions.assertThat; - -public final class FilterNullsJsonAdapterTest { - // Lazy adapters work only within the context of moshi. - private final Moshi moshi = new Moshi.Builder() - .add(FilterNulls.ADAPTER_FACTORY) - .add(new Custom.CustomAdapter()) // We need to check that other annotations are not lost. - .build(); - - @Test public void noNullValues() throws Exception { - JsonAdapter> adapter = moshi.adapter(Types.newParameterizedType(List.class, - String.class), FilterNulls.class); - - List fromJson = adapter.fromJson("[\"apple\",\"banana\"]"); - assertThat(fromJson).containsExactly("apple", "banana"); - - String toJson = adapter.toJson(fromJson); - assertThat(toJson).isEqualTo("[\"apple\",\"banana\"]"); - } - - @Test public void nullValues() throws Exception { - JsonAdapter> adapter = moshi.adapter(Types.newParameterizedType(List.class, - String.class), FilterNulls.class); - - List fromJson = adapter.fromJson("[\"apple\",\"banana\",null]"); - assertThat(fromJson).containsExactly("apple", "banana"); - - String toJson = adapter.toJson(new ArrayList<>(asList("apple", "banana", null))); - assertThat(toJson).isEqualTo("[\"apple\",\"banana\"]"); - } - - @Test public void nullList() throws Exception { - JsonAdapter> adapter = moshi.adapter(Types.newParameterizedType(List.class, - String.class), FilterNulls.class); - - List fromJson = adapter.fromJson("null"); - assertThat(fromJson).isNull(); - - String toJson = adapter.toJson(null); - assertThat(toJson).isEqualTo("null"); - } - - @Test public void toStringReflectsInnerAdapter() throws Exception { - JsonAdapter adapter = moshi.adapter(Types.newParameterizedType(Collection.class, - String.class), FilterNulls.class); - - assertThat(adapter.toString()) - .isEqualTo("JsonAdapter(String).nullSafe().collection().nullSafe().filterNulls()"); - } -} diff --git a/src/unitTest/java/com/serjltt/moshi/adapters/FirstElementJsonAdapterTest.java b/src/unitTest/java/com/serjltt/moshi/adapters/FirstElementJsonAdapterTest.java deleted file mode 100644 index 0fd32e2..0000000 --- a/src/unitTest/java/com/serjltt/moshi/adapters/FirstElementJsonAdapterTest.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2016 Serj Lotutovici - * - * 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 com.serjltt.moshi.adapters; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonDataException; -import com.squareup.moshi.Moshi; -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.util.LinkedHashSet; -import java.util.Set; -import org.junit.Ignore; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; - -public final class FirstElementJsonAdapterTest { - // Lazy adapters work only within the context of moshi. - private final Moshi moshi = new Moshi.Builder() - .add(FirstElement.ADAPTER_FACTORY) - .add(new Custom.CustomAdapter()) // We need to check that other annotations are not lost. - .build(); - - @Test public void first() throws Exception { - JsonAdapter adapter = moshi.adapter(Data.class); - - Data fromJson = adapter.fromJson("{\n" - + " \"obj\": [\n" - + " \"one\",\n" - + " \"two\"\n" - + " ]\n" - + "}"); - assertThat(fromJson.str).isEqualTo("one"); - - String toJson = adapter.toJson(fromJson); - // The excluded data is lost during parsing - // Adapter under test assumes that the consumer doesn't need that data - assertThat(toJson).isEqualTo("{\"obj\":[\"one\"]}"); - } - - @Test public void fromJsonOnEmptyArrayReturnsNull() throws Exception { - assertNullReturn("{\n" - + " \"obj\": []\n" - + "}"); - } - - @Test public void fromJsonOnNullArrayReturnsNull() throws Exception { - assertNullReturn("{\n" - + " \"obj\": null\n" - + "}"); - } - - @Test public void fromJsonExpectsAnArray() throws Exception { - JsonAdapter adapter = moshi.adapter(Data.class); - - try { - adapter.fromJson("{\n" - + " \"obj\": \"this_will_throw\"\n" - + "}"); - fail(); - } catch (JsonDataException e) { - // Moshi's Collection adapter will throw - assertThat(e).hasMessage("Expected BEGIN_ARRAY but was STRING at path $.obj"); - } - } - - // Currently there is no way to create an adapter - @Test @Ignore public void factoryMaintainsOtherAnnotations() throws Exception { - JsonAdapter adapter = moshi.adapter(Data2.class); - - Data2 fromJson = adapter.fromJson("{\n" - + " \"str\": [\n" - + " \"test\"\n" - + " ]\n" - + "}"); - assertThat(fromJson.str).isEqualTo("testCustom"); - - String toJson = adapter.toJson(fromJson); - assertThat(toJson).isEqualTo("{\"str\":[\"test\"]}"); - } - - // This one is redundant, but keeps JaCoCo quiet - @Test public void factoryExpectsOnlyOneAnnotation() throws Exception { - // A list of fake annotations. - Set annotations = new LinkedHashSet() { - { - add(new Annotation() { - @Override public Class annotationType() { - return Test.class; - } - }); - add(new Annotation() { - @Override public Class annotationType() { - return Custom.class; - } - }); - } - }; - assertThat(FirstElement.ADAPTER_FACTORY.create(String.class, annotations, moshi)).isNull(); - - // Emulate existing annotation (should also return null). - annotations.add(new Annotation() { - @Override public Class annotationType() { - return FirstElement.class; - } - }); - assertThat(FirstElement.ADAPTER_FACTORY.create(String.class, annotations, moshi)).isNull(); - } - - @Test public void toStringReflectsInnerAdapter() throws Exception { - JsonAdapter adapter = moshi.adapter(String.class, FirstElement.class); - - assertThat(adapter.toString()) - .isEqualTo("JsonAdapter(String).nullSafe().collection().nullSafe().elementAt(0)"); - } - - private void assertNullReturn(String string) throws IOException { - JsonAdapter adapter = moshi.adapter(Data.class); - - Data fromJson = adapter.fromJson(string); - assertThat(fromJson.str).isNull(); - - String toJson = adapter.toJson(fromJson); - assertThat(toJson).isEqualTo("{\"obj\":[null]}"); - } - - private static class Data { - @FirstElement - @Json(name = "obj") String str; - } - - private static class Data2 { - @FirstElement - @Custom String str; - } -} diff --git a/src/unitTest/java/com/serjltt/moshi/adapters/LastElementJsonAdapterTest.java b/src/unitTest/java/com/serjltt/moshi/adapters/LastElementJsonAdapterTest.java deleted file mode 100644 index 4a85f46..0000000 --- a/src/unitTest/java/com/serjltt/moshi/adapters/LastElementJsonAdapterTest.java +++ /dev/null @@ -1,137 +0,0 @@ -package com.serjltt.moshi.adapters; - -import com.squareup.moshi.Json; -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonDataException; -import com.squareup.moshi.Moshi; -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.util.LinkedHashSet; -import java.util.Set; -import org.junit.Ignore; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; - -public final class LastElementJsonAdapterTest { - // Lazy adapters work only within the context of moshi. - private final Moshi moshi = new Moshi.Builder() - .add(LastElement.ADAPTER_FACTORY) - .add(new Custom.CustomAdapter()) // We need to check that other annotations are not lost. - .build(); - - @Test public void last() throws Exception { - JsonAdapter - adapter = moshi.adapter(LastElementJsonAdapterTest.Data.class); - - LastElementJsonAdapterTest.Data fromJson = adapter.fromJson("{\n" - + " \"obj\": [\n" - + " \"one\",\n" - + " \"two\"\n" - + " ]\n" - + "}"); - assertThat(fromJson.str).isEqualTo("two"); - - String toJson = adapter.toJson(fromJson); - // The excluded data is lost during parsing - // Adapter under test assumes that the consumer doesn't need that data - assertThat(toJson).isEqualTo("{\"obj\":[\"two\"]}"); - } - - @Test public void fromJsonOnEmptyArrayReturnsNull() throws Exception { - assertNullReturn("{\n" - + " \"obj\": []\n" - + "}"); - } - - @Test public void fromJsonOnNullArrayReturnsNull() throws Exception { - assertNullReturn("{\n" - + " \"obj\": null\n" - + "}"); - } - - @Test public void fromJsonExpectsAnArray() throws Exception { - JsonAdapter adapter = moshi.adapter(Data.class); - - try { - adapter.fromJson("{\n" - + " \"obj\": \"this_will_throw\"\n" - + "}"); - fail(); - } catch (JsonDataException e) { - // Moshi's Collection adapter will throw - assertThat(e).hasMessage("Expected BEGIN_ARRAY but was STRING at path $.obj"); - } - } - - // Currently there is no way to create an adapter - @Test @Ignore public void factoryMaintainsOtherAnnotations() throws Exception { - JsonAdapter adapter = moshi.adapter(Data2.class); - - LastElementJsonAdapterTest.Data2 fromJson = adapter.fromJson("{\n" - + " \"str\": [\n" - + " \"test\"\n" - + " ]\n" - + "}"); - assertThat(fromJson.str).isEqualTo("testCustom"); - - String toJson = adapter.toJson(fromJson); - assertThat(toJson).isEqualTo("{\"str\":[\"test\"]}"); - } - - // This one is redundant, but keeps JaCoCo quiet - @Test public void factoryExpectsOnlyOneAnnotation() throws Exception { - // A list of fake annotations. - Set annotations = new LinkedHashSet() { - { - add(new Annotation() { - @Override public Class annotationType() { - return Test.class; - } - }); - add(new Annotation() { - @Override public Class annotationType() { - return Custom.class; - } - }); - } - }; - assertThat(LastElement.ADAPTER_FACTORY.create(String.class, annotations, moshi)).isNull(); - - // Emulate existing annotation (should also return null). - annotations.add(new Annotation() { - @Override public Class annotationType() { - return LastElement.class; - } - }); - assertThat(LastElement.ADAPTER_FACTORY.create(String.class, annotations, moshi)).isNull(); - } - - @Test public void toStringReflectsInnerAdapter() throws Exception { - JsonAdapter adapter = moshi.adapter(String.class, LastElement.class); - - assertThat(adapter.toString()) - .isEqualTo("JsonAdapter(String).nullSafe().collection().nullSafe().lastElement()"); - } - - private void assertNullReturn(String string) throws IOException { - JsonAdapter adapter = moshi.adapter(Data.class); - - LastElementJsonAdapterTest.Data fromJson = adapter.fromJson(string); - assertThat(fromJson.str).isNull(); - - String toJson = adapter.toJson(fromJson); - assertThat(toJson).isEqualTo("{\"obj\":[null]}"); - } - - private static class Data { - @LastElement - @Json(name = "obj") String str; - } - - private static class Data2 { - @LastElement - @Custom String str; - } -} diff --git a/src/unitTest/java/com/serjltt/moshi/adapters/SerializeNullsJsonAdapterTest.java b/src/unitTest/java/com/serjltt/moshi/adapters/SerializeNullsJsonAdapterTest.java deleted file mode 100644 index b9e4f2c..0000000 --- a/src/unitTest/java/com/serjltt/moshi/adapters/SerializeNullsJsonAdapterTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2016 Serj Lotutovici - * - * 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 com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonWriter; -import com.squareup.moshi.Moshi; -import okio.Buffer; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public final class SerializeNullsJsonAdapterTest { - // Lazy adapters work only within the context of moshi. - private final Moshi moshi = new Moshi.Builder() - .add(SerializeNulls.ADAPTER_FACTORY) - .add(new Custom.CustomAdapter()) // We need to check that other annotations are not lost. - .build(); - - @Test public void serializesNulls() throws Exception { - JsonAdapter adapter = moshi.adapter(Data1.class); - - Data1 fromJson = adapter.fromJson("{\n" - + " \"data\": null\n" - + "}"); - assertThat(fromJson.data).isNull(); - - String toJson = adapter.toJson(fromJson); - assertThat(toJson).isEqualTo("{\"data\":null}"); - } - - @Test public void factoryMaintainsOtherAnnotations() throws Exception { - JsonAdapter adapter = moshi.adapter(Data2.class); - - Data2 fromJson = adapter.fromJson("{\n" - + " \"data\": \"val\"\n" - + "}"); - assertThat(fromJson.data).isEqualTo("valCustom"); - - String toJson = adapter.toJson(fromJson); - assertThat(toJson).isEqualTo("{\"data\":\"val\"}"); - - Data2 data = new Data2(); - data.data = null; - toJson = adapter.toJson(data); - assertThat(toJson).isEqualTo("{\"data\":null}"); - } - - @Test public void maintainsPreviousSerializationValue() throws Exception { - JsonAdapter adapter = moshi.adapter(Data1.class); - Data1 data1 = new Data1(); - - JsonWriter writer1 = JsonWriter.of(new Buffer()); - writer1.setSerializeNulls(true); - adapter.toJson(writer1, data1); - assertThat(writer1.getSerializeNulls()).isTrue(); - - JsonWriter writer2 = JsonWriter.of(new Buffer()); - writer2.setSerializeNulls(false); - adapter.toJson(writer2, data1); - assertThat(writer2.getSerializeNulls()).isFalse(); - } - - @Test public void toStringReflectsInnerAdapter() throws Exception { - JsonAdapter adapter = moshi.adapter(String.class, SerializeNulls.class); - - assertThat(adapter.toString()) - .isEqualTo("JsonAdapter(String).nullSafe().serializeNulls()"); - } - - private static class Data1 { - @SerializeNulls String data; - } - - private static class Data2 { - @Custom - @SerializeNulls String data; - } -} diff --git a/src/unitTest/java/com/serjltt/moshi/adapters/SerializeOnlyJsonAdapterTest.java b/src/unitTest/java/com/serjltt/moshi/adapters/SerializeOnlyJsonAdapterTest.java deleted file mode 100644 index 1314b1a..0000000 --- a/src/unitTest/java/com/serjltt/moshi/adapters/SerializeOnlyJsonAdapterTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.Moshi; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public final class SerializeOnlyJsonAdapterTest { - // Lazy adapters work only within the context of moshi. - private final Moshi moshi = new Moshi.Builder() - .add(SerializeOnly.ADAPTER_FACTORY) - .add(SerializeNulls.ADAPTER_FACTORY) - .add(new Custom.CustomAdapter()) // We need to check that other annotations are not lost. - .build(); - - @Test public void serializeOnly() throws Exception { - JsonAdapter adapter = moshi.adapter(Data1.class); - - Data1 fromJson = adapter.fromJson("{\"data\": \"test\"}"); - assertThat(fromJson.data).isNull(); - - fromJson.data = "1234"; - assertThat(adapter.toJson(fromJson)).isEqualTo("{\"data\":\"1234\"}"); - } - - @Test public void factoryMaintainsOtherAnnotations() throws Exception { - JsonAdapter adapter = moshi.adapter(Data2.class); - - Data2 fromJson = adapter.fromJson("{\"data\": \"test\"}"); - assertThat(fromJson.data).isNull(); - - fromJson.data = "1234Custom"; - String toJson = adapter.toJson(fromJson); - assertThat(toJson).isEqualTo("{\"data\":\"1234\"}"); - - Data2 data = new Data2(); - data.data = null; - toJson = adapter.toJson(data); - assertThat(toJson).isEqualTo("{\"data\":null}"); - } - - @Test public void toStringReflectsInnerAdapter() throws Exception { - JsonAdapter adapter = moshi.adapter(String.class, SerializeOnly.class); - - assertThat(adapter.toString()).isEqualTo("JsonAdapter(String).nullSafe().serializeOnly()"); - } - - private static class Data1 { - @SerializeOnly String data; - } - - private static class Data2 { - @Custom @SerializeOnly @SerializeNulls String data; - } -} diff --git a/src/unitTest/java/com/serjltt/moshi/adapters/SerializeOnlyNonEmptyJsonAdapterTest.java b/src/unitTest/java/com/serjltt/moshi/adapters/SerializeOnlyNonEmptyJsonAdapterTest.java deleted file mode 100644 index 24628c9..0000000 --- a/src/unitTest/java/com/serjltt/moshi/adapters/SerializeOnlyNonEmptyJsonAdapterTest.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright 2016 Serj Lotutovici - * - * 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 com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.Moshi; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public final class SerializeOnlyNonEmptyJsonAdapterTest { - // Lazy adapters work only within the context of moshi. - private final Moshi moshi = new Moshi.Builder() - .add(SerializeOnlyNonEmpty.ADAPTER_FACTORY) - .add(new Custom.CustomAdapter()) // We need to check that other annotations are not lost. - .build(); - - @Test public void serializesOnlyNonEmptyCustomArray() throws Exception { - JsonAdapter adapter = moshi.adapter(Data1.class); - - Data1 fromJson = adapter.fromJson("{\n" - + "\"customArray\": [{" - + "\"data\":\"blub\"" - + "}]\n" - + "}"); - assertThat(fromJson.customArray).isNotNull().hasSize(1); - assertThat(fromJson.customArray[0].data).isEqualTo("blub"); - - fromJson.customArray = new CustomType[0]; - assertThat(adapter.toJson(fromJson)).isEqualTo("{}"); - - fromJson.customArray = new CustomType[] { new CustomType("blub") }; - assertThat(adapter.toJson(fromJson)).isEqualTo("{\"customArray\":[{\"data\":\"blub\"}]}"); - } - - @Test public void serializesOnlyNonEmptyByteArray() throws Exception { - JsonAdapter adapter = moshi.adapter(Data1.class); - - Data1 fromJson = adapter.fromJson("{\n" - + "\"byteArray\": [1]\n" - + "}"); - assertThat(fromJson.byteArray).containsExactly((byte) 1); - - fromJson.byteArray = new byte[0]; - assertThat(adapter.toJson(fromJson)).isEqualTo("{}"); - - fromJson.byteArray = new byte[] { 5 }; - assertThat(adapter.toJson(fromJson)).isEqualTo("{\"byteArray\":[5]}"); - } - - @Test public void serializesOnlyNonEmptyCharArray() throws Exception { - JsonAdapter adapter = moshi.adapter(Data1.class); - - Data1 fromJson = adapter.fromJson("{\n" - + "\"charArray\": [\"A\"]\n" - + "}"); - assertThat(fromJson.charArray).containsExactly((char) 65); - - fromJson.charArray = new char[0]; - assertThat(adapter.toJson(fromJson)).isEqualTo("{}"); - - fromJson.charArray = new char[] { 65 }; - assertThat(adapter.toJson(fromJson)).isEqualTo("{\"charArray\":[\"A\"]}"); - } - - @Test public void serializesOnlyNonEmptyShortArray() throws Exception { - JsonAdapter adapter = moshi.adapter(Data1.class); - - Data1 fromJson = adapter.fromJson("{\n" - + "\"shortArray\": [1]\n" - + "}"); - assertThat(fromJson.shortArray).containsExactly((short) 1); - - fromJson.shortArray = new short[0]; - assertThat(adapter.toJson(fromJson)).isEqualTo("{}"); - - fromJson.shortArray = new short[] { 5 }; - assertThat(adapter.toJson(fromJson)).isEqualTo("{\"shortArray\":[5]}"); - } - - @Test public void serializesOnlyNonEmptyIntArray() throws Exception { - JsonAdapter adapter = moshi.adapter(Data1.class); - - Data1 fromJson = adapter.fromJson("{\n" - + "\"intArray\": [1]\n" - + "}"); - assertThat(fromJson.intArray).containsExactly(1); - - fromJson.intArray = new int[0]; - assertThat(adapter.toJson(fromJson)).isEqualTo("{}"); - - fromJson.intArray = new int[] { 5 }; - assertThat(adapter.toJson(fromJson)).isEqualTo("{\"intArray\":[5]}"); - } - - @Test public void serializesOnlyNonEmptyLongArray() throws Exception { - JsonAdapter adapter = moshi.adapter(Data1.class); - - Data1 fromJson = adapter.fromJson("{\n" - + "\"longArray\": [1]\n" - + "}"); - assertThat(fromJson.longArray).containsExactly(1L); - - fromJson.longArray = new long[0]; - assertThat(adapter.toJson(fromJson)).isEqualTo("{}"); - - fromJson.longArray = new long[] { 5L }; - assertThat(adapter.toJson(fromJson)).isEqualTo("{\"longArray\":[5]}"); - } - - @Test public void serializesOnlyNonEmptyFloatArray() throws Exception { - JsonAdapter adapter = moshi.adapter(Data1.class); - - Data1 fromJson = adapter.fromJson("{\n" - + "\"floatArray\": [1.0]\n" - + "}"); - assertThat(fromJson.floatArray).containsExactly(1.f); - - fromJson.floatArray = new float[0]; - assertThat(adapter.toJson(fromJson)).isEqualTo("{}"); - - fromJson.floatArray = new float[] { 5f }; - assertThat(adapter.toJson(fromJson)).isEqualTo("{\"floatArray\":[5.0]}"); - } - - @Test public void serializesOnlyNonEmptyDoubleArray() throws Exception { - JsonAdapter adapter = moshi.adapter(Data1.class); - - Data1 fromJson = adapter.fromJson("{\n" - + "\"doubleArray\": [1.0]\n" - + "}"); - assertThat(fromJson.doubleArray).containsExactly(1.f); - - fromJson.doubleArray = new double[0]; - assertThat(adapter.toJson(fromJson)).isEqualTo("{}"); - - fromJson.doubleArray = new double[] { 5f }; - assertThat(adapter.toJson(fromJson)).isEqualTo("{\"doubleArray\":[5.0]}"); - } - - @Test public void serializesOnlyNonEmptyBooleanArray() throws Exception { - JsonAdapter adapter = moshi.adapter(Data1.class); - - Data1 fromJson = adapter.fromJson("{\n" - + "\"booleanArray\": [false]\n" - + "}"); - assertThat(fromJson.booleanArray).containsExactly(false); - - fromJson.booleanArray = new boolean[0]; - assertThat(adapter.toJson(fromJson)).isEqualTo("{}"); - - fromJson.booleanArray = new boolean[] { false }; - assertThat(adapter.toJson(fromJson)).isEqualTo("{\"booleanArray\":[false]}"); - } - - @Test public void serializesOnlyNonEmptyStringArray() throws Exception { - JsonAdapter adapter = moshi.adapter(Data1.class); - - Data1 fromJson = adapter.fromJson("{\n" - + "\"stringArray\": [\"blub\"]\n" - + "}"); - assertThat(fromJson.stringArray).containsExactly("blub"); - - fromJson.stringArray = new String[0]; - assertThat(adapter.toJson(fromJson)).isEqualTo("{}"); - - fromJson.stringArray = new String[] { "blub" }; - assertThat(adapter.toJson(fromJson)).isEqualTo("{\"stringArray\":[\"blub\"]}"); - } - - @Test public void serializesOnlyNonEmptyCollection() throws Exception { - JsonAdapter adapter = moshi.adapter(Data1.class); - - Data1 fromJson = adapter.fromJson("{\n" - + "\"collection\": [\"blub\"]\n" - + "}"); - assertThat(fromJson.collection).containsExactly("blub"); - - fromJson.collection = new ArrayList<>(0); - assertThat(adapter.toJson(fromJson)).isEqualTo("{}"); - - fromJson.collection.add("blub"); - assertThat(adapter.toJson(fromJson)).isEqualTo("{\"collection\":[\"blub\"]}"); - } - - @Test public void serializesOnlyNonEmptyMap() throws Exception { - JsonAdapter adapter = moshi.adapter(Data1.class); - - Data1 fromJson = adapter.fromJson("{\n" - + "\"map\": {" - + "\"email\":\"blub\"\n" - + "}\n" - + "}"); - assertThat(fromJson.map).containsEntry("email", "blub"); - - fromJson.map = new HashMap<>(); - assertThat(adapter.toJson(fromJson)).isEqualTo("{}"); - - fromJson.map.put("email", "blub"); - assertThat(adapter.toJson(fromJson)).isEqualTo("{\"map\":{\"email\":\"blub\"}}"); - } - - @Test public void toStringReflectsInnerAdapter() throws Exception { - JsonAdapter adapter = moshi.adapter(String[].class, SerializeOnlyNonEmpty.class); - - assertThat(adapter.toString()) - .isEqualTo("JsonAdapter(String).nullSafe().array().nullSafe().serializeOnlyNonEmpty()"); - } - - static class Data1 { - @SerializeOnlyNonEmpty CustomType[] customArray; - @SerializeOnlyNonEmpty byte[] byteArray; - @SerializeOnlyNonEmpty char[] charArray; - @SerializeOnlyNonEmpty short[] shortArray; - @SerializeOnlyNonEmpty int[] intArray; - @SerializeOnlyNonEmpty long[] longArray; - @SerializeOnlyNonEmpty float[] floatArray; - @SerializeOnlyNonEmpty double[] doubleArray; - @SerializeOnlyNonEmpty boolean[] booleanArray; - @SerializeOnlyNonEmpty String[] stringArray; - @SerializeOnlyNonEmpty Collection collection; - @SerializeOnlyNonEmpty Map map; - } - - static class CustomType { - final String data; - - CustomType(final String data) { - this.data = data; - } - } -} diff --git a/src/unitTest/java/com/serjltt/moshi/adapters/WrappedJsonAdapterTest.java b/src/unitTest/java/com/serjltt/moshi/adapters/WrappedJsonAdapterTest.java deleted file mode 100644 index 43591b3..0000000 --- a/src/unitTest/java/com/serjltt/moshi/adapters/WrappedJsonAdapterTest.java +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Copyright 2016 Serj Lotutovici - * - * 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 com.serjltt.moshi.adapters; - -import com.pushtorefresh.private_constructor_checker.PrivateConstructorChecker; -import com.squareup.moshi.FromJson; -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonDataException; -import com.squareup.moshi.JsonEncodingException; -import com.squareup.moshi.JsonQualifier; -import com.squareup.moshi.Moshi; -import com.squareup.moshi.ToJson; -import com.squareup.moshi.Types; -import java.io.IOException; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.Collections; -import java.util.List; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; - -public final class WrappedJsonAdapterTest { - // Lazy adapters work only within the context of moshi. - private final Moshi moshi = new Moshi.Builder() - .add(Wrapped.ADAPTER_FACTORY) - .add(new Custom.CustomAdapter()) // We need to check that other annotations are not lost. - .add(new ThrowingAdapter()) // We need to check that exceptions are propagated correctly. - .build(); - - @Test public void oneObject() throws Exception { - JsonAdapter adapter = moshi.adapter(Data2.class); - - Data2 fromJson = adapter.fromJson("{\n" - + " \"data\": {\n" - + " \"1\": {\n" - + " \"2\": {\n" - + " \"str\": \"test\",\n" - + " \"val\": 42\n" - + " }\n" - + " }\n" - + " }\n" - + "}"); - assertThat(fromJson).isNotNull(); - assertThat(fromJson.data.str).isEqualTo("test"); - assertThat(fromJson.data.val).isEqualTo(42); - - String toJson = adapter.toJson(fromJson); - assertThat(toJson).isEqualTo("{\"data\":{\"1\":{\"2\":{\"str\":\"test\",\"val\":42}}}}"); - } - - @Test public void arrayOfObjects() throws Exception { - JsonAdapter> adapter = moshi.adapter( - Types.newParameterizedType(List.class, Data2.class)); - - List fromJson = adapter.fromJson("[\n" - + " {\n" - + " \"data\": {\n" - + " \"1\": {\n" - + " \"2\": {\n" - + " \"str\": \"funny\",\n" - + " \"val\": 42\n" - + " }\n" - + " }\n" - + " }\n" - + " },\n" - + " {\n" - + " \"data\": {\n" - + " \"1\": {\n" - + " \"2\": {\n" - + " \"str\": \"prime\",\n" - + " \"val\": 43\n" - + " }\n" - + " }\n" - + " }\n" - + " }\n" - + "]"); - assertThat(fromJson.get(0).data.str).isEqualTo("funny"); - assertThat(fromJson.get(0).data.val).isEqualTo(42); - assertThat(fromJson.get(1).data.str).isEqualTo("prime"); - assertThat(fromJson.get(1).data.val).isEqualTo(43); - - String toJson = adapter.toJson(fromJson); - assertThat(toJson).isEqualTo("[" - + "{\"data\":{\"1\":{\"2\":{\"str\":\"funny\",\"val\":42}}}}," - + "{\"data\":{\"1\":{\"2\":{\"str\":\"prime\",\"val\":43}}}}" - + "]"); - } - - @Test public void failOnNotFound() throws Exception { - JsonAdapter adapter = moshi.adapter(Data2.class); - - try { - adapter.fromJson("{\n" - + " \"data\": {\n" - + " \"1\": {\n" - + " \"2\": null\n" - + " }\n" - + " }\n" - + "}"); - fail(); - } catch (JsonDataException ex) { - assertThat(ex).hasMessage( - "Wrapped Json expected at path: [1, 2]. Found null at $.data.1.2"); - } - } - - @Test public void failOnNotFound2() throws Exception { - JsonAdapter adapter = moshi.adapter(Data2.class); - - try { - adapter.fromJson("{\n" - + " \"data\": {\n" - + " \"1\": null\n" - + " }\n" - + "}"); - fail(); - } catch (JsonDataException ex) { - assertThat(ex).hasMessage( - "Wrapped Json expected at path: [1, 2]. Found null at $.data.1"); - } - } - - @Test public void failOnNotFoundFalse() throws Exception { - JsonAdapter adapter = moshi.adapter(String.class, - Collections.singleton(Wrapped.Factory.create(false, "one"))); - - String fromJson = adapter.fromJson("{\"one\":null}"); - assertThat(fromJson).isEqualTo(null); - } - - @Test public void notNullSafe() throws Exception { - JsonAdapter adapter = moshi.adapter(Data2.class); - - try { - adapter.fromJson("{\n" - + " \"data\": null\n" - + "}"); - fail(); - } catch (JsonDataException expected) { - } - - Data2 data2 = new Data2(); - String toJson = adapter.toJson(data2); - assertThat(toJson).isEqualTo("{}"); - - toJson = adapter.serializeNulls().toJson(data2); - assertThat(toJson).isEqualTo("{\"data\":{\"1\":{\"2\":null}}}"); - } - - @Test public void fromJsonSkipsNonPathValues() throws Exception { - JsonAdapter adapter = moshi.adapter(Data2.class); - - Data2 fromJson = adapter.fromJson("{\n" - + " \"data\": {\n" - + " \"should_be_skipped\": null,\n" - + " \"1\": {\n" - + " \"2\": {\n" - + " \"str\": \"works\",\n" - + " \"val\": 11\n" - + " }\n" - + " }\n" - + "\n" - + " }\n" - + "}"); - - assertThat(fromJson.data.str).isEqualTo("works"); - assertThat(fromJson.data.val).isEqualTo(11); - } - - @Test public void fromJsonRemainingPathValues() throws Exception { - JsonAdapter adapter = moshi.adapter(Data2.class); - - Data2 fromJson = adapter.fromJson("{\n" - + " \"data\": {\n" - + " \"1\": {\n" - + " \"2\": {\n" - + " \"str\": \"works\",\n" - + " \"val\": 11\n" - + " }\n" - + " },\n" - + " \"should_be_skipped1\": null,\n" - + " \"should_be_skipped2\": null\n" - + " }\n" - + "}"); - - assertThat(fromJson.data.str).isEqualTo("works"); - assertThat(fromJson.data.val).isEqualTo(11); - } - - @Test public void fromJsonOnIncorrectPath() throws Exception { - JsonAdapter adapter = moshi.adapter(Data2.class); - - try { - adapter.fromJson("{\n" - + " \"data\": {\n" - + " \"2\": {\n" - + " \"1\": null\n" - + " }\n" - + " }\n" - + "}"); - fail(); - } catch (JsonDataException e) { - assertThat(e).hasMessage("Wrapped Json expected at path: [1, 2]. Actual: $.data"); - } - } - - @Test public void fromJsonDoesNotSwallowIOExceptions() throws Exception { - JsonAdapter adapter = moshi.adapter(Data4.class); - - try { - adapter.fromJson("{\n" - + " \"th\": {\n" - + " \"1\": \"this_will_throw\"\n" - + " }\n" - + "}"); - fail(); - } catch (IOException e) { - assertThat(e).hasMessage("ThrowingAdapter.fromJson"); - } - } - - @Test public void fromJsonDoesNotSwallowJsonEncodingExceptions() throws Exception { - JsonAdapter adapter = moshi.adapter(Data2.class); - - try { - adapter.fromJson("{\n" - + " \"data\": {\n" - + " \"1\": {\n" - + " \"2\": {\n" - + " \"str\": \"valid\",\n" - + " \"val\": NaN\n" - + " }\n" - + " }\n" - + " }\n" - + "}"); - fail(); - } catch (JsonEncodingException e) { - assertThat(e).hasMessage( - "Use JsonReader.setLenient(true) to accept malformed JSON at path $.data.1.2.val"); - } - } - - @Test public void fromJsonDoesNotSwallowJsonDataExceptions() throws Exception { - JsonAdapter adapter = moshi.adapter(Data3.class); - - try { - adapter.fromJson("{\n" - + " \"str\": {\n" - + " \"1\": false\n" - + " }\n" - + "}"); - fail(); - } catch (JsonDataException e) { - assertThat(e).hasMessage("Expected a string but was BOOLEAN at path $.str.1"); - } - } - - @Test public void toJsonDoesNotSwallowExceptions() throws Exception { - JsonAdapter adapter = moshi.adapter(Data4.class); - - Data4 data4 = new Data4(); - data4.th = new Throws(); - try { - adapter.toJson(data4); - fail(); - } catch (Throwable e) { - // Moshi wraps write exceptions in an AssertionError - assertThat(e.getCause()).hasMessage("ThrowingAdapter.toJson"); - } - } - - @Test public void factoryMaintainsOtherAnnotations() throws Exception { - JsonAdapter adapter = moshi.adapter(Data3.class); - - Data3 fromJson = adapter.fromJson("{\n" - + " \"str\": {\n" - + " \"1\": \"test\"\n" - + " }\n" - + "}"); - assertThat(fromJson.str).isEqualTo("testCustom"); - - String toJson = adapter.toJson(fromJson); - assertThat(toJson).isEqualTo("{\"str\":{\"1\":\"test\"}}"); - } - - @Test public void toStringReflectsInnerAdapter() throws Exception { - JsonAdapter adapter = moshi.adapter(String.class, - Collections.singleton(Wrapped.Factory.create("1", "2"))); - assertThat(adapter.toString()) - .isEqualTo("JsonAdapter(String).nullSafe().wrapped([1, 2]).failOnNotFound()"); - - JsonAdapter failingAdapter = moshi.adapter(String.class, - Collections.singleton(Wrapped.Factory.create(false, "1", "2"))); - assertThat(failingAdapter.toString()) - .isEqualTo("JsonAdapter(String).nullSafe().wrapped([1, 2])"); - } - - @Test - public void wrappedFactoryRespectsEquals() throws Exception { - Wrapped wrapped1 = Wrapped.Factory.create("one", "two", "three"); - Wrapped wrapped2 = Wrapped.Factory.create("one", "two", "three"); - Wrapped wrapped3 = Wrapped.Factory.create("one", "two", "four"); - - assertThat(wrapped1).isEqualTo(wrapped2); - assertThat(wrapped1.hashCode()).isEqualTo(wrapped2.hashCode()); - assertThat(wrapped1.toString()).isEqualTo(wrapped2.toString()); - - assertThat(wrapped1).isNotEqualTo(wrapped3); - assertThat(wrapped1.hashCode()).isNotEqualTo(wrapped3.hashCode()); - assertThat(wrapped1.toString()).isNotEqualTo(wrapped3.toString()); - } - - @Test public void checkWrappedFactoryConstructorThrows() throws Exception { - PrivateConstructorChecker - .forClass(Wrapped.Factory.class) - .expectedTypeOfException(AssertionError.class) - .expectedExceptionMessage("No instances.") - .check(); - } - - @Test public void factoryFetchesWrappedFromDelegate() throws Exception { - JsonAdapter adapter = moshi.adapter(Data5.class); - - Data5 fromJson = adapter.fromJson("{\n" - + " \"str\": {\n" - + " \"1\": \"test\"\n" - + " }\n" - + "}"); - assertThat(fromJson.str).isEqualTo("test"); - - String toJson = adapter.toJson(fromJson); - assertThat(toJson).isEqualTo("{\"str\":{\"1\":\"test\"}}"); - } - - private static class Data1 { - String str; - int val; - } - - private static class Data2 { - @Wrapped(path = { "1", "2" }) Data1 data; - } - - private static class Data3 { - @Custom - @Wrapped(path = "1") String str; - } - - private static class Data4 { - @Wrapped(path = "1") Throws th; - } - - private static class Data5 { - @WrappedDelegate String str; - } - private static class Throws { - } - - @JsonQualifier - @Wrapped(path = "1") - @Retention(RetentionPolicy.RUNTIME) - @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER }) - @interface WrappedDelegate { } - - /** String adapter, that will throw on read and write. */ - private static final class ThrowingAdapter { - @FromJson Throws fromJson(String str) throws IOException { - throw new IOException("ThrowingAdapter.fromJson"); - } - - @ToJson String toJson(Throws th) throws IOException { - throw new IOException("ThrowingAdapter.toJson"); - } - } -} From f25164e3785279714ab003e829ba2c8fb2b5b44a Mon Sep 17 00:00:00 2001 From: amanarora12 Date: Tue, 28 Jun 2022 14:00:50 +0530 Subject: [PATCH 2/7] Update dependencies and add kotlin --- build.gradle | 46 +++++++++++++++++++++++++++++---------------- dependencies.gradle | 8 ++------ 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/build.gradle b/build.gradle index 647d8eb..309493a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,19 @@ buildscript { + ext.kotlin_version = '1.6.21' repositories { mavenCentral() - maven { url 'https://jitpack.io' } + maven { + url 'https://jitpack.io' + } + maven { + url "https://plugins.gradle.org/m2/" + } } // Needed to use auto-value-moshi in tests dependencies { - classpath 'com.github.tbroyer:gradle-apt-plugin:v0.12' + classpath "net.ltgt.gradle:gradle-apt-plugin:0.21" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -15,6 +22,7 @@ repositories { } apply plugin: 'net.ltgt.apt-idea' +apply plugin: 'kotlin' apply plugin: 'java' apply from: rootProject.file('dependencies.gradle') @@ -34,18 +42,24 @@ sourceSets { } dependencies { - compile moshi - - testCompile junit - testCompile assertJ - testCompile privateConstructorChecker - testCompile retrofit - testCompile retrofitMoshiConverter - testCompile mockWebServer - testCompile rxJava2 - - // This is needed to test integration with auto-value-moshi - testCompileOnly autoValueMoshiAnnotations - testCompileOnly autoValueAnnotations - testApt autoValueMoshi + implementation moshi + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" + + testImplementation junit + testImplementation assertJ + testImplementation privateConstructorChecker + testImplementation retrofit + testImplementation retrofitMoshiConverter + testImplementation mockWebServer + testImplementation rxJava2 +} +compileKotlin { + kotlinOptions { + jvmTarget = "11" + } +} +compileTestKotlin { + kotlinOptions { + jvmTarget = "11" + } } diff --git a/dependencies.gradle b/dependencies.gradle index 3950370..24129a4 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,10 +1,10 @@ ext { - javaVersion = JavaVersion.VERSION_1_7 + javaVersion = JavaVersion.VERSION_11 ci = 'true'.equals(System.getenv('CI')) /* Dependencies */ - moshi = 'com.squareup.moshi:moshi:1.5.0' + moshi = 'com.squareup.moshi:moshi:1.13.0' /* Testing */ junit = 'junit:junit:4.12' @@ -14,8 +14,4 @@ ext { mockWebServer = 'com.squareup.okhttp3:mockwebserver:3.4.1' privateConstructorChecker = 'com.pushtorefresh.java-private-constructor-checker:checker:1.2.0' rxJava2 = 'io.reactivex.rxjava2:rxjava:2.0.3' - - autoValueMoshi = 'com.ryanharter.auto.value:auto-value-moshi:0.4.2' - autoValueMoshiAnnotations = 'com.ryanharter.auto.value:auto-value-moshi-annotations:0.4.2' - autoValueAnnotations = 'com.jakewharton.auto.value:auto-value-annotations:1.3' } From ea265bf5d8a65bb8ab0d539124e57b2e7e5b4396 Mon Sep 17 00:00:00 2001 From: amanarora12 Date: Tue, 28 Jun 2022 14:01:24 +0530 Subject: [PATCH 3/7] Update gradle version --- gradle/wrapper/gradle-wrapper.properties | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8de55b6..1b16c34 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Mon Oct 09 10:31:26 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.2.1-all.zip From 8518eec382c22f2a3dc62c03386a51fc07f9c24a Mon Sep 17 00:00:00 2001 From: amanarora12 Date: Tue, 28 Jun 2022 14:02:55 +0530 Subject: [PATCH 4/7] Rename .java to .kt --- .../moshi/adapters/{DeserializeOnly.java => DeserializeOnly.kt} | 0 .../moshi/adapters/{FallbackOnNull.java => FallbackOnNull.kt} | 0 ...allbackOnNullJsonAdapter.java => FallbackOnNullJsonAdapter.kt} | 0 .../{TransientJsonAdapter.java => TransientJsonAdapter.kt} | 0 src/main/java/com/serjltt/moshi/adapters/{Util.java => Util.kt} | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename src/main/java/com/serjltt/moshi/adapters/{DeserializeOnly.java => DeserializeOnly.kt} (100%) rename src/main/java/com/serjltt/moshi/adapters/{FallbackOnNull.java => FallbackOnNull.kt} (100%) rename src/main/java/com/serjltt/moshi/adapters/{FallbackOnNullJsonAdapter.java => FallbackOnNullJsonAdapter.kt} (100%) rename src/main/java/com/serjltt/moshi/adapters/{TransientJsonAdapter.java => TransientJsonAdapter.kt} (100%) rename src/main/java/com/serjltt/moshi/adapters/{Util.java => Util.kt} (100%) diff --git a/src/main/java/com/serjltt/moshi/adapters/DeserializeOnly.java b/src/main/java/com/serjltt/moshi/adapters/DeserializeOnly.kt similarity index 100% rename from src/main/java/com/serjltt/moshi/adapters/DeserializeOnly.java rename to src/main/java/com/serjltt/moshi/adapters/DeserializeOnly.kt diff --git a/src/main/java/com/serjltt/moshi/adapters/FallbackOnNull.java b/src/main/java/com/serjltt/moshi/adapters/FallbackOnNull.kt similarity index 100% rename from src/main/java/com/serjltt/moshi/adapters/FallbackOnNull.java rename to src/main/java/com/serjltt/moshi/adapters/FallbackOnNull.kt diff --git a/src/main/java/com/serjltt/moshi/adapters/FallbackOnNullJsonAdapter.java b/src/main/java/com/serjltt/moshi/adapters/FallbackOnNullJsonAdapter.kt similarity index 100% rename from src/main/java/com/serjltt/moshi/adapters/FallbackOnNullJsonAdapter.java rename to src/main/java/com/serjltt/moshi/adapters/FallbackOnNullJsonAdapter.kt diff --git a/src/main/java/com/serjltt/moshi/adapters/TransientJsonAdapter.java b/src/main/java/com/serjltt/moshi/adapters/TransientJsonAdapter.kt similarity index 100% rename from src/main/java/com/serjltt/moshi/adapters/TransientJsonAdapter.java rename to src/main/java/com/serjltt/moshi/adapters/TransientJsonAdapter.kt diff --git a/src/main/java/com/serjltt/moshi/adapters/Util.java b/src/main/java/com/serjltt/moshi/adapters/Util.kt similarity index 100% rename from src/main/java/com/serjltt/moshi/adapters/Util.java rename to src/main/java/com/serjltt/moshi/adapters/Util.kt From 592ba6ffe108dcab7084faf95b76c57097447106 Mon Sep 17 00:00:00 2001 From: amanarora12 Date: Tue, 28 Jun 2022 14:02:55 +0530 Subject: [PATCH 5/7] Convert java adapters to kotlin --- .../serjltt/moshi/adapters/DeserializeOnly.kt | 69 ++++--- .../serjltt/moshi/adapters/FallbackOnNull.kt | 168 +++++++++--------- .../adapters/FallbackOnNullJsonAdapter.kt | 87 +++++---- .../java/com/serjltt/moshi/adapters/Pair.java | 12 -- .../moshi/adapters/TransientJsonAdapter.kt | 69 ++++--- .../java/com/serjltt/moshi/adapters/Util.kt | 95 +++++----- 6 files changed, 232 insertions(+), 268 deletions(-) delete mode 100644 src/main/java/com/serjltt/moshi/adapters/Pair.java diff --git a/src/main/java/com/serjltt/moshi/adapters/DeserializeOnly.kt b/src/main/java/com/serjltt/moshi/adapters/DeserializeOnly.kt index 3128e0d..ab87d93 100644 --- a/src/main/java/com/serjltt/moshi/adapters/DeserializeOnly.kt +++ b/src/main/java/com/serjltt/moshi/adapters/DeserializeOnly.kt @@ -1,44 +1,43 @@ -package com.serjltt.moshi.adapters; +package com.serjltt.moshi.adapters -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonQualifier; -import com.squareup.moshi.Moshi; -import com.squareup.moshi.Types; -import java.lang.annotation.Annotation; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Type; -import java.util.Set; +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonQualifier +import com.squareup.moshi.Moshi +import com.squareup.moshi.Types /** * Indicates that the annotated field may only be deserialized. * - *

To leverage from {@link DeserializeOnly} {@link DeserializeOnly#ADAPTER_FACTORY} must be - * added to your {@linkplain Moshi Moshi instance}: * - *


- *   Moshi moshi = new Moshi.Builder()
- *      .add(DeserializeOnly.ADAPTER_FACTORY)
- *      .build();
- * 
+ * To leverage from [DeserializeOnly] [DeserializeOnly.ADAPTER_FACTORY] must be + * added to your [Moshi instance][Moshi]: + * + *
`
+ * Moshi moshi = new Moshi.Builder()
+ * .add(DeserializeOnly.ADAPTER_FACTORY)
+ * .build();
+`
* */ -@Documented +@MustBeDocumented @JsonQualifier -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.FIELD, ElementType.METHOD }) -public @interface DeserializeOnly { - /** Builds an adapter that can process a types annotated with {@link DeserializeOnly}. */ - JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() { - @Override public JsonAdapter create(Type type, Set annotations, - Moshi moshi) { - Set nextAnnotations = - Types.nextAnnotations(annotations, DeserializeOnly.class); - if (nextAnnotations == null) return null; - - return new TransientJsonAdapter<>(moshi.adapter(type, nextAnnotations), false, true); +@Retention(AnnotationRetention.RUNTIME) +@Target( + AnnotationTarget.FIELD, + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER +) +annotation class DeserializeOnly { + companion object { + /** Builds an adapter that can process a types annotated with [DeserializeOnly]. */ + @JvmField + val ADAPTER_FACTORY = JsonAdapter.Factory { type, annotations, moshi -> + val nextAnnotations = Types.nextAnnotations(annotations, DeserializeOnly::class.java) + ?: return@Factory null + TransientJsonAdapter(moshi.adapter(type, nextAnnotations), + serialize = false, + deserialize = true + ) + } } - }; -} +} \ No newline at end of file diff --git a/src/main/java/com/serjltt/moshi/adapters/FallbackOnNull.kt b/src/main/java/com/serjltt/moshi/adapters/FallbackOnNull.kt index b5cb980..3eeb94d 100644 --- a/src/main/java/com/serjltt/moshi/adapters/FallbackOnNull.kt +++ b/src/main/java/com/serjltt/moshi/adapters/FallbackOnNull.kt @@ -13,100 +13,92 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.serjltt.moshi.adapters; +package com.serjltt.moshi.adapters -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonQualifier; -import com.squareup.moshi.Moshi; -import com.squareup.moshi.Types; -import java.lang.annotation.Annotation; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Method; -import java.lang.reflect.Type; -import java.util.Set; -import java.util.Locale; - -import static com.serjltt.moshi.adapters.Util.nextAnnotations; +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonQualifier +import com.squareup.moshi.Moshi +import com.squareup.moshi.Types +import java.lang.reflect.Type +import java.util.Locale /** - * Indicates that the annotated field may be {@code null} in the json source and thus requires a + * Indicates that the annotated field may be `null` in the json source and thus requires a * fallback value. * - *

To leverage from {@linkplain FallbackOnNull} {@linkplain FallbackOnNull#ADAPTER_FACTORY} - * must be added to your {@linkplain Moshi Moshi instance}: * - *


- *   Moshi moshi = new Moshi.Builder()
- *      .add(FallbackOnNull.ADAPTER_FACTORY)
- *      .build();
- * 
+ * To leverage from [FallbackOnNull] [FallbackOnNull.ADAPTER_FACTORY] + * must be added to your [Moshi instance][Moshi]: + * + *
`
+ * Moshi moshi = new Moshi.Builder()
+ * .add(FallbackOnNull.ADAPTER_FACTORY)
+ * .build();
+`
* */ -@Documented +@MustBeDocumented @JsonQualifier -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE }) -public @interface FallbackOnNull { - /** Fallback value for {@code boolean} primitives. Default: {@code false}. */ - boolean fallbackBoolean() default false; - - /** Fallback value for {@code byte} primitives. Default: {@code Byte.MIN_VALUE}. */ - byte fallbackByte() default Byte.MIN_VALUE; - - /** Fallback value for {@code char} primitives. Default: {@code Character.MIN_VALUE}. */ - char fallbackChar() default Character.MIN_VALUE; - - /** Fallback value for {@code double} primitives. Default: {@code Double.MIN_VALUE}. */ - double fallbackDouble() default Double.MIN_VALUE; - - /** Fallback value for {@code float} primitives. Default: {@code Float.MIN_VALUE}. */ - float fallbackFloat() default Float.MIN_VALUE; - - /** Fallback value for {@code int} primitives. Default: {@code Integer.MIN_VALUE}. */ - int fallbackInt() default Integer.MIN_VALUE; - - /** Fallback value for {@code long} primitives. Default: {@code Long.MIN_VALUE}. */ - long fallbackLong() default Long.MIN_VALUE; - - /** Fallback value for {@code short} primitives. Default: {@code Short.MIN_VALUE}. */ - short fallbackShort() default Short.MIN_VALUE; - - /** Builds an adapter that can process a types annotated with {@link FallbackOnNull}. */ - JsonAdapter.Factory ADAPTER_FACTORY = new JsonAdapter.Factory() { - @Override public JsonAdapter create(Type type, Set annotations, - Moshi moshi) { - Pair> nextAnnotations = - nextAnnotations(annotations, FallbackOnNull.class); - if (nextAnnotations == null) return null; - - Class rawType = Types.getRawType(type); - if (!FallbackOnNullJsonAdapter.PRIMITIVE_CLASSES.contains(rawType)) return null; - - String fallbackType = fallbackType(rawType); - Object fallback = retrieveFallback(nextAnnotations.first, fallbackType); - - return new FallbackOnNullJsonAdapter<>(moshi.adapter(type, nextAnnotations.second), - fallback, fallbackType); - } - - /** Invokes the appropriate fallback method based on the {@code fallbackType}. */ - private Object retrieveFallback(FallbackOnNull annotation, String fallbackType) { - try { - Method fallbackMethod = FallbackOnNull.class.getMethod(fallbackType); - return fallbackMethod.invoke(annotation); - } catch (Exception e) { - throw new AssertionError(e); - } - } - - /** Constructs the appropriate fallback method name based on the {@code rawType}. */ - private String fallbackType(Class rawType) { - String typeName = rawType.getSimpleName(); - String methodSuffix = typeName.substring(0, 1).toUpperCase(Locale.US) + typeName.substring(1); - return "fallback" + methodSuffix; +@kotlin.annotation.Retention(AnnotationRetention.RUNTIME) +@Target( + AnnotationTarget.FIELD, + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.ANNOTATION_CLASS +) +annotation class FallbackOnNull( + /** Fallback value for `boolean` primitives. Default: `false`. */ + val fallbackBoolean: Boolean = false, + /** Fallback value for `byte` primitives. Default: `Byte.MIN_VALUE`. */ + val fallbackByte: Byte = Byte.MIN_VALUE, + /** Fallback value for `char` primitives. Default: `Character.MIN_VALUE`. */ + val fallbackChar: Char = Character.MIN_VALUE, + /** Fallback value for `double` primitives. Default: `Double.MIN_VALUE`. */ + val fallbackDouble: Double = Double.MIN_VALUE, + /** Fallback value for `float` primitives. Default: `Float.MIN_VALUE`. */ + val fallbackFloat: Float = Float.MIN_VALUE, + /** Fallback value for `int` primitives. Default: `Integer.MIN_VALUE`. */ + val fallbackInt: Int = Int.MIN_VALUE, + /** Fallback value for `long` primitives. Default: `Long.MIN_VALUE`. */ + val fallbackLong: Long = Long.MIN_VALUE, + /** Fallback value for `short` primitives. Default: `Short.MIN_VALUE`. */ + val fallbackShort: Short = Short.MIN_VALUE +) { + companion object { + /** Builds an adapter that can process a types annotated with [FallbackOnNull]. */ + @JvmField + val ADAPTER_FACTORY: JsonAdapter.Factory = object : JsonAdapter.Factory { + override fun create( + type: Type, annotations: Set, moshi: Moshi + ): JsonAdapter<*>? { + val nextAnnotations = Util.nextAnnotations(annotations, FallbackOnNull::class.java) + ?: return null + val rawType = Types.getRawType(type) + if (!FallbackOnNullJsonAdapter.PRIMITIVE_CLASSES.contains(rawType)) return null + val fallbackType = fallbackType(rawType) + val fallback = retrieveFallback(nextAnnotations.first, fallbackType) + return FallbackOnNullJsonAdapter( + moshi.adapter(type, nextAnnotations.second), fallback, fallbackType + ) + } + + /** Invokes the appropriate fallback method based on the `fallbackType`. */ + private fun retrieveFallback(annotation: FallbackOnNull, fallbackType: String): Any { + return try { + val fallbackMethod = FallbackOnNull::class.java.getMethod(fallbackType) + fallbackMethod.invoke(annotation) + } catch (e: Exception) { + throw AssertionError(e) + } + } + + /** Constructs the appropriate fallback method name based on the `rawType`. */ + private fun fallbackType(rawType: Class<*>): String { + val typeName: String = rawType.simpleName + val methodSuffix: String = + typeName.substring(0, 1).uppercase(Locale.US) + typeName.substring(1) + return "fallback$methodSuffix" + } + } } - }; -} +} \ No newline at end of file diff --git a/src/main/java/com/serjltt/moshi/adapters/FallbackOnNullJsonAdapter.kt b/src/main/java/com/serjltt/moshi/adapters/FallbackOnNullJsonAdapter.kt index 7f8e7ed..4a03fb4 100644 --- a/src/main/java/com/serjltt/moshi/adapters/FallbackOnNullJsonAdapter.kt +++ b/src/main/java/com/serjltt/moshi/adapters/FallbackOnNullJsonAdapter.kt @@ -13,57 +13,54 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.serjltt.moshi.adapters; +package com.serjltt.moshi.adapters -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonReader; -import com.squareup.moshi.JsonWriter; -import java.io.IOException; -import java.util.LinkedHashSet; -import java.util.Set; +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonReader +import com.squareup.moshi.JsonWriter +import java.io.IOException +import java.util.LinkedHashSet /** - * {@linkplain JsonAdapter} that fallbacks to a default value of a primitive field annotated with - * {@linkplain FallbackOnNull}. + * [JsonAdapter] that fallbacks to a default value of a primitive field annotated with + * [FallbackOnNull]. */ -final class FallbackOnNullJsonAdapter extends JsonAdapter { - /** Set of primitives classes that are supported by this adapter. */ - static final Set> PRIMITIVE_CLASSES = new LinkedHashSet<>(); +internal class FallbackOnNullJsonAdapter( + val delegate: JsonAdapter, + val fallback: T, + private val fallbackType: String +) : JsonAdapter() { + companion object { + /** Set of primitives classes that are supported by **this** adapter. */ + @JvmField val PRIMITIVE_CLASSES: MutableSet?> = LinkedHashSet() - static { - PRIMITIVE_CLASSES.add(boolean.class); - PRIMITIVE_CLASSES.add(byte.class); - PRIMITIVE_CLASSES.add(char.class); - PRIMITIVE_CLASSES.add(double.class); - PRIMITIVE_CLASSES.add(float.class); - PRIMITIVE_CLASSES.add(int.class); - PRIMITIVE_CLASSES.add(long.class); - PRIMITIVE_CLASSES.add(short.class); - } - - final JsonAdapter delegate; - final T fallback; - final String fallbackType; - - FallbackOnNullJsonAdapter(JsonAdapter delegate, T fallback, String fallbackType) { - this.delegate = delegate; - this.fallback = fallback; - this.fallbackType = fallbackType; - } + init { + PRIMITIVE_CLASSES.add(Boolean::class.javaPrimitiveType) + PRIMITIVE_CLASSES.add(Byte::class.javaPrimitiveType) + PRIMITIVE_CLASSES.add(Char::class.javaPrimitiveType) + PRIMITIVE_CLASSES.add(Double::class.javaPrimitiveType) + PRIMITIVE_CLASSES.add(Float::class.javaPrimitiveType) + PRIMITIVE_CLASSES.add(Int::class.javaPrimitiveType) + PRIMITIVE_CLASSES.add(Long::class.javaPrimitiveType) + PRIMITIVE_CLASSES.add(Short::class.javaPrimitiveType) + } + } - @Override public T fromJson(JsonReader reader) throws IOException { - if (reader.peek() == JsonReader.Token.NULL) { - reader.nextNull(); // We need to consume the value. - return fallback; + @Throws(IOException::class) + override fun fromJson(reader: JsonReader): T? { + if (reader.peek() == JsonReader.Token.NULL) { + reader.nextNull() // We need to consume the value. + return fallback + } + return delegate.fromJson(reader) } - return delegate.fromJson(reader); - } - @Override public void toJson(JsonWriter writer, T value) throws IOException { - delegate.toJson(writer, value); - } + @Throws(IOException::class) + override fun toJson(writer: JsonWriter, value: T?) { + delegate.toJson(writer, value) + } - @Override public String toString() { - return delegate + ".fallbackOnNull(" + fallbackType + '=' + fallback + ')'; - } -} + override fun toString(): String { + return "$delegate.fallbackOnNull($fallbackType=$fallback)" + } +} \ No newline at end of file diff --git a/src/main/java/com/serjltt/moshi/adapters/Pair.java b/src/main/java/com/serjltt/moshi/adapters/Pair.java deleted file mode 100644 index a5a85c9..0000000 --- a/src/main/java/com/serjltt/moshi/adapters/Pair.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.serjltt.moshi.adapters; - -/** A simple pair data class. */ -final class Pair { - final F first; - final S second; - - Pair(F first, S second) { - this.first = first; - this.second = second; - } -} diff --git a/src/main/java/com/serjltt/moshi/adapters/TransientJsonAdapter.kt b/src/main/java/com/serjltt/moshi/adapters/TransientJsonAdapter.kt index 875e2d3..4730822 100644 --- a/src/main/java/com/serjltt/moshi/adapters/TransientJsonAdapter.kt +++ b/src/main/java/com/serjltt/moshi/adapters/TransientJsonAdapter.kt @@ -1,47 +1,40 @@ -package com.serjltt.moshi.adapters; +package com.serjltt.moshi.adapters -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonReader; -import com.squareup.moshi.JsonWriter; -import java.io.IOException; +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonReader +import com.squareup.moshi.JsonWriter +import java.io.IOException /** - * {@link JsonAdapter} with transient functionality. The consumer can decide to ether serialize or + * [JsonAdapter] with transient functionality. The consumer can decide to ether serialize or * deserialize, or make the adapter completely transient. */ -final class TransientJsonAdapter extends JsonAdapter { - private final JsonAdapter delegate; - private final boolean serialize; - private final boolean deserialize; - - TransientJsonAdapter(JsonAdapter delegate, boolean serialize, boolean deserialize) { - this.delegate = delegate; - this.serialize = serialize; - this.deserialize = deserialize; - } - - @Override public T fromJson(JsonReader reader) throws IOException { - if (deserialize) { - return delegate.fromJson(reader); - } else { - reader.skipValue(); - return null; +internal class TransientJsonAdapter( + private val delegate: JsonAdapter, + private val serialize: Boolean, + private val deserialize: Boolean +) : JsonAdapter() { + @Throws(IOException::class) + override fun fromJson(reader: JsonReader): T? { + return if (deserialize) { + delegate.fromJson(reader) + } else { + reader.skipValue() + null + } } - } - @Override public void toJson(JsonWriter writer, T value) throws IOException { - if (serialize) { - delegate.toJson(writer, value); - } else { - // We'll need to consume this property otherwise we'll get an IllegalArgumentException. - delegate.toJson(writer, null); + @Throws(IOException::class) + override fun toJson(writer: JsonWriter, value: T?) { + if (serialize) { + delegate.toJson(writer, value) + } else { + // We'll need to consume this property otherwise we'll get an IllegalArgumentException. + delegate.toJson(writer, null) + } } - } - @Override public String toString() { - return delegate + ((serialize && deserialize) - ? "" : serialize - ? ".serializeOnly()" : deserialize - ? ".deserializeOnly()" : ".transient()"); - } -} + override fun toString(): String { + return delegate.toString() + if (serialize && deserialize) "" else if (serialize) ".serializeOnly()" else if (deserialize) ".deserializeOnly()" else ".transient()" + } +} \ No newline at end of file diff --git a/src/main/java/com/serjltt/moshi/adapters/Util.kt b/src/main/java/com/serjltt/moshi/adapters/Util.kt index 9e99e00..0ee113f 100644 --- a/src/main/java/com/serjltt/moshi/adapters/Util.kt +++ b/src/main/java/com/serjltt/moshi/adapters/Util.kt @@ -14,58 +14,53 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.serjltt.moshi.adapters; +package com.serjltt.moshi.adapters -import com.squareup.moshi.JsonQualifier; -import java.lang.annotation.Annotation; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Set; +import com.squareup.moshi.JsonQualifier +import java.util.Collections +import java.util.LinkedHashSet +import kotlin.Pair -final class Util { - /** - * Checks if {@code annotations} contains {@code jsonQualifier}. - * Returns a pair containing the subset of {@code annotations} without {@code jsonQualifier} - * and the {@code jsonQualified} instance, or null if {@code annotations} does not contain - * {@code jsonQualifier}. - */ - public static Pair> nextAnnotations( - Set annotations, Class jsonQualifier) { - if (!jsonQualifier.isAnnotationPresent(JsonQualifier.class)) { - throw new IllegalArgumentException(jsonQualifier + " is not a JsonQualifier."); +object Util { + /** + * Checks if `annotations` contains `jsonQualifier`. + * Returns a pair containing the subset of `annotations` without `jsonQualifier` + * and the `jsonQualified` instance, or null if `annotations` does not contain + * `jsonQualifier`. + */ + fun nextAnnotations( + annotations: Set, jsonQualifier: Class + ): Pair>? { + require(jsonQualifier.isAnnotationPresent(JsonQualifier::class.java)) { "$jsonQualifier is not a JsonQualifier." } + if (annotations.isEmpty()) { + return null + } + for (annotation in annotations) { + if (jsonQualifier == annotation.annotationClass.java) { + val delegateAnnotations: LinkedHashSet = linkedSetOf() + delegateAnnotations.addAll(annotations) + delegateAnnotations.remove(annotation) + return Pair(annotation as A, Collections.unmodifiableSet(delegateAnnotations)) + } + val delegate = findDelegatedAnnotation(annotation, jsonQualifier) + if (delegate != null) { + val delegateAnnotations: LinkedHashSet = linkedSetOf() + delegateAnnotations.addAll(annotations) + delegateAnnotations.remove(annotation) + return Pair(delegate, Collections.unmodifiableSet(delegateAnnotations)) + } + } + return null } - if (annotations.isEmpty()) { - return null; - } - for (Annotation annotation : annotations) { - if (jsonQualifier.equals(annotation.annotationType())) { - Set delegateAnnotations = new LinkedHashSet<>(annotations); - delegateAnnotations.remove(annotation); - //noinspection unchecked Protected by the if statment. - return new Pair<>((A) annotation, Collections.unmodifiableSet(delegateAnnotations)); - } - A delegate = findDelegatedAnnotation(annotation, jsonQualifier); - if (delegate != null) { - Set delegateAnnotations = new LinkedHashSet<>(annotations); - delegateAnnotations.remove(annotation); - return new Pair<>(delegate, Collections.unmodifiableSet(delegateAnnotations)); - } - } - return null; - } - private static A findDelegatedAnnotation( - Annotation annotation, Class jsonQualifier) { - for (Annotation delegatedAnnotation : annotation.annotationType().getAnnotations()) { - if (jsonQualifier.equals(delegatedAnnotation.annotationType())) { - //noinspection unchecked - return (A) delegatedAnnotation; - } + private fun findDelegatedAnnotation( + annotation: Annotation, jsonQualifier: Class + ): A? { + for (delegatedAnnotation in annotation.javaClass.annotations) { + if (jsonQualifier == delegatedAnnotation.annotationClass.java) { + return delegatedAnnotation as A + } + } + return null } - return null; - } - - private Util() { - throw new AssertionError("No instances."); - } -} +} \ No newline at end of file From 9c909c4aceab7bcb415974e52484022f1768b24b Mon Sep 17 00:00:00 2001 From: amanarora12 Date: Tue, 28 Jun 2022 17:25:46 +0530 Subject: [PATCH 6/7] Rename .java to .kt --- ...OnlyJsonAdapterTest.java => DeserializeOnlyJsonAdapterTest.kt} | 0 ...nNullJsonAdapterTest.java => FallbackOnNullJsonAdapterTest.kt} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/unitTest/java/com/serjltt/moshi/adapters/{DeserializeOnlyJsonAdapterTest.java => DeserializeOnlyJsonAdapterTest.kt} (100%) rename src/unitTest/java/com/serjltt/moshi/adapters/{FallbackOnNullJsonAdapterTest.java => FallbackOnNullJsonAdapterTest.kt} (100%) diff --git a/src/unitTest/java/com/serjltt/moshi/adapters/DeserializeOnlyJsonAdapterTest.java b/src/unitTest/java/com/serjltt/moshi/adapters/DeserializeOnlyJsonAdapterTest.kt similarity index 100% rename from src/unitTest/java/com/serjltt/moshi/adapters/DeserializeOnlyJsonAdapterTest.java rename to src/unitTest/java/com/serjltt/moshi/adapters/DeserializeOnlyJsonAdapterTest.kt diff --git a/src/unitTest/java/com/serjltt/moshi/adapters/FallbackOnNullJsonAdapterTest.java b/src/unitTest/java/com/serjltt/moshi/adapters/FallbackOnNullJsonAdapterTest.kt similarity index 100% rename from src/unitTest/java/com/serjltt/moshi/adapters/FallbackOnNullJsonAdapterTest.java rename to src/unitTest/java/com/serjltt/moshi/adapters/FallbackOnNullJsonAdapterTest.kt From 5c732e826a66dafcf78ee0d56ffff26045fa7a11 Mon Sep 17 00:00:00 2001 From: amanarora12 Date: Tue, 28 Jun 2022 17:25:46 +0530 Subject: [PATCH 7/7] Remove @JvmField annotation from DeserializeOnly.kt --- build.gradle | 142 +++-- jacoco.gradle | 2 +- .../serjltt/moshi/adapters/DeserializeOnly.kt | 1 - .../DeserializeOnlyJsonAdapterTest.kt | 105 ++-- .../adapters/FallbackOnNullJsonAdapterTest.kt | 570 ++++++++++-------- 5 files changed, 478 insertions(+), 342 deletions(-) diff --git a/build.gradle b/build.gradle index 309493a..6446ebc 100644 --- a/build.gradle +++ b/build.gradle @@ -1,65 +1,135 @@ buildscript { - ext.kotlin_version = '1.6.21' - repositories { - mavenCentral() - maven { - url 'https://jitpack.io' - } - maven { - url "https://plugins.gradle.org/m2/" + ext.kotlin_version = '1.6.21' + repositories { + mavenCentral() + maven { + url 'https://jitpack.io' + } + maven { + url "https://plugins.gradle.org/m2/" + } } - } - // Needed to use auto-value-moshi in tests - dependencies { - classpath "net.ltgt.gradle:gradle-apt-plugin:0.21" - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } + // Needed to use auto-value-moshi in tests + dependencies { + classpath "net.ltgt.gradle:gradle-apt-plugin:0.21" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.28.3" + } } repositories { - mavenCentral() + mavenCentral() } apply plugin: 'net.ltgt.apt-idea' apply plugin: 'kotlin' apply plugin: 'java' +apply plugin: "com.jfrog.artifactory" +apply plugin: "maven-publish" +apply plugin: 'java-library' +apply plugin: 'kotlin-kapt' apply from: rootProject.file('dependencies.gradle') apply from: rootProject.file('checkstyle.gradle') apply from: rootProject.file('jacoco.gradle') -apply from: rootProject.file('gradle/gradle-mvn-push.gradle') +// sourceCompatibility = javaVersion targetCompatibility = javaVersion sourceSets { - // Setup source sets to split unit and integration tests - test { - java.srcDirs = ['src/unitTest/java', 'src/integrationTest/java'] - resources.srcDirs = ['src/unitTest/resources', 'src/integrationTest/resources'] - } + // Setup source sets to split unit and integration tests + test { + java.srcDirs = ['src/unitTest/java'] + resources.srcDirs = ['src/unitTest/resources'] + } } dependencies { - implementation moshi - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" + implementation moshi + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" + kapt "com.squareup.moshi:moshi-kotlin-codegen:1.13.0" - testImplementation junit - testImplementation assertJ - testImplementation privateConstructorChecker - testImplementation retrofit - testImplementation retrofitMoshiConverter - testImplementation mockWebServer - testImplementation rxJava2 + testImplementation junit + testImplementation assertJ + testImplementation privateConstructorChecker + testImplementation retrofit + testImplementation retrofitMoshiConverter + testImplementation mockWebServer + testImplementation rxJava2 } compileKotlin { - kotlinOptions { - jvmTarget = "11" - } + kotlinOptions { + jvmTarget = "11" + } } compileTestKotlin { - kotlinOptions { - jvmTarget = "11" - } + kotlinOptions { + jvmTarget = "11" + } } +ext.versionName = { -> + def currentTag = 'git tag --points-at HEAD'.execute().in.text.toString().trim() + def currentBranch = 'git rev-parse --abbrev-ref HEAD'.execute().in.text.toString().trim() + def tagRegex = "[0-9.]*[0-9]" + if (!currentTag.isEmpty() && currentTag.matches(tagRegex)) { +// is not empty and is in following format 8.0 + return currentTag + } else { + return currentBranch + '-SNAPSHOT' + } +} + +def libraryGroupId = 'com.meesho.android' +def libraryVersion = versionName() + +task androidSourcesJar(type: Jar) { + archiveClassifier.set('sources') + from sourceSets.main.java.srcDirs +} + + +artifactoryPublish.dependsOn('build') +publishing { + publications { + mavenJava(MavenPublication) { + groupId = libraryGroupId + artifactId = 'moshi-lazy-adapters' + version = libraryVersion + // Tell maven to prepare the generated "*.jar" file for publishing + artifact("$buildDir/libs/moshi-lazy-adapters.jar") + artifact androidSourcesJar + + pom.withXml { + def dependencies = asNode().appendNode('dependencies') + configurations.implementation.allDependencies.each { + def dependency = dependencies.appendNode('dependency') + dependency.appendNode('groupId', it.group) + dependency.appendNode('artifactId', it.name) + dependency.appendNode('version', it.version) + } + } + } + } +} + +artifactory { + //The base Artifactory URL if not overridden by the publisher/resolver + contextUrl = project.properties["JFROG_ARTIFACTORY_URL"] + publish { + repository { + repoKey = libraryVersion.endsWith('-SNAPSHOT') ? project.properties["SNAPSHOT_REPO_NAME"] : + project.properties["RELEASE_REPO_NAME"] + username = project.properties["JFROG_ARTIFACTORY_USERNAME"] + password = project.properties["JFROG_ARTIFACTORY_KEY"] + } + defaults { + // Tell the Artifactory Plugin which artifacts should be published to Artifactory. + publications('mavenJava') + publishArtifacts = true + // Publish generated POM files to Artifactory (true by default) + publishPom = true + } + } +} \ No newline at end of file diff --git a/jacoco.gradle b/jacoco.gradle index 25ee8c3..9253b33 100644 --- a/jacoco.gradle +++ b/jacoco.gradle @@ -1,7 +1,7 @@ apply plugin: 'jacoco' jacoco { - toolVersion = '0.7.7.201606060606' // See http://www.eclemma.org/jacoco/. + toolVersion = '0.8.7' // See http://www.eclemma.org/jacoco/. } jacocoTestReport { diff --git a/src/main/java/com/serjltt/moshi/adapters/DeserializeOnly.kt b/src/main/java/com/serjltt/moshi/adapters/DeserializeOnly.kt index ab87d93..b28454c 100644 --- a/src/main/java/com/serjltt/moshi/adapters/DeserializeOnly.kt +++ b/src/main/java/com/serjltt/moshi/adapters/DeserializeOnly.kt @@ -30,7 +30,6 @@ import com.squareup.moshi.Types annotation class DeserializeOnly { companion object { /** Builds an adapter that can process a types annotated with [DeserializeOnly]. */ - @JvmField val ADAPTER_FACTORY = JsonAdapter.Factory { type, annotations, moshi -> val nextAnnotations = Types.nextAnnotations(annotations, DeserializeOnly::class.java) ?: return@Factory null diff --git a/src/unitTest/java/com/serjltt/moshi/adapters/DeserializeOnlyJsonAdapterTest.kt b/src/unitTest/java/com/serjltt/moshi/adapters/DeserializeOnlyJsonAdapterTest.kt index e0a5a3b..5574164 100644 --- a/src/unitTest/java/com/serjltt/moshi/adapters/DeserializeOnlyJsonAdapterTest.kt +++ b/src/unitTest/java/com/serjltt/moshi/adapters/DeserializeOnlyJsonAdapterTest.kt @@ -1,47 +1,58 @@ -package com.serjltt.moshi.adapters; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.Moshi; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public final class DeserializeOnlyJsonAdapterTest { - // Lazy adapters work only within the context of moshi. - private final Moshi moshi = new Moshi.Builder() - .add(DeserializeOnly.ADAPTER_FACTORY) - .add(new Custom.CustomAdapter()) // We need to check that other annotations are not lost. - .build(); - - @Test public void deserializeOnly() throws Exception { - JsonAdapter adapter = moshi.adapter(Data1.class); - - Data1 fromJson = adapter.fromJson("{\"data\": \"test\"}"); - assertThat(fromJson.data).isEqualTo("test"); - - assertThat(adapter.toJson(fromJson)).isEqualTo("{}"); - } - - @Test public void factoryMaintainsOtherAnnotations() throws Exception { - JsonAdapter adapter = moshi.adapter(Data2.class); - - Data2 fromJson = adapter.fromJson("{\"data\": \"test\"}"); - assertThat(fromJson.data).isEqualTo("testCustom"); - - assertThat(adapter.toJson(fromJson)).isEqualTo("{}"); - } - - @Test public void toStringReflectsInnerAdapter() throws Exception { - JsonAdapter adapter = moshi.adapter(String.class, DeserializeOnly.class); - - assertThat(adapter.toString()).isEqualTo("JsonAdapter(String).nullSafe().deserializeOnly()"); - } - - private static class Data1 { - @DeserializeOnly String data; - } - - private static class Data2 { - @DeserializeOnly @Custom String data; - } -} +package com.serjltt.moshi.adapters + +import com.squareup.moshi.Moshi +import com.serjltt.moshi.adapters.DeserializeOnly +import com.serjltt.moshi.adapters.Custom.CustomAdapter +import kotlin.Throws +import com.squareup.moshi.JsonAdapter +import com.serjltt.moshi.adapters.DeserializeOnlyJsonAdapterTest.Data1 +import com.serjltt.moshi.adapters.DeserializeOnlyJsonAdapterTest.Data2 +import com.serjltt.moshi.adapters.Custom +import org.assertj.core.api.Assertions +import org.junit.Test +import java.lang.Exception + +class DeserializeOnlyJsonAdapterTest { + // Lazy adapters work only within the context of moshi. + private val moshi = Moshi.Builder() + .add(DeserializeOnly.ADAPTER_FACTORY) + .add(CustomAdapter()) // We need to check that other annotations are not lost. + .build() + + @Test + @Throws(Exception::class) + fun deserializeOnly() { + val adapter = moshi.adapter(Data1::class.java) + val fromJson = adapter.fromJson("{\"data\": \"test\"}") + Assertions.assertThat(fromJson!!.data).isEqualTo("test") + Assertions.assertThat(adapter.toJson(fromJson)).isEqualTo("{}") + } + + @Test + @Throws(Exception::class) + fun factoryMaintainsOtherAnnotations() { + val adapter = moshi.adapter(Data2::class.java) + val fromJson = adapter.fromJson("{\"data\": \"test\"}") + Assertions.assertThat(fromJson!!.data).isEqualTo("testCustom") + Assertions.assertThat(adapter.toJson(fromJson)).isEqualTo("{}") + } + + @Test + @Throws(Exception::class) + fun toStringReflectsInnerAdapter() { + val adapter = moshi.adapter(String::class.java, DeserializeOnly::class.java) + Assertions.assertThat(adapter.toString()) + .isEqualTo("JsonAdapter(String).nullSafe().deserializeOnly()") + } + + private class Data1 { + @DeserializeOnly + var data: String? = null + } + + private class Data2 { + @DeserializeOnly + @Custom + var data: String? = null + } +} \ No newline at end of file diff --git a/src/unitTest/java/com/serjltt/moshi/adapters/FallbackOnNullJsonAdapterTest.kt b/src/unitTest/java/com/serjltt/moshi/adapters/FallbackOnNullJsonAdapterTest.kt index e1bb861..c04a42f 100644 --- a/src/unitTest/java/com/serjltt/moshi/adapters/FallbackOnNullJsonAdapterTest.kt +++ b/src/unitTest/java/com/serjltt/moshi/adapters/FallbackOnNullJsonAdapterTest.kt @@ -13,322 +13,378 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.serjltt.moshi.adapters; - -import com.squareup.moshi.FromJson; -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonQualifier; -import com.squareup.moshi.Moshi; -import com.squareup.moshi.ToJson; -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Locale; -import java.util.Set; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public final class FallbackOnNullJsonAdapterTest { - // Lazy adapters work only within the context of moshi. - private final Moshi moshi = new Moshi.Builder() - .add(FallbackOnNull.ADAPTER_FACTORY) - .add(new Multiply.MultiplyAdapter()) - .build(); - - @Test public void booleanFallbacks() throws Exception { - assertForClass(WrapsBool.class, false, true, "{\"first\":false,\"second\":true}"); - } - - private static class WrapsBool implements Wrapper { - @FallbackOnNull boolean first; - @FallbackOnNull(fallbackBoolean = true) boolean second; - - @Override public Boolean first() { - return first; +package com.serjltt.moshi.adapters + +import com.serjltt.moshi.adapters.FallbackOnNull +import com.serjltt.moshi.adapters.FallbackOnNullJsonAdapterTest.Multiply.MultiplyAdapter +import kotlin.Throws +import com.serjltt.moshi.adapters.FallbackOnNullJsonAdapterTest.WrapsBool +import com.serjltt.moshi.adapters.FallbackOnNullJsonAdapterTest.WrapsByte +import com.serjltt.moshi.adapters.FallbackOnNullJsonAdapterTest.WrapsChar +import com.serjltt.moshi.adapters.FallbackOnNullJsonAdapterTest.WrapsDouble +import com.serjltt.moshi.adapters.FallbackOnNullJsonAdapterTest.WrapsFloat +import com.serjltt.moshi.adapters.FallbackOnNullJsonAdapterTest.WrapsInt +import com.serjltt.moshi.adapters.FallbackOnNullJsonAdapterTest.WrapsLong +import com.serjltt.moshi.adapters.FallbackOnNullJsonAdapterTest.WrapsShort +import com.serjltt.moshi.adapters.FallbackOnNullJsonAdapterTest.AnotherInt +import com.serjltt.moshi.adapters.FallbackOnNullJsonAdapterTest.Multiply +import com.serjltt.moshi.adapters.FallbackOnNullJsonAdapterTest +import com.serjltt.moshi.adapters.FallbackOnNullJsonAdapterTest.AndAnotherInt +import com.serjltt.moshi.adapters.FallbackOnNullJsonAdapterTest.AlwaysFallBackToTwoOnNull +import com.squareup.moshi.* +import org.assertj.core.api.Assertions +import org.junit.Test +import java.io.IOException +import java.lang.Exception +import java.lang.annotation.Retention +import java.lang.annotation.RetentionPolicy +import java.util.* + +class FallbackOnNullJsonAdapterTest { + // Lazy adapters work only within the context of moshi. + private val moshi = Moshi.Builder() + .add(FallbackOnNull.ADAPTER_FACTORY) + .add(MultiplyAdapter()) + .build() + + @Test + @Throws(Exception::class) + fun booleanFallbacks() { + assertForClass(WrapsBool::class.java, false, true, "{\"first\":false,\"second\":true}") } - @Override public Boolean second() { - return second; - } - } - - @Test public void byteFallbacks() throws Exception { - assertForClass(WrapsByte.class, Byte.MIN_VALUE, (byte) 42, "{\"first\":128,\"second\":42}"); - } + private class WrapsBool : Wrapper { + @FallbackOnNull + var first = false - private static class WrapsByte implements Wrapper { - @FallbackOnNull byte first; - @FallbackOnNull(fallbackByte = 42) byte second; + @FallbackOnNull(fallbackBoolean = true) + var second = false + override fun first(): Boolean { + return first + } - @Override public Byte first() { - return first; + override fun second(): Boolean { + return second + } } - @Override public Byte second() { - return second; + @Test + @Throws(Exception::class) + fun byteFallbacks() { + assertForClass( + WrapsByte::class.java, + Byte.MIN_VALUE, + 42.toByte(), + "{\"first\":128,\"second\":42}" + ) } - } - @Test public void charFallbacks() throws Exception { - assertForClass(WrapsChar.class, '\u0000', 'a', "{\"first\":\"\\u0000\",\"second\":\"a\"}"); - } + private class WrapsByte : Wrapper { + @FallbackOnNull + var first: Byte = 0 - private static class WrapsChar implements Wrapper { - @FallbackOnNull char first; - @FallbackOnNull(fallbackChar = 'a') char second; + @FallbackOnNull(fallbackByte = 42) + var second: Byte = 0 + override fun first(): Byte { + return first + } - @Override public Character first() { - return first; + override fun second(): Byte { + return second + } } - @Override public Character second() { - return second; + @Test + @Throws(Exception::class) + fun charFallbacks() { + assertForClass( + WrapsChar::class.java, + '\u0000', + 'a', + "{\"first\":\"\\u0000\",\"second\":\"a\"}" + ) } - } - @Test public void doubleFallbacks() throws Exception { - assertForClass(WrapsDouble.class, Double.MIN_VALUE, 12.0, - "{\"first\":4.9E-324,\"second\":12.0}"); - } + @JsonClass(generateAdapter = true) + private class WrapsChar : Wrapper { + @FallbackOnNull + var first = 0.toChar() - private static class WrapsDouble implements Wrapper { - @FallbackOnNull double first; - @FallbackOnNull(fallbackDouble = 12.0) double second; + @FallbackOnNull(fallbackChar = 'a') + var second = 0.toChar() + override fun first(): Char { + return first + } - @Override public Double first() { - return first; + override fun second(): Char { + return second + } } - @Override public Double second() { - return second; + @Test + @Throws(Exception::class) + fun doubleFallbacks() { + assertForClass( + WrapsDouble::class.java, Double.MIN_VALUE, 12.0, + "{\"first\":4.9E-324,\"second\":12.0}" + ) } - } - @Test public void floatFallbacks() throws Exception { - assertForClass(WrapsFloat.class, Float.MIN_VALUE, 16.0f, - "{\"first\":1.4E-45,\"second\":16.0}"); - } + private class WrapsDouble : Wrapper { + @FallbackOnNull + var first = 0.0 - private static class WrapsFloat implements Wrapper { - @FallbackOnNull float first; - @FallbackOnNull(fallbackFloat = 16.0f) float second; + @FallbackOnNull(fallbackDouble = 12.0) + var second = 0.0 + override fun first(): Double { + return first + } - @Override public Float first() { - return first; + override fun second(): Double { + return second + } } - @Override public Float second() { - return second; + @Test + @Throws(Exception::class) + fun floatFallbacks() { + assertForClass( + WrapsFloat::class.java, Float.MIN_VALUE, 16.0f, + "{\"first\":1.4E-45,\"second\":16.0}" + ) } - } - @Test public void intFallbacks() throws Exception { - assertForClass(WrapsInt.class, Integer.MIN_VALUE, -1, "{\"first\":-2147483648,\"second\":-1}"); - } + private class WrapsFloat : Wrapper { + @FallbackOnNull + var first = 0f - @Test public void intFallbacksNoLocaleInfluence() throws Exception { - Locale defaultLocale = Locale.getDefault(); - - Locale.setDefault(new Locale("tr", "TR")); - assertForClass(WrapsInt.class, Integer.MIN_VALUE, -1, "{\"first\":-2147483648,\"second\":-1}"); - - Locale.setDefault(defaultLocale); - } + @FallbackOnNull(fallbackFloat = 16.0f) + var second = 0f + override fun first(): Float { + return first + } - private static class WrapsInt implements Wrapper { - @FallbackOnNull int first; - @FallbackOnNull(fallbackInt = -1) int second; + override fun second(): Float { + return second + } + } - @Override public Integer first() { - return first; + @Test + @Throws(Exception::class) + fun intFallbacks() { + assertForClass( + WrapsInt::class.java, + Int.MIN_VALUE, + -1, + "{\"first\":-2147483648,\"second\":-1}" + ) } - @Override public Integer second() { - return second; + @Test + @Throws(Exception::class) + fun intFallbacksNoLocaleInfluence() { + val defaultLocale = Locale.getDefault() + Locale.setDefault(Locale("tr", "TR")) + assertForClass( + WrapsInt::class.java, + Int.MIN_VALUE, + -1, + "{\"first\":-2147483648,\"second\":-1}" + ) + Locale.setDefault(defaultLocale) } - } - @Test public void longFallbacks() throws Exception { - assertForClass(WrapsLong.class, Long.MIN_VALUE, -113L, - "{\"first\":-9223372036854775808,\"second\":-113}"); - } + private class WrapsInt : Wrapper { + @FallbackOnNull + var first = 0 - private static class WrapsLong implements Wrapper { - @FallbackOnNull long first; - @FallbackOnNull(fallbackLong = -113) long second; + @FallbackOnNull(fallbackInt = -1) + var second = 0 + override fun first(): Int { + return first + } - @Override public Long first() { - return first; + override fun second(): Int { + return second + } } - @Override public Long second() { - return second; + @Test + @Throws(Exception::class) + fun longFallbacks() { + assertForClass( + WrapsLong::class.java, Long.MIN_VALUE, -113L, + "{\"first\":-9223372036854775808,\"second\":-113}" + ) } - } - @Test public void shortFallbacks() throws Exception { - assertForClass(WrapsShort.class, Short.MIN_VALUE, (short) 121, - "{\"first\":-32768,\"second\":121}"); - } + private class WrapsLong : Wrapper { + @FallbackOnNull + var first: Long = 0 - private static class WrapsShort implements Wrapper { - @FallbackOnNull short first; - @FallbackOnNull(fallbackShort = 121) short second; + @FallbackOnNull(fallbackLong = -113) + var second: Long = 0 + override fun first(): Long { + return first + } - @Override public Short first() { - return first; + override fun second(): Long { + return second + } } - @Override public Short second() { - return second; - } - } - - @Test public void factoryMaintainsOtherAnnotations() throws Exception { - JsonAdapter adapter = moshi.adapter(AnotherInt.class); - - AnotherInt fromJson = adapter.fromJson("{\n" - + " \"willFallback\": null,\n" - + " \"willMultiply\": 3\n" - + "}"); - assertThat(fromJson.willFallback).isEqualTo(2); - assertThat(fromJson.willMultiply).isEqualTo(6); - - String toJson = adapter.toJson(fromJson); - // Both values should be serialized by the Multiply json adapter. - assertThat(toJson).isEqualTo("{\"willFallback\":1,\"willMultiply\":3}"); - } - - private static class AnotherInt { - @FallbackOnNull(fallbackInt = 2) @Multiply int willFallback; - @FallbackOnNull(fallbackInt = 2) @Multiply int willMultiply; - } - - @Test public void factoryIgnoresNonPrimitiveTypes() { - List> classes = new ArrayList>() { - { - add(Boolean.class); - add(Byte.class); - add(Character.class); - add(Double.class); - add(Float.class); - add(Integer.class); - add(Long.class); - add(Short.class); - add(String.class); - add(Object.class); - } - }; - - for (Class cls : classes) { - assertThat(FallbackOnNull.ADAPTER_FACTORY.create(cls, ANNOTATIONS, moshi)).isNull(); + @Test + @Throws(Exception::class) + fun shortFallbacks() { + assertForClass( + WrapsShort::class.java, Short.MIN_VALUE, 121.toShort(), + "{\"first\":-32768,\"second\":121}" + ) } - } - @Test public void fallbackOnNullIsDelegated() throws Exception { - JsonAdapter adapter = moshi.adapter(AndAnotherInt.class); + private class WrapsShort : Wrapper { + @FallbackOnNull + var first: Short = 0 - AndAnotherInt fromJson = adapter.fromJson("{\n" - + " \"willFallback\": null\n" - + "}"); - assertThat(fromJson.willFallback).isEqualTo(2); - } - - private static class AndAnotherInt { - @AlwaysFallBackToTwoOnNull int willFallback; - } + @FallbackOnNull(fallbackShort = 121) + var second: Short = 0 + override fun first(): Short { + return first + } - @JsonQualifier - @FallbackOnNull(fallbackInt = 2) - @Retention(RetentionPolicy.RUNTIME) - @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER }) - @interface AlwaysFallBackToTwoOnNull { } + override fun second(): Short { + return second + } + } - @Test public void toStringReflectsInnerAdapter() throws Exception { - JsonAdapter adapter = moshi.adapter(int.class, ANNOTATIONS); + @Test + @Throws(Exception::class) + fun factoryMaintainsOtherAnnotations() { + val adapter = moshi.adapter(AnotherInt::class.java) + val fromJson = adapter.fromJson( + """{ + "willFallback": null, + "willMultiply": 3 +}""" + ) + Assertions.assertThat(fromJson!!.willFallback).isEqualTo(2) + Assertions.assertThat(fromJson.willMultiply).isEqualTo(6) + val toJson = adapter.toJson(fromJson) + // Both values should be serialized by the Multiply json adapter. + Assertions.assertThat(toJson).isEqualTo("{\"willFallback\":1,\"willMultiply\":3}") + } - assertThat(adapter.toString()) - .isEqualTo("JsonAdapter(Integer).fallbackOnNull(fallbackInt=-1)"); - } + private class AnotherInt { + @FallbackOnNull(fallbackInt = 2) + @Multiply + var willFallback = 0 - private static final Set ANNOTATIONS = Collections.singleton( - new FallbackOnNull() { + @FallbackOnNull(fallbackInt = 2) + @Multiply + var willMultiply = 0 + } - @Override public Class annotationType() { - return FallbackOnNull.class; + @Test + fun factoryIgnoresNonPrimitiveTypes() { + val classes: ArrayList?> = object : ArrayList?>() { + init { + add(Boolean::class.java) + add(Byte::class.java) + add(Char::class.java) + add(Double::class.java) + add(Float::class.java) + add(Int::class.java) + add(Long::class.java) + add(Short::class.java) + add(String::class.java) + add(Any::class.java) + } } - - @Override public boolean fallbackBoolean() { - return false; + for (cls in classes) { + Assertions.assertThat(FallbackOnNull.ADAPTER_FACTORY.create(cls, ANNOTATIONS, moshi)) + .isNull() } + } - @Override public byte fallbackByte() { - return 0; - } + @Test + @Throws(Exception::class) + fun fallbackOnNullIsDelegated() { + val adapter = moshi.adapter(AndAnotherInt::class.java) + val fromJson = adapter.fromJson( + """{ + "willFallback": null +}""" + ) + Assertions.assertThat(fromJson!!.willFallback).isEqualTo(2) + } - @Override public char fallbackChar() { - return 0; - } + private class AndAnotherInt { + @AlwaysFallBackToTwoOnNull + var willFallback = 0 + } - @Override public double fallbackDouble() { - return 0; - } + @JsonQualifier + @FallbackOnNull(fallbackInt = 2) + @Retention(RetentionPolicy.RUNTIME) + @Target( + AnnotationTarget.FIELD, + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.VALUE_PARAMETER + ) + internal annotation class AlwaysFallBackToTwoOnNull + + @Test + @Throws(Exception::class) + fun toStringReflectsInnerAdapter() { + val adapter = moshi.adapter(Int::class.javaPrimitiveType, ANNOTATIONS) + Assertions.assertThat(adapter.toString()) + .isEqualTo("JsonAdapter(Integer).fallbackOnNull(fallbackInt=-1)") + } - @Override public float fallbackFloat() { - return 0; - } + @Throws(IOException::class) + private fun ?, P> assertForClass( + cls: Class, first: P, second: P, + asJson: String + ) { + val adapter = moshi.adapter(cls) + val fromJson = adapter.fromJson( + """{ + "first": null, + "second": null +}""" + ) + Assertions.assertThat(fromJson!!.first()).isEqualTo(first) + Assertions.assertThat(fromJson.second()).isEqualTo(second) + val toJson = adapter.toJson(fromJson) + Assertions.assertThat(toJson).isEqualTo(asJson) + } - @Override public int fallbackInt() { - return -1; // Only this method will be taken into account - } + private interface Wrapper

{ + fun first(): P + fun second(): P + } - @Override public long fallbackLong() { - return 0; + @JsonQualifier + @Retention(RetentionPolicy.RUNTIME) + private annotation class Multiply { + class MultiplyAdapter { + @Multiply + @FromJson + fun fromJson(`val`: Int): Int { + return `val` * 2 + } + + @ToJson + fun toJson(@Multiply `val`: Int): Int { + return `val` / 2 + } } + } - @Override public short fallbackShort() { - return 0; - } - }); - - private , P> void assertForClass(Class cls, P first, P second, - String asJson) throws IOException { - JsonAdapter adapter = moshi.adapter(cls); - - T fromJson = adapter.fromJson("{\n" - + " \"first\": null,\n" - + " \"second\": null\n" - + "}"); - assertThat(fromJson.first()).isEqualTo(first); - assertThat(fromJson.second()).isEqualTo(second); - - String toJson = adapter.toJson(fromJson); - assertThat(toJson).isEqualTo(asJson); - } - - private interface Wrapper

{ - P first(); - - P second(); - } - - @JsonQualifier - @Retention(RetentionPolicy.RUNTIME) private @interface Multiply { - final class MultiplyAdapter { - @Multiply @FromJson int fromJson(int val) { - return val * 2; - } - - @ToJson int toJson(@Multiply int val) { - return val / 2; - } + companion object { + private val ANNOTATIONS: Set = + setOf(FallbackOnNull(false, 0, '0', 0.0, 0.0f, -1, 0, 0)) } - } -} +} \ No newline at end of file