2022-10-20 09:34:51 +00:00
|
|
|
use ctor::ctor;
|
2022-11-11 03:13:35 +00:00
|
|
|
|
2023-01-16 10:44:19 +00:00
|
|
|
use loro_internal::container::registry::ContainerWrapper;
|
|
|
|
use loro_internal::container::ContainerID;
|
|
|
|
use loro_internal::context::Context;
|
|
|
|
use loro_internal::id::ID;
|
2022-12-13 14:59:29 +00:00
|
|
|
|
2023-01-16 10:44:19 +00:00
|
|
|
use loro_internal::log_store::EncodeConfig;
|
|
|
|
use loro_internal::{ContainerType, LoroCore, VersionVector};
|
2022-10-20 08:29:38 +00:00
|
|
|
|
2023-01-06 13:03:11 +00:00
|
|
|
#[test]
|
|
|
|
fn send_sync() {
|
2023-01-15 03:49:23 +00:00
|
|
|
fn example<T: Send + Sync + 'static>(_: T) {}
|
2023-01-06 13:03:11 +00:00
|
|
|
let loro = LoroCore::default();
|
|
|
|
example(loro);
|
|
|
|
}
|
|
|
|
|
2022-12-12 05:44:49 +00:00
|
|
|
#[test]
|
|
|
|
fn example_list() {
|
|
|
|
let mut doc = LoroCore::default();
|
|
|
|
let mut list = doc.get_list("list");
|
|
|
|
list.insert(&doc, 0, 11).unwrap();
|
|
|
|
list.insert(&doc, 1, 22).unwrap();
|
|
|
|
dbg!(&doc.log_store());
|
|
|
|
}
|
|
|
|
|
2022-11-13 09:57:13 +00:00
|
|
|
#[test]
|
|
|
|
#[cfg(feature = "json")]
|
|
|
|
fn example() {
|
2023-01-16 10:44:19 +00:00
|
|
|
use loro_internal::ContainerType;
|
2022-11-13 09:57:13 +00:00
|
|
|
|
|
|
|
let mut doc = LoroCore::default();
|
|
|
|
let mut list = doc.get_list("list");
|
2022-11-22 02:39:43 +00:00
|
|
|
list.insert(&doc, 0, 123).unwrap();
|
2022-11-22 03:51:55 +00:00
|
|
|
let map_id = list.insert(&doc, 1, ContainerType::Map).unwrap().unwrap();
|
2022-11-13 09:57:13 +00:00
|
|
|
let mut map = doc.get_map(map_id);
|
2022-11-22 03:51:55 +00:00
|
|
|
let text = map
|
|
|
|
.insert(&doc, "map_b", ContainerType::Text)
|
|
|
|
.unwrap()
|
|
|
|
.unwrap();
|
2022-11-13 09:57:13 +00:00
|
|
|
let mut text = doc.get_text(text);
|
2022-11-22 02:39:43 +00:00
|
|
|
text.insert(&doc, 0, "world!").unwrap();
|
|
|
|
text.insert(&doc, 0, "hello ").unwrap();
|
2022-11-13 09:57:13 +00:00
|
|
|
assert_eq!(
|
|
|
|
r#"[123,{"map_b":"hello world!"}]"#,
|
|
|
|
list.get_value_deep(&doc).to_json()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-12-08 07:19:54 +00:00
|
|
|
#[test]
|
|
|
|
fn subscribe_deep() {
|
|
|
|
let mut doc = LoroCore::default();
|
|
|
|
doc.subscribe_deep(Box::new(move |event| {
|
|
|
|
println!("event: {:?}", event);
|
|
|
|
}));
|
|
|
|
let mut text = doc.get_text("root");
|
|
|
|
text.insert(&doc, 0, "abc").unwrap();
|
|
|
|
}
|
|
|
|
|
2022-11-24 07:10:21 +00:00
|
|
|
#[test]
|
2022-11-28 09:24:14 +00:00
|
|
|
#[cfg(feature = "json")]
|
2022-11-24 07:10:21 +00:00
|
|
|
fn text_observe() {
|
2023-01-06 13:03:11 +00:00
|
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
|
2023-01-16 10:44:19 +00:00
|
|
|
use loro_internal::LoroValue;
|
|
|
|
|
2022-11-24 07:10:21 +00:00
|
|
|
let mut doc = LoroCore::default();
|
2023-01-06 13:03:11 +00:00
|
|
|
let track_value = Arc::new(Mutex::new(LoroValue::Map(Default::default())));
|
|
|
|
let moved_value = Arc::clone(&track_value);
|
2022-11-24 15:28:36 +00:00
|
|
|
doc.subscribe_deep(Box::new(move |event| {
|
2023-01-06 13:03:11 +00:00
|
|
|
let mut v = moved_value.lock().unwrap();
|
2022-11-24 15:28:36 +00:00
|
|
|
v.apply(&event.relative_path, &event.diff);
|
|
|
|
}));
|
|
|
|
let mut map = doc.get_map("meta");
|
|
|
|
map.insert(&doc, "name", "anonymous").unwrap();
|
|
|
|
let list = map
|
|
|
|
.insert(&doc, "to-dos", ContainerType::List)
|
|
|
|
.unwrap()
|
|
|
|
.unwrap();
|
|
|
|
let mut list = doc.get_list(list);
|
|
|
|
let todo_item = list.insert(&doc, 0, ContainerType::Map).unwrap().unwrap();
|
|
|
|
let mut todo_item = doc.get_map(todo_item);
|
|
|
|
todo_item.insert(&doc, "todo", "coding").unwrap();
|
2023-01-06 13:03:11 +00:00
|
|
|
assert_eq!(&doc.to_json(), &*track_value.lock().unwrap());
|
2022-11-24 07:10:21 +00:00
|
|
|
let mut text = doc.get_text("text");
|
|
|
|
text.insert(&doc, 0, "hello ").unwrap();
|
|
|
|
let mut doc_b = LoroCore::default();
|
|
|
|
let mut text_b = doc_b.get_text("text");
|
|
|
|
text_b.insert(&doc_b, 0, "world").unwrap();
|
|
|
|
doc.import(doc_b.export(Default::default()));
|
2023-01-06 13:03:11 +00:00
|
|
|
assert_eq!(&doc.to_json(), &*track_value.lock().unwrap());
|
2022-11-24 15:28:36 +00:00
|
|
|
println!("{}", doc.to_json().to_json());
|
2022-11-24 07:10:21 +00:00
|
|
|
}
|
|
|
|
|
2022-11-12 03:11:07 +00:00
|
|
|
#[test]
|
|
|
|
#[cfg(feature = "json")]
|
|
|
|
fn list() {
|
|
|
|
let mut loro_a = LoroCore::default();
|
|
|
|
let mut loro_b = LoroCore::default();
|
|
|
|
let mut list_a = loro_a.get_list("list");
|
|
|
|
let mut list_b = loro_b.get_list("list");
|
2022-11-22 02:39:43 +00:00
|
|
|
list_a
|
|
|
|
.insert_batch(&loro_a, 0, vec![12.into(), "haha".into()])
|
|
|
|
.unwrap();
|
|
|
|
list_b
|
|
|
|
.insert_batch(&loro_b, 0, vec![123.into(), "kk".into()])
|
|
|
|
.unwrap();
|
|
|
|
let map_id = list_b
|
2023-01-16 10:44:19 +00:00
|
|
|
.insert(&loro_b, 1, loro_internal::ContainerType::Map)
|
2022-11-22 03:51:55 +00:00
|
|
|
.unwrap()
|
2022-11-22 02:39:43 +00:00
|
|
|
.unwrap();
|
2022-11-12 03:33:23 +00:00
|
|
|
let mut map = loro_b.get_map(map_id);
|
2022-11-22 02:39:43 +00:00
|
|
|
map.insert(&loro_b, "map_b", 123).unwrap();
|
2022-11-12 03:11:07 +00:00
|
|
|
println!("{}", list_a.get_value().to_json());
|
2022-11-12 03:33:23 +00:00
|
|
|
println!("{}", list_b.get_value().to_json());
|
2022-12-12 17:39:57 +00:00
|
|
|
loro_b.import(loro_a.export(loro_b.vv_cloned()));
|
|
|
|
loro_a.import(loro_b.export(loro_a.vv_cloned()));
|
2022-11-12 03:33:23 +00:00
|
|
|
println!("{}", list_b.get_value_deep(&loro_b).to_json());
|
|
|
|
println!("{}", list_a.get_value_deep(&loro_b).to_json());
|
2022-11-12 03:11:07 +00:00
|
|
|
assert_eq!(list_b.get_value(), list_a.get_value());
|
|
|
|
}
|
|
|
|
|
2022-10-20 09:34:51 +00:00
|
|
|
#[test]
|
2022-11-11 16:00:54 +00:00
|
|
|
#[cfg(feature = "json")]
|
2022-11-08 06:59:13 +00:00
|
|
|
fn map() {
|
2023-01-16 10:44:19 +00:00
|
|
|
use loro_internal::LoroValue;
|
|
|
|
|
2022-11-08 06:59:13 +00:00
|
|
|
let mut loro = LoroCore::new(Default::default(), Some(10));
|
2022-11-11 14:26:06 +00:00
|
|
|
let mut root = loro.get_map("root");
|
2022-11-22 02:39:43 +00:00
|
|
|
root.insert(&loro, "haha", 1.2).unwrap();
|
2022-11-08 07:40:14 +00:00
|
|
|
let value = root.get_value();
|
|
|
|
assert_eq!(value.as_map().unwrap().len(), 1);
|
|
|
|
assert_eq!(
|
|
|
|
*value
|
|
|
|
.as_map()
|
|
|
|
.unwrap()
|
2022-11-08 15:35:32 +00:00
|
|
|
.get("haha")
|
2022-11-08 07:40:14 +00:00
|
|
|
.unwrap()
|
|
|
|
.as_double()
|
|
|
|
.unwrap(),
|
|
|
|
1.2
|
|
|
|
);
|
2022-11-22 02:39:43 +00:00
|
|
|
let map_id = root
|
2023-01-16 10:44:19 +00:00
|
|
|
.insert(&loro, "map", loro_internal::ContainerType::Map)
|
2022-11-22 03:51:55 +00:00
|
|
|
.unwrap()
|
2022-11-22 02:39:43 +00:00
|
|
|
.unwrap();
|
2022-11-08 15:35:32 +00:00
|
|
|
drop(root);
|
2022-11-11 14:26:06 +00:00
|
|
|
let mut sub_map = loro.get_map(&map_id);
|
2022-11-22 03:51:55 +00:00
|
|
|
sub_map.insert(&loro, "sub", false).unwrap();
|
2022-11-08 15:35:32 +00:00
|
|
|
drop(sub_map);
|
2022-11-11 07:23:22 +00:00
|
|
|
let root = loro.get_map("root");
|
2022-11-08 15:35:32 +00:00
|
|
|
let value = root.get_value();
|
|
|
|
assert_eq!(value.as_map().unwrap().len(), 2);
|
|
|
|
let map = value.as_map().unwrap();
|
|
|
|
assert_eq!(*map.get("haha").unwrap().as_double().unwrap(), 1.2);
|
2022-11-11 03:12:55 +00:00
|
|
|
assert!(map.get("map").unwrap().as_unresolved().is_some());
|
2022-11-11 16:00:54 +00:00
|
|
|
println!("{}", value.to_json());
|
2022-11-11 14:26:06 +00:00
|
|
|
let deep_value = root.get_value_deep(&loro);
|
|
|
|
assert_eq!(deep_value.as_map().unwrap().len(), 2);
|
|
|
|
let map = deep_value.as_map().unwrap();
|
|
|
|
assert_eq!(*map.get("haha").unwrap().as_double().unwrap(), 1.2);
|
|
|
|
let inner_map = map.get("map").unwrap().as_map().unwrap();
|
|
|
|
assert_eq!(inner_map.len(), 1);
|
|
|
|
assert_eq!(inner_map.get("sub").unwrap(), &LoroValue::Bool(false));
|
2022-11-11 16:00:54 +00:00
|
|
|
let json = deep_value.to_json();
|
|
|
|
// println!("{}", json);
|
|
|
|
let actual: LoroValue = serde_json::from_str(&json).unwrap();
|
|
|
|
// dbg!(&actual);
|
|
|
|
assert_eq!(actual, deep_value);
|
2022-11-08 06:59:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn two_client_text_sync() {
|
2022-10-20 14:40:35 +00:00
|
|
|
let mut store = LoroCore::new(Default::default(), Some(10));
|
2022-11-11 07:23:22 +00:00
|
|
|
let mut text_container = store.get_text("haha");
|
2022-11-22 02:39:43 +00:00
|
|
|
text_container.insert(&store, 0, "012").unwrap();
|
|
|
|
text_container.insert(&store, 1, "34").unwrap();
|
|
|
|
text_container.insert(&store, 1, "56").unwrap();
|
2022-10-20 09:34:51 +00:00
|
|
|
let value = text_container.get_value();
|
|
|
|
let value = value.as_string().unwrap();
|
2022-11-08 07:40:14 +00:00
|
|
|
assert_eq!(&**value, "0563412");
|
2022-10-20 14:40:35 +00:00
|
|
|
drop(text_container);
|
2022-10-20 17:48:57 +00:00
|
|
|
|
2022-10-20 16:57:35 +00:00
|
|
|
let mut store_b = LoroCore::new(Default::default(), Some(11));
|
2022-10-20 17:48:57 +00:00
|
|
|
let exported = store.export(Default::default());
|
|
|
|
store_b.import(exported);
|
2022-11-11 07:23:22 +00:00
|
|
|
let mut text_container = store_b.get_text("haha");
|
|
|
|
text_container.with_container(|x| x.check());
|
2022-10-20 14:40:35 +00:00
|
|
|
let value = text_container.get_value();
|
|
|
|
let value = value.as_string().unwrap();
|
2022-11-08 07:40:14 +00:00
|
|
|
assert_eq!(&**value, "0563412");
|
2022-10-21 02:46:48 +00:00
|
|
|
|
2022-11-22 02:39:43 +00:00
|
|
|
text_container.delete(&store_b, 0, 2).unwrap();
|
|
|
|
text_container.insert(&store_b, 4, "789").unwrap();
|
2022-10-21 02:46:48 +00:00
|
|
|
let value = text_container.get_value();
|
|
|
|
let value = value.as_string().unwrap();
|
2022-11-08 07:40:14 +00:00
|
|
|
assert_eq!(&**value, "63417892");
|
2022-10-21 02:46:48 +00:00
|
|
|
drop(text_container);
|
|
|
|
|
2022-12-12 17:39:57 +00:00
|
|
|
store.import(store_b.export(store.vv_cloned()));
|
2022-11-11 07:23:22 +00:00
|
|
|
let mut text_container = store.get_text("haha");
|
2022-10-21 02:46:48 +00:00
|
|
|
let value = text_container.get_value();
|
|
|
|
let value = value.as_string().unwrap();
|
2022-11-08 07:40:14 +00:00
|
|
|
assert_eq!(&**value, "63417892");
|
2022-11-22 02:39:43 +00:00
|
|
|
text_container.delete(&store, 0, 8).unwrap();
|
|
|
|
text_container.insert(&store, 0, "abc").unwrap();
|
2022-10-21 02:46:48 +00:00
|
|
|
let value = text_container.get_value();
|
|
|
|
let value = value.as_string().unwrap();
|
2022-11-08 07:40:14 +00:00
|
|
|
assert_eq!(&**value, "abc");
|
2022-10-21 02:46:48 +00:00
|
|
|
|
|
|
|
store_b.import(store.export(Default::default()));
|
2022-11-11 07:23:22 +00:00
|
|
|
let text_container = store_b.get_text("haha");
|
|
|
|
text_container.with_container(|x| x.check());
|
2022-10-21 02:46:48 +00:00
|
|
|
let value = text_container.get_value();
|
|
|
|
let value = value.as_string().unwrap();
|
2022-11-08 07:40:14 +00:00
|
|
|
assert_eq!(&**value, "abc");
|
2022-10-20 09:34:51 +00:00
|
|
|
}
|
|
|
|
|
2022-11-21 09:10:04 +00:00
|
|
|
#[test]
|
|
|
|
#[should_panic]
|
|
|
|
fn test_recursive_should_panic() {
|
|
|
|
let mut store_a = LoroCore::new(Default::default(), Some(1));
|
|
|
|
let mut store_b = LoroCore::new(Default::default(), Some(2));
|
|
|
|
let mut text_a = store_a.get_text("text_a");
|
|
|
|
let mut text_b = store_b.get_text("text_b");
|
2022-11-22 02:39:43 +00:00
|
|
|
text_a.insert(&store_a, 0, "012").unwrap();
|
|
|
|
text_b.insert(&store_a, 1, "34").unwrap();
|
2022-11-21 09:10:04 +00:00
|
|
|
}
|
|
|
|
|
2022-12-13 14:59:29 +00:00
|
|
|
#[test]
|
2022-12-13 15:06:21 +00:00
|
|
|
fn fix_fields_order() {
|
2022-12-13 14:59:29 +00:00
|
|
|
// ContainerType ContainerID Index ID
|
|
|
|
// TotalOrderStamp RemoteContent MapSet ListOp DeleteSpan ListSlice (mod test)
|
|
|
|
let id = ID::new(0, 1);
|
|
|
|
let id_buf = vec![0, 2];
|
|
|
|
assert_eq!(postcard::from_bytes::<ID>(&id_buf).unwrap(), id);
|
|
|
|
|
|
|
|
let container_type = vec![ContainerType::List, ContainerType::Map, ContainerType::Text];
|
|
|
|
let container_type_buf = vec![3, 2, 1, 0];
|
|
|
|
assert_eq!(
|
|
|
|
postcard::from_bytes::<Vec<ContainerType>>(&container_type_buf).unwrap(),
|
|
|
|
container_type
|
|
|
|
);
|
|
|
|
|
|
|
|
let container_id = vec![
|
|
|
|
ContainerID::new_root("root", ContainerType::List),
|
|
|
|
ContainerID::new_normal(ID::new(0, 0), ContainerType::Text),
|
|
|
|
];
|
|
|
|
let container_id_buf = vec![2, 0, 4, 114, 111, 111, 116, 2, 1, 0, 0, 0];
|
|
|
|
assert_eq!(
|
|
|
|
postcard::from_bytes::<Vec<ContainerID>>(&container_id_buf).unwrap(),
|
|
|
|
container_id
|
|
|
|
);
|
2022-12-19 03:41:10 +00:00
|
|
|
}
|
2022-12-13 14:59:29 +00:00
|
|
|
|
2022-12-19 03:41:10 +00:00
|
|
|
#[test]
|
|
|
|
fn encode_hierarchy() {
|
|
|
|
fn assert_eq(c1: &LoroCore, c2: &LoroCore) {
|
2022-12-21 07:52:28 +00:00
|
|
|
let h1 = c1.hierarchy();
|
|
|
|
let h1 = h1.try_lock().unwrap();
|
2022-12-19 03:41:10 +00:00
|
|
|
|
2022-12-21 07:52:28 +00:00
|
|
|
let h2 = c2.hierarchy();
|
|
|
|
let h2 = h2.try_lock().unwrap();
|
2022-12-19 03:41:10 +00:00
|
|
|
assert_eq!(format!("{:?}", h1), format!("{:?}", h2));
|
2022-12-19 09:20:21 +00:00
|
|
|
assert_eq!(c1.to_json(), c2.to_json());
|
2022-12-19 03:41:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let mut c1 = LoroCore::default();
|
|
|
|
let mut map = c1.get_map("map");
|
|
|
|
let (_, text_id) = {
|
|
|
|
let list_id = map.insert(&c1, "a", ContainerType::List).unwrap();
|
|
|
|
let list = c1.get_container(&list_id.unwrap()).unwrap();
|
2022-12-27 07:15:07 +00:00
|
|
|
let list = list.upgrade().unwrap();
|
2022-12-19 03:41:10 +00:00
|
|
|
let mut list = list.try_lock().unwrap();
|
|
|
|
let list = list.as_list_mut().unwrap();
|
2023-01-15 03:49:23 +00:00
|
|
|
list.insert(&c1, 0, ContainerType::Text).unwrap()
|
2022-12-19 03:41:10 +00:00
|
|
|
};
|
|
|
|
{
|
|
|
|
let text = c1.get_container(&text_id.unwrap()).unwrap();
|
2022-12-27 07:15:07 +00:00
|
|
|
let text = text.upgrade().unwrap();
|
2022-12-19 03:41:10 +00:00
|
|
|
let mut text = text.try_lock().unwrap();
|
|
|
|
let text = text.as_text_mut().unwrap();
|
|
|
|
text.insert(&c1, 0, "text_text");
|
|
|
|
};
|
|
|
|
|
|
|
|
// updates
|
|
|
|
println!("updates");
|
2023-01-16 07:28:10 +00:00
|
|
|
let input = c1.encode_with_cfg(EncodeConfig::update(VersionVector::new()).without_compress());
|
2022-12-19 03:41:10 +00:00
|
|
|
let mut c2 = LoroCore::default();
|
2022-12-19 09:20:21 +00:00
|
|
|
c2.subscribe_deep(Box::new(move |_event| {
|
|
|
|
// println!("event: {:?}", _event);
|
|
|
|
}));
|
2022-12-19 03:41:10 +00:00
|
|
|
c2.decode(&input).unwrap();
|
|
|
|
assert_eq(&c1, &c2);
|
|
|
|
|
|
|
|
// rle updates
|
|
|
|
println!("rle updates");
|
2023-01-16 07:28:10 +00:00
|
|
|
let input =
|
|
|
|
c1.encode_with_cfg(EncodeConfig::rle_update(VersionVector::new()).without_compress());
|
2022-12-19 03:41:10 +00:00
|
|
|
let mut c2 = LoroCore::default();
|
2022-12-19 09:20:21 +00:00
|
|
|
c2.subscribe_deep(Box::new(move |_event| {
|
|
|
|
// println!("event: {:?}", _event);
|
|
|
|
}));
|
2022-12-19 03:41:10 +00:00
|
|
|
c2.decode(&input).unwrap();
|
|
|
|
assert_eq(&c1, &c2);
|
|
|
|
|
|
|
|
// snapshot
|
|
|
|
println!("snapshot");
|
2023-01-16 07:28:10 +00:00
|
|
|
let input = c1.encode_all();
|
2022-12-19 03:41:10 +00:00
|
|
|
let mut c2 = LoroCore::default();
|
2022-12-19 09:20:21 +00:00
|
|
|
c2.subscribe_deep(Box::new(move |_event| {
|
|
|
|
// println!("event: {:?}", _event);
|
|
|
|
}));
|
2022-12-19 03:41:10 +00:00
|
|
|
c2.decode(&input).unwrap();
|
|
|
|
assert_eq(&c1, &c2);
|
2022-11-24 03:06:24 +00:00
|
|
|
}
|
|
|
|
|
2022-10-20 09:34:51 +00:00
|
|
|
#[ctor]
|
|
|
|
fn init_color_backtrace() {
|
|
|
|
color_backtrace::install();
|
|
|
|
}
|