// Path: reactive-conversion-api/src/main/java/com/github/jloisel/reactive/conversion/api/Serializer.java
// public interface Serializer<T extends ReactiveEntity> extends
//  Func1<T, RawJsonDocument> {
// 
// }
// 
// Path: reactive-conversion-jackson/src/main/java/com/github/jloisel/reactive/conversion/jackson/BeanWrapper.java
// @Value
// class BeanWrapper<T extends ReactiveEntity> {
//   @JsonTypeInfo(use = Id.CLASS, include = As.PROPERTY, property = "_class")
//   T entity;
// 
//   @JsonCreator
//   BeanWrapper(@JsonProperty("entity") final T entity) {
//     super();
//     this.entity = checkNotNull(entity);
//   }
// }
// 
// Path: reactive-conversion-jackson/src/main/java/com/github/jloisel/reactive/conversion/jackson/JacksonConversionException.java
// final class JacksonConversionException extends RuntimeException {
//   private static final long serialVersionUID = -4917703394134871581L;
// 
//   JacksonConversionException(String message, Throwable e) {
//     super(e);
//   }
// }
// 
// Path: reactive-conversion-jackson/src/main/java/com/github/jloisel/reactive/conversion/jackson/JacksonDeserializer.java
// @AllArgsConstructor(access = PACKAGE)
// final class JacksonDeserializer<T extends ReactiveEntity> implements Deserializer<T> {
//   static final String START_OBJECT = "{\"entity\":";
//   static final String END_OBJECT = "}";
// 
//   @NonNull
//   private final ObjectMapper mapper;
//   @NonNull
//   private final TypeReference<BeanWrapper<T>> reference;
// 
//   @Override
//   public T call(final RawJsonDocument document) {
//     try {
//       final String wrapped = join(START_OBJECT, document.content(), END_OBJECT);
//       final BeanWrapper<T> bean = mapper.reader(reference).readValue(wrapped);
//       return bean.getEntity();
//     } catch (final IOException e) {
//       throw new JacksonConversionException("Error while deserializing document id=" + document.id(), e);
//     }
//   }
// 
// }
// 
// Path: reactive-conversion-jackson/src/main/java/com/github/jloisel/reactive/conversion/jackson/JacksonSerializer.java
// @AllArgsConstructor(access = PACKAGE)
// @FieldDefaults(level = PRIVATE, makeFinal = true)
// final class JacksonSerializer<T extends ReactiveEntity> implements Serializer<T> {
//   @NonNull
//   ObjectMapper mapper;
//   @NonNull
//   TypeReference<BeanWrapper<T>> reference;
// 
//   @Override
//   public RawJsonDocument call(final T bean) {
//     try {
//       final ObjectWriter writer = mapper.writerFor(reference);
//       final String json = writer.writeValueAsString(new BeanWrapper<T>(bean));
//       final String unwrapped =
//           json.substring(START_OBJECT.length(), json.length() - END_OBJECT.length());
//       return RawJsonDocument.create(bean.getId(), unwrapped);
//     } catch (final IOException e) {
//       throw new JacksonConversionException("Error while serializing bean=" + bean, e);
//     }
//   }
// }
// 
// Path: reactive-entity-api/src/main/java/com/github/jloisel/reactive/entity/api/ReactiveEntity.java
// public interface ReactiveEntity {
// 
//   /**
//    * @return id of the entity
//    */
//   String getId();
// }


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import com.couchbase.client.java.document.RawJsonDocument;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.github.jloisel.reactive.conversion.api.Serializer;
import com.github.jloisel.reactive.conversion.jackson.BeanWrapper;
import com.github.jloisel.reactive.conversion.jackson.JacksonConversionException;
import com.github.jloisel.reactive.conversion.jackson.JacksonDeserializer;
import com.github.jloisel.reactive.conversion.jackson.JacksonSerializer;
import com.github.jloisel.reactive.entity.api.ReactiveEntity;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.NullPointerTester.Visibility;
package com.github.jloisel.reactive.conversion.jackson;





@RunWith(MockitoJUnitRunner.class)
public class JacksonSerializerTest {

  @Mock
  private ObjectMapper mapper;
  @Mock
  private ObjectWriter writer;
  @Mock
  private ReactiveEntity entity;

  private Serializer<ReactiveEntity> serializer;

  private final TypeReference<BeanWrapper<ReactiveEntity>> reference =
      new TypeReference<BeanWrapper<ReactiveEntity>>() {};

  @Before
  public void before() throws IOException {
    when(entity.getId()).thenReturn("id");
    when(mapper.writerFor(reference)).thenReturn(writer);
    when(writer.writeValueAsString(any())).thenReturn(
// Path: reactive-conversion-api/src/main/java/com/github/jloisel/reactive/conversion/api/Serializer.java
// public interface Serializer<T extends ReactiveEntity> extends
//  Func1<T, RawJsonDocument> {
// 
// }
// 
// Path: reactive-conversion-jackson/src/main/java/com/github/jloisel/reactive/conversion/jackson/BeanWrapper.java
// @Value
// class BeanWrapper<T extends ReactiveEntity> {
//   @JsonTypeInfo(use = Id.CLASS, include = As.PROPERTY, property = "_class")
//   T entity;
// 
//   @JsonCreator
//   BeanWrapper(@JsonProperty("entity") final T entity) {
//     super();
//     this.entity = checkNotNull(entity);
//   }
// }
// 
// Path: reactive-conversion-jackson/src/main/java/com/github/jloisel/reactive/conversion/jackson/JacksonConversionException.java
// final class JacksonConversionException extends RuntimeException {
//   private static final long serialVersionUID = -4917703394134871581L;
// 
//   JacksonConversionException(String message, Throwable e) {
//     super(e);
//   }
// }
// 
// Path: reactive-conversion-jackson/src/main/java/com/github/jloisel/reactive/conversion/jackson/JacksonDeserializer.java
// @AllArgsConstructor(access = PACKAGE)
// final class JacksonDeserializer<T extends ReactiveEntity> implements Deserializer<T> {
//   static final String START_OBJECT = "{\"entity\":";
//   static final String END_OBJECT = "}";
// 
//   @NonNull
//   private final ObjectMapper mapper;
//   @NonNull
//   private final TypeReference<BeanWrapper<T>> reference;
// 
//   @Override
//   public T call(final RawJsonDocument document) {
//     try {
//       final String wrapped = join(START_OBJECT, document.content(), END_OBJECT);
//       final BeanWrapper<T> bean = mapper.reader(reference).readValue(wrapped);
//       return bean.getEntity();
//     } catch (final IOException e) {
//       throw new JacksonConversionException("Error while deserializing document id=" + document.id(), e);
//     }
//   }
// 
// }
// 
// Path: reactive-conversion-jackson/src/main/java/com/github/jloisel/reactive/conversion/jackson/JacksonSerializer.java
// @AllArgsConstructor(access = PACKAGE)
// @FieldDefaults(level = PRIVATE, makeFinal = true)
// final class JacksonSerializer<T extends ReactiveEntity> implements Serializer<T> {
//   @NonNull
//   ObjectMapper mapper;
//   @NonNull
//   TypeReference<BeanWrapper<T>> reference;
// 
//   @Override
//   public RawJsonDocument call(final T bean) {
//     try {
//       final ObjectWriter writer = mapper.writerFor(reference);
//       final String json = writer.writeValueAsString(new BeanWrapper<T>(bean));
//       final String unwrapped =
//           json.substring(START_OBJECT.length(), json.length() - END_OBJECT.length());
//       return RawJsonDocument.create(bean.getId(), unwrapped);
//     } catch (final IOException e) {
//       throw new JacksonConversionException("Error while serializing bean=" + bean, e);
//     }
//   }
// }
// 
// Path: reactive-entity-api/src/main/java/com/github/jloisel/reactive/entity/api/ReactiveEntity.java
// public interface ReactiveEntity {
// 
//   /**
//    * @return id of the entity
//    */
//   String getId();
// }


// Path: reactive-conversion-jackson/src/test/java/com/github/jloisel/reactive/conversion/jackson/JacksonSerializerTest.java
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import com.couchbase.client.java.document.RawJsonDocument;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.github.jloisel.reactive.conversion.api.Serializer;
import com.github.jloisel.reactive.conversion.jackson.BeanWrapper;
import com.github.jloisel.reactive.conversion.jackson.JacksonConversionException;
import com.github.jloisel.reactive.conversion.jackson.JacksonDeserializer;
import com.github.jloisel.reactive.conversion.jackson.JacksonSerializer;
import com.github.jloisel.reactive.entity.api.ReactiveEntity;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.NullPointerTester.Visibility;

package com.github.jloisel.reactive.conversion.jackson;





@RunWith(MockitoJUnitRunner.class)
public class JacksonSerializerTest {

  @Mock
  private ObjectMapper mapper;
  @Mock
  private ObjectWriter writer;
  @Mock
  private ReactiveEntity entity;

  private Serializer<ReactiveEntity> serializer;

  private final TypeReference<BeanWrapper<ReactiveEntity>> reference =
      new TypeReference<BeanWrapper<ReactiveEntity>>() {};

  @Before
  public void before() throws IOException {
    when(entity.getId()).thenReturn("id");
    when(mapper.writerFor(reference)).thenReturn(writer);
    when(writer.writeValueAsString(any())).thenReturn(
        JacksonDeserializer.START_OBJECT + "{json}" + JacksonDeserializer.END_OBJECT);