use bson::{doc, oid::ObjectId, spec::BinarySubtype, Bson};
use chrono::offset::Utc;
use hex;
#[test]
fn standard_format() {
let id_string = "thisismyname";
let string_bytes: Vec<_> = id_string.bytes().collect();
let mut bytes = [0; 12];
bytes[..12].clone_from_slice(&string_bytes[..12]);
let id = ObjectId::with_bytes(bytes);
let date = Utc::now();
let doc = doc! {
"float": 2.4,
"string": "hello",
"array" => ["testing", 1, true, [1, 2]],
"doc": {
"fish": "in",
"a": "barrel",
"!": 1,
},
"bool": true,
"null": null,
"regexp": Bson::RegExp("s[ao]d".to_owned(), "i".to_owned()),
"with_wrapped_parens": (-20),
"code": Bson::JavaScriptCode("function(x) { return x._id; }".to_owned()),
"i32": 12,
"i64": -55,
"timestamp": Bson::TimeStamp(229_999_444),
"binary": Bson::Binary(BinarySubtype::Md5, "thingies".to_owned().into_bytes()),
"_id": id,
"date": Bson::UtcDatetime(date),
};
let expected = format!(
"{{ float: 2.4, string: \"hello\", array: [\"testing\", 1, true, [1, 2]], doc: {{ fish: \
\"in\", a: \"barrel\", !: 1 }}, bool: true, null: null, regexp: /s[ao]d/i, \
with_wrapped_parens: -20, code: function(x) {{ return x._id; }}, i32: 12, i64: -55, \
timestamp: Timestamp(0, 229999444), binary: BinData(5, 0x{}), _id: ObjectId(\"{}\"), \
date: Date(\"{}\") }}",
hex::encode("thingies"),
hex::encode(id_string),
date
);
assert_eq!(expected, format!("{}", doc));
}
#[test]
fn rocket_format() {
let id_string = "thisismyname";
let string_bytes: Vec<_> = id_string.bytes().collect();
let mut bytes = [0; 12];
bytes[..12].clone_from_slice(&string_bytes[..12]);
let id = ObjectId::with_bytes(bytes);
let date = Utc::now();
let doc = doc! {
"float" => 2.4,
"string" => "hello",
"array" => ["testing", 1, true, ["nested", 2]],
"doc" => {
"fish" => "in",
"a" => "barrel",
"!" => 1,
},
"bool" => true,
"null" => null,
"regexp" => Bson::RegExp("s[ao]d".to_owned(), "i".to_owned()),
"with_wrapped_parens" => (-20),
"code" => Bson::JavaScriptCode("function(x) { return x._id; }".to_owned()),
"i32" => 12,
"i64" => -55,
"timestamp" => Bson::TimeStamp(229_999_444),
"binary" => Bson::Binary(BinarySubtype::Md5, "thingies".to_owned().into_bytes()),
"_id" => id,
"date" => Bson::UtcDatetime(date),
};
let expected = format!(
"{{ float: 2.4, string: \"hello\", array: [\"testing\", 1, true, [\"nested\", 2]], doc: \
{{ fish: \"in\", a: \"barrel\", !: 1 }}, bool: true, null: null, regexp: /s[ao]d/i, \
with_wrapped_parens: -20, code: function(x) {{ return x._id; }}, i32: 12, i64: -55, \
timestamp: Timestamp(0, 229999444), binary: BinData(5, 0x{}), _id: ObjectId(\"{}\"), \
date: Date(\"{}\") }}",
hex::encode("thingies"),
hex::encode(id_string),
date
);
assert_eq!(expected, format!("{}", doc));
}
#[test]
fn non_trailing_comma() {
let doc = doc! {
"a": "foo",
"b": { "ok": "then" }
};
let expected = "{ a: \"foo\", b: { ok: \"then\" } }".to_string();
assert_eq!(expected, format!("{}", doc));
}
#[test]
fn non_trailing_comma_with_rockets() {
let doc = doc! {
"a" => "foo",
"b" => { "ok": "then" }
};
let expected = "{ a: \"foo\", b: { ok: \"then\" } }".to_string();
assert_eq!(expected, format!("{}", doc));
}
#[test]
#[allow(clippy::float_cmp)]
fn recursive_macro() {
let doc = doc! {
"a": "foo",
"b": {
"bar": {
"harbor": ["seal", false],
"jelly": 42.0,
},
"grape": 27,
},
"c": [-7],
"d": [
{
"apple": "ripe",
}
],
"e": { "single": "test" },
"n": (Bson::Null),
};
match doc.get("a") {
Some(&Bson::String(ref s)) => assert_eq!("foo", s),
_ => panic!("String 'foo' was not inserted correctly."),
}
match doc.get("b") {
Some(&Bson::Document(ref doc)) => {
match doc.get("bar") {
Some(&Bson::Document(ref inner_doc)) => {
match inner_doc.get("harbor") {
Some(&Bson::Array(ref arr)) => {
assert_eq!(2, arr.len());
match arr[0] {
Bson::String(ref s) => assert_eq!("seal", s),
_ => panic!(
"String 'seal' was not inserted into inner array correctly."
),
}
match arr[1] {
Bson::Boolean(ref b) => assert!(!b),
_ => panic!(
"Boolean 'false' was not inserted into inner array correctly."
),
}
}
_ => panic!("Inner array was not inserted correctly."),
}
match inner_doc.get("jelly") {
Some(&Bson::FloatingPoint(ref fp)) => assert_eq!(42.0, *fp),
_ => panic!("Floating point 42.0 was not inserted correctly."),
}
}
_ => panic!("Second inner document was not inserted correctly."),
}
}
_ => panic!("Inner document was not inserted correctly."),
}
match doc.get("c") {
Some(&Bson::Array(ref arr)) => {
assert_eq!(1, arr.len());
match arr[0] {
Bson::I32(ref i) => assert_eq!(-7, *i),
_ => panic!("I32 '-7' was not inserted correctly."),
}
}
_ => panic!("Single-item array was not inserted correctly."),
}
match doc.get("d") {
Some(&Bson::Array(ref arr)) => {
assert_eq!(1, arr.len());
match arr[0] {
Bson::Document(ref doc) => {
match doc.get("apple") {
Some(&Bson::String(ref s)) => assert_eq!("ripe", s),
_ => panic!("String 'ripe' was not inserted correctly."),
}
}
_ => panic!("Document was not inserted into array correctly."),
}
}
_ => panic!("Array was not inserted correctly."),
}
match doc.get("e") {
Some(&Bson::Document(ref bdoc)) => {
match bdoc.get("single") {
Some(&Bson::String(ref s)) => assert_eq!("test", s),
_ => panic!("String 'test' was not inserted correctly."),
}
}
_ => panic!("Single-item document was not inserted correctly."),
}
match doc.get("n") {
Some(&Bson::Null) => {
}
_ => panic!("Null was not inserted correctly."),
}
}