Package de.undercouch.bson4jackson

Source Code of de.undercouch.bson4jackson.BsonGeneratorTest

// Copyright 2010-2011 Michel Kraemer
//
// 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 de.undercouch.bson4jackson;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.regex.Pattern;

import org.bson.BSONDecoder;
import org.bson.BSONObject;
import org.bson.BasicBSONDecoder;
import org.bson.types.BSONTimestamp;
import org.bson.types.Code;
import org.bson.types.CodeWScope;
import org.junit.Test;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;

import de.undercouch.bson4jackson.io.DynamicOutputBuffer;
import de.undercouch.bson4jackson.types.JavaScript;
import de.undercouch.bson4jackson.types.ObjectId;
import de.undercouch.bson4jackson.types.Timestamp;

/**
* Tests {@link BsonGenerator}
* @author Michel Kraemer
*/
public class BsonGeneratorTest {
  @Test
  public void generatePrimitives() throws Exception {
    Map<String, Object> data = new LinkedHashMap<String, Object>();
    data.put("Int32", 5);
    data.put("Boolean1", true);
    data.put("Boolean2", false);
    data.put("String", "Hello");
    data.put("Long", 1234L);
    data.put("Null", null);
    data.put("Float", 1234.1234f);
    data.put("Double", 5678.5678);
   
    //BigInteger that can be serialized as an Integer
    data.put("BigInt1", BigInteger.valueOf(Integer.MAX_VALUE));
   
    //BigInteger that can be serialized as a Long
    BigInteger bi2 = BigInteger.valueOf(Integer.MAX_VALUE)
      .multiply(BigInteger.valueOf(2));
    data.put("BigInt2", bi2);
   
    //BigInteger that will be serialized as a String
    BigInteger bi3 = BigInteger.valueOf(Long.MAX_VALUE)
      .multiply(BigInteger.valueOf(Long.MAX_VALUE));
    data.put("BigInt3", bi3);
   
    BSONObject obj = generateAndParse(data);

    assertEquals(5, obj.get("Int32"));
    assertEquals(true, obj.get("Boolean1"));
    assertEquals(false, obj.get("Boolean2"));
    assertEquals("Hello", obj.get("String"));
    assertEquals(1234L, obj.get("Long"));
    assertEquals(null, obj.get("Null"));
    assertEquals(1234.1234f, (Double)obj.get("Float"), 0.00001);
    assertEquals(5678.5678, (Double)obj.get("Double"), 0.00001);
    assertEquals(Integer.MAX_VALUE, obj.get("BigInt1"));
    assertEquals(Long.valueOf(Integer.MAX_VALUE) * 2L, obj.get("BigInt2"));
    assertEquals(bi3.toString(), obj.get("BigInt3"));
  }
 
  @Test
  public void stream() throws Exception {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    BsonFactory fac = new BsonFactory();
    fac.enable(BsonGenerator.Feature.ENABLE_STREAMING);
    BsonGenerator gen = fac.createGenerator(baos);
    byte[] dummy = new byte[DynamicOutputBuffer.DEFAULT_BUFFER_SIZE * 3 / 2];
    gen.writeStartObject();
    gen.writeFieldName("Test");
    gen.writeBinary(dummy);
   
    assertEquals(DynamicOutputBuffer.DEFAULT_BUFFER_SIZE, baos.size());
   
    gen.writeEndObject();
    gen.writeStartObject();
    gen.writeFieldName("Test");
    gen.writeBinary(dummy);
   
    assertEquals(DynamicOutputBuffer.DEFAULT_BUFFER_SIZE * 3, baos.size());
   
    gen.writeEndObject();
    gen.close();
   
    assertTrue(baos.size() > DynamicOutputBuffer.DEFAULT_BUFFER_SIZE * 3);
  }
 
  private void assertRaw(byte[] r) throws Exception {
    ByteArrayInputStream bais = new ByteArrayInputStream(r);
    BSONDecoder decoder = new BasicBSONDecoder();
    BSONObject obj = decoder.readObject(bais);
    byte[] o = (byte[])obj.get("Test");
    CharBuffer buf = ByteBuffer.wrap(o).order(ByteOrder.LITTLE_ENDIAN).asCharBuffer();
    assertEquals(2, buf.remaining());
    char a = buf.get();
    char b = buf.get();
    assertEquals('a', a);
    assertEquals('b', b);
  }
 
  @Test
  public void rawChar() throws Exception {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    BsonGenerator gen = new BsonGenerator(JsonGenerator.Feature.collectDefaults(), 0, baos);
    gen.writeStartObject();
    gen.writeFieldName("Test");
    gen.writeRaw(new char[] { 'a', 'b' }, 0, 2);
    gen.writeEndObject();
    gen.close();
    assertRaw(baos.toByteArray());
  }
 
  @Test
  public void rawString() throws Exception {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    BsonGenerator gen = new BsonGenerator(JsonGenerator.Feature.collectDefaults(), 0, baos);
    gen.writeStartObject();
    gen.writeFieldName("Test");
    gen.writeRaw("ab");
    gen.writeEndObject();
    gen.close();
    assertRaw(baos.toByteArray());
  }
 
  @Test
  public void rawBytes() throws Exception {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    BsonGenerator gen = new BsonGenerator(JsonGenerator.Feature.collectDefaults(), 0, baos);
    gen.writeStartObject();
    gen.writeFieldName("Test");
    gen.writeBinary(new byte[] { (byte)1, (byte)2 });
    gen.writeEndObject();
    gen.close();
   
    byte[] r = baos.toByteArray();
    ByteArrayInputStream bais = new ByteArrayInputStream(r);
    BSONDecoder decoder = new BasicBSONDecoder();
    BSONObject obj = decoder.readObject(bais);
    byte[] o = (byte[])obj.get("Test");
    assertEquals(2, o.length);
    assertEquals((byte)1, o[0]);
    assertEquals((byte)2, o[1]);
  }
 
  @Test
  public void stackedObjects() throws Exception {
    Map<String, Object> data1 = new LinkedHashMap<String, Object>();
    data1.put("Int32", 5);
    Map<String, Object> data3 = new LinkedHashMap<String, Object>();
    data3.put("String", "Hello");
   
    Map<String, Object> data2 = new LinkedHashMap<String, Object>();
    data2.put("Int64", 10L);
    data2.put("data1", data1);
    data2.put("data3", data3);

    BSONObject obj2 = generateAndParse(data2);

    assertEquals(10L, obj2.get("Int64"));
    BSONObject obj1 = (BSONObject)obj2.get("data1");
    assertEquals(5, obj1.get("Int32"));
    BSONObject obj3 = (BSONObject)obj2.get("data3");
    assertEquals("Hello", obj3.get("String"));
  }
 
  @Test
  @SuppressWarnings("unchecked")
  public void arrays() throws Exception {
    Map<String, Object> data = new LinkedHashMap<String, Object>();
    data.put("Int32", 5);
    data.put("Arr", Arrays.asList("a", "b", "c"));
    data.put("Int64", 10L);
    List<String> a3 = Arrays.asList("d", "e", "f");
    List<String> a4 = Arrays.asList("g", "h", "j");
    List<List<String>> a5 = new ArrayList<List<String>>();
    a5.add(a3);
    a5.add(a4);
    data.put("Arr2", a5);
   
    Map<String, Object> data2 = new LinkedHashMap<String, Object>();
    data2.put("Str", "Hello");
    List<Map<String, Object>> a6 = new ArrayList<Map<String, Object>>();
    a6.add(data2);
    data.put("Arr3", a6);
   
    BSONObject obj = generateAndParse(data);

    assertEquals(5, obj.get("Int32"));
    List<String> o = (List<String>)obj.get("Arr");
    assertEquals(3, o.size());
    assertEquals("a", o.get(0));
    assertEquals("b", o.get(1));
    assertEquals("c", o.get(2));
    assertEquals(10L, obj.get("Int64"));
    List<List<String>> o5 = (List<List<String>>)obj.get("Arr2");
    assertEquals(a5, o5);
    List<BSONObject> o6 = (List<BSONObject>)obj.get("Arr3");
    assertEquals(1, o6.size());
    BSONObject b6 = o6.get(0);
    assertEquals("Hello", b6.get("Str"));
  }
 
  @Test
  public void utf8Strings() throws Exception {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    BsonGenerator gen = new BsonGenerator(JsonGenerator.Feature.collectDefaults(), 0, baos);
    gen.writeStartObject();
    gen.writeFieldName("a\u20AC\u00A2\u00A2bb");
    gen.writeString("a\u20AC\u00A2\u00A2bb");
    gen.writeEndObject();
    gen.close();
   
    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    BSONDecoder decoder = new BasicBSONDecoder();
    BSONObject obj = decoder.readObject(bais);
    String s = (String)obj.get("a\u20AC\u00A2\u00A2bb");
    assertEquals("a\u20AC\u00A2\u00A2bb", s);
  }
 
  @Test
  public void uuids() throws Exception {
    Map<String, Object> data = new LinkedHashMap<String, Object>();
    data.put("Int32", 5);
    data.put("Arr", Arrays.asList("a", "b", "c"));
    UUID uuid = UUID.randomUUID();
    data.put("Uuid", uuid);

    BSONObject obj = generateAndParse(data);

    assertEquals(5, obj.get("Int32"));
    assertNotNull(obj.get("Uuid"));
    assertEquals(UUID.class, obj.get("Uuid").getClass());
    assertEquals(uuid, obj.get("Uuid"));
  }

  @Test
  public void dates() throws Exception {
    Map<String, Object> data = new LinkedHashMap<String, Object>();
    Date date = new Date();
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    data.put("date", date);
    data.put("calendar", calendar);

    BSONObject obj = generateAndParse(data);

    assertEquals(date, obj.get("date"));
    assertEquals(date, obj.get("calendar"));
  }

  @Test
  public void objectIds() throws Exception {
    Map<String, Object> data = new LinkedHashMap<String, Object>();
    ObjectId objectId = new ObjectId((int) (System.currentTimeMillis() / 1000), new Random().nextInt(), 100);
    data.put("_id", objectId);

    BSONObject obj = generateAndParse(data);

    org.bson.types.ObjectId result = (org.bson.types.ObjectId) obj.get("_id");
    assertNotNull(result);
    assertEquals(objectId.getTime(), result.getTimeSecond());
    assertEquals(objectId.getMachine(), result.getMachine());
    assertEquals(objectId.getInc(), result.getInc());
  }

  @Test
  public void patterns() throws Exception {
    Pattern pattern = Pattern.compile("a.*a", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
    Map<String, Object> data = new LinkedHashMap<String, Object>();
    data.put("pattern", pattern);

    BSONObject obj = generateAndParse(data);

    Pattern result = (Pattern) obj.get("pattern");
    assertNotNull(result);
    assertEquals(pattern.pattern(), result.pattern());
    assertEquals(pattern.flags(), result.flags());
  }

  @Test
  public void timestamps() throws Exception {
    Timestamp timestamp = new Timestamp(100, 200);
    Map<String, Object> data = new LinkedHashMap<String, Object>();
    data.put("timestamp", timestamp);

    BSONObject obj = generateAndParse(data);

    BSONTimestamp result = (BSONTimestamp) obj.get("timestamp");
    assertNotNull(result);
    assertEquals(timestamp.getInc(), result.getInc());
    assertEquals(timestamp.getTime(), result.getTime());
  }

  @Test
  public void javascript() throws Exception {
    JavaScript javaScript = new JavaScript("a < 100");
    Map<String, Object> data = new LinkedHashMap<String, Object>();
    data.put("javaScript", javaScript);

    BSONObject obj = generateAndParse(data);

    Code result = (Code) obj.get("javaScript");
    assertNotNull(result);
    assertEquals(javaScript.getCode(), result.getCode());
  }

  @Test
  public void javascriptWithScope() throws Exception {
    Map<String, Object> scope = new LinkedHashMap<String, Object>();
    scope.put("a", 99);
    scope.put("b", 80);
    JavaScript javaScript = new JavaScript("a < 100", scope);
    Map<String, Object> data = new LinkedHashMap<String, Object>();
    data.put("javaScript", javaScript);

    BSONObject obj = generateAndParse(data);

    CodeWScope result = (CodeWScope) obj.get("javaScript");
    assertNotNull(result);
    assertEquals(javaScript.getCode(), result.getCode());
    Map<?, ?> returnedScope = result.getScope().toMap();
    assertEquals(returnedScope, scope);
  }

  private BSONObject generateAndParse(Map<String, Object> data,
      BsonGenerator.Feature... featuresToEnable) throws Exception {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    BsonFactory bsonFactory = new BsonFactory();
    if (featuresToEnable != null) {
      for (BsonGenerator.Feature fe : featuresToEnable) {
        bsonFactory.enable(fe);
      }
    }
    ObjectMapper om = new ObjectMapper(bsonFactory);
    om.registerModule(new BsonModule());
    om.writeValue(baos, data);

    byte[] r = baos.toByteArray();
    ByteArrayInputStream bais = new ByteArrayInputStream(r);

    BSONDecoder decoder = new BasicBSONDecoder();
    return decoder.readObject(bais);
  }
 
  @Test
  public void writeBigDecimalsAsStrings() throws Exception {
    Map<String, Object> data = new LinkedHashMap<String, Object>();
    data.put("big", new BigDecimal("0.3"));

    BSONObject obj = generateAndParse(data);

    Double result = (Double)obj.get("big");
   
    //BigDecimal("0.3") does not equal 0.3!
    assertEquals(Double.valueOf(0.3), result, 0.000001);
    assertFalse(Double.valueOf(0.3).equals(result));
   
    data = new LinkedHashMap<String, Object>();
    data.put("big", new BigDecimal("0.3"));

    obj = generateAndParse(data,
        BsonGenerator.Feature.WRITE_BIGDECIMALS_AS_STRINGS);

    String strResult = (String)obj.get("big");
    assertEquals("0.3", strResult);
  }
 
  @Test
  public void writeBinaryData() throws Exception {
    byte[] binary = new byte[] { (byte)0x05, (byte)0xff, (byte)0xaf,
        (byte)0x30, 'A', 'B', 'C', (byte)0x13, (byte)0x80,
        (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff};
   
    Map<String, Object> data = new LinkedHashMap<String, Object>();
    data.put("binary", binary);
   
    //binary data has to be converted to base64 with normal JSON
    ObjectMapper mapper = new ObjectMapper();
    String jsonString = mapper.writeValueAsString(data);
    assertEquals("{\"binary\":\"Bf+vMEFCQxOA/////w==\"}", jsonString);
   
    //with BSON we don't have to convert to base64
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    BsonFactory bsonFactory = new BsonFactory();
    ObjectMapper om = new ObjectMapper(bsonFactory);
    om.writeValue(baos, data);
   
    //document header (4 bytes) + type (1 byte) + field_name ("binary", 6 bytes) +
    //end_of_string (1 byte) + binary_size (4 bytes) + subtype (1 byte) +
    //binary_data (13 bytes) + end_of_document (1 byte)
    int expectedLen = 4 + 1 + 6 + 1 + 4 + 1 + 13 + 1;
   
    assertEquals(expectedLen, baos.size());
   
    //BSON is smaller than JSON (at least in this case)
    assertTrue(baos.size() < jsonString.length());
   
    //test if binary data can be parsed
    BSONObject obj = generateAndParse(data);
    byte[] objbin = (byte[])obj.get("binary");
    assertArrayEquals(binary, objbin);
  }
}
TOP

Related Classes of de.undercouch.bson4jackson.BsonGeneratorTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.