mirror of
https://github.com/loro-dev/loro.git
synced 2025-01-22 21:07:43 +00:00
fix: checkout into middle of marks
This commit is contained in:
parent
672062c9d1
commit
35854743f0
2 changed files with 88 additions and 26 deletions
|
@ -11371,6 +11371,42 @@ fn gc_fuzz_23() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn gc_fuzz_25() {
|
||||||
|
test_multi_sites_with_gc(
|
||||||
|
5,
|
||||||
|
vec![FuzzTarget::All],
|
||||||
|
&mut [
|
||||||
|
Handle {
|
||||||
|
site: 219,
|
||||||
|
target: 0,
|
||||||
|
container: 0,
|
||||||
|
action: Generic(GenericAction {
|
||||||
|
value: I32(0),
|
||||||
|
bool: true,
|
||||||
|
key: 0,
|
||||||
|
pos: 0,
|
||||||
|
length: 0,
|
||||||
|
prop: 33685248,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
Handle {
|
||||||
|
site: 219,
|
||||||
|
target: 255,
|
||||||
|
container: 207,
|
||||||
|
action: Generic(GenericAction {
|
||||||
|
value: Container(Unknown(255)),
|
||||||
|
bool: true,
|
||||||
|
key: 8,
|
||||||
|
pos: 576742222985166848,
|
||||||
|
length: 15852445288443686912,
|
||||||
|
prop: 557810552588529338,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn minify() {
|
fn minify() {
|
||||||
minify_error(
|
minify_error(
|
||||||
|
|
|
@ -666,14 +666,14 @@ impl DiffCalculatorTrait for ListDiffCalculator {
|
||||||
|
|
||||||
match &op.op().content {
|
match &op.op().content {
|
||||||
crate::op::InnerContent::List(l) => match l {
|
crate::op::InnerContent::List(l) => match l {
|
||||||
crate::container::list::list_op::InnerListOp::Insert { slice, pos } => {
|
InnerListOp::Insert { slice, pos } => {
|
||||||
self.tracker.insert(
|
self.tracker.insert(
|
||||||
op.id_full(),
|
op.id_full(),
|
||||||
*pos,
|
*pos,
|
||||||
RichtextChunk::new_text(slice.0.clone()),
|
RichtextChunk::new_text(slice.0.clone()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
crate::container::list::list_op::InnerListOp::Delete(del) => {
|
InnerListOp::Delete(del) => {
|
||||||
self.tracker.delete(
|
self.tracker.delete(
|
||||||
op.id_start(),
|
op.id_start(),
|
||||||
del.id_start,
|
del.id_start,
|
||||||
|
@ -916,7 +916,7 @@ impl DiffCalculatorTrait for RichtextDiffCalculator {
|
||||||
| InnerListOp::Set { .. } => {
|
| InnerListOp::Set { .. } => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
crate::container::list::list_op::InnerListOp::InsertText {
|
InnerListOp::InsertText {
|
||||||
slice: _,
|
slice: _,
|
||||||
unicode_start,
|
unicode_start,
|
||||||
unicode_len: len,
|
unicode_len: len,
|
||||||
|
@ -931,10 +931,10 @@ impl DiffCalculatorTrait for RichtextDiffCalculator {
|
||||||
(),
|
(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
crate::container::list::list_op::InnerListOp::Delete(del) => {
|
InnerListOp::Delete(del) => {
|
||||||
diff.delete(del.start() as usize, del.atom_len());
|
diff.delete(del.start() as usize, del.atom_len());
|
||||||
}
|
}
|
||||||
crate::container::list::list_op::InnerListOp::StyleStart {
|
InnerListOp::StyleStart {
|
||||||
start,
|
start,
|
||||||
end,
|
end,
|
||||||
key,
|
key,
|
||||||
|
@ -958,8 +958,37 @@ impl DiffCalculatorTrait for RichtextDiffCalculator {
|
||||||
(),
|
(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
crate::container::list::list_op::InnerListOp::StyleEnd => {
|
InnerListOp::StyleEnd => {
|
||||||
let (style_op, pos) = last_style_start.take().unwrap();
|
let (style_op, pos) = match last_style_start.take() {
|
||||||
|
Some((style_op, pos)) => (style_op, pos),
|
||||||
|
None => {
|
||||||
|
let Some(start_op) = oplog.get_op_that_includes(op.id().inc(-1))
|
||||||
|
else {
|
||||||
|
panic!("Unhandled checkout case")
|
||||||
|
};
|
||||||
|
|
||||||
|
let InnerListOp::StyleStart {
|
||||||
|
key,
|
||||||
|
value,
|
||||||
|
info,
|
||||||
|
end,
|
||||||
|
..
|
||||||
|
} = start_op.content.as_list().unwrap()
|
||||||
|
else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
let style_op = Arc::new(StyleOp {
|
||||||
|
lamport: op.lamport() - 1,
|
||||||
|
peer: op.peer,
|
||||||
|
cnt: op.id_start().counter - 1,
|
||||||
|
key: key.clone(),
|
||||||
|
value: value.clone(),
|
||||||
|
info: *info,
|
||||||
|
});
|
||||||
|
|
||||||
|
(style_op, *end)
|
||||||
|
}
|
||||||
|
};
|
||||||
assert_eq!(style_op.peer, op.peer);
|
assert_eq!(style_op.peer, op.peer);
|
||||||
assert_eq!(style_op.cnt, op.id_start().counter - 1);
|
assert_eq!(style_op.cnt, op.id_start().counter - 1);
|
||||||
diff.insert_value(
|
diff.insert_value(
|
||||||
|
@ -986,7 +1015,7 @@ impl DiffCalculatorTrait for RichtextDiffCalculator {
|
||||||
| InnerListOp::Set { .. } => {
|
| InnerListOp::Set { .. } => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
crate::container::list::list_op::InnerListOp::InsertText {
|
InnerListOp::InsertText {
|
||||||
slice: _,
|
slice: _,
|
||||||
unicode_start,
|
unicode_start,
|
||||||
unicode_len: len,
|
unicode_len: len,
|
||||||
|
@ -998,7 +1027,7 @@ impl DiffCalculatorTrait for RichtextDiffCalculator {
|
||||||
RichtextChunk::new_text(*unicode_start..*unicode_start + *len),
|
RichtextChunk::new_text(*unicode_start..*unicode_start + *len),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
crate::container::list::list_op::InnerListOp::Delete(del) => {
|
InnerListOp::Delete(del) => {
|
||||||
tracker.delete(
|
tracker.delete(
|
||||||
op.id_start(),
|
op.id_start(),
|
||||||
del.id_start,
|
del.id_start,
|
||||||
|
@ -1007,7 +1036,7 @@ impl DiffCalculatorTrait for RichtextDiffCalculator {
|
||||||
del.is_reversed(),
|
del.is_reversed(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
crate::container::list::list_op::InnerListOp::StyleStart {
|
InnerListOp::StyleStart {
|
||||||
start,
|
start,
|
||||||
end,
|
end,
|
||||||
key,
|
key,
|
||||||
|
@ -1033,7 +1062,7 @@ impl DiffCalculatorTrait for RichtextDiffCalculator {
|
||||||
RichtextChunk::new_style_anchor(style_id as u32, AnchorType::Start),
|
RichtextChunk::new_style_anchor(style_id as u32, AnchorType::Start),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
crate::container::list::list_op::InnerListOp::StyleEnd => {
|
InnerListOp::StyleEnd => {
|
||||||
let id = op.id();
|
let id = op.id();
|
||||||
if let Some(pos) = styles.iter().rev().position(|(op, _pos)| {
|
if let Some(pos) = styles.iter().rev().position(|(op, _pos)| {
|
||||||
op.peer == id.peer && op.cnt == id.counter - 1
|
op.peer == id.peer && op.cnt == id.counter - 1
|
||||||
|
@ -1182,20 +1211,17 @@ impl DiffCalculatorTrait for RichtextDiffCalculator {
|
||||||
let lamport = rich_op.lamport();
|
let lamport = rich_op.lamport();
|
||||||
let content = op.content.as_list().unwrap();
|
let content = op.content.as_list().unwrap();
|
||||||
match content {
|
match content {
|
||||||
crate::container::list::list_op::InnerListOp::InsertText {
|
InnerListOp::InsertText { slice, .. } => {
|
||||||
slice,
|
delta.push_insert(
|
||||||
..
|
RichtextStateChunk::Text(TextChunk::new(
|
||||||
} => {
|
slice.clone(),
|
||||||
delta.push_insert(
|
IdFull::new(id.peer, op.counter, lamport),
|
||||||
RichtextStateChunk::Text(TextChunk::new(
|
)),
|
||||||
slice.clone(),
|
(),
|
||||||
IdFull::new(id.peer, op.counter, lamport),
|
);
|
||||||
)),
|
}
|
||||||
(),
|
_ => unreachable!("{:?}", content),
|
||||||
);
|
|
||||||
}
|
}
|
||||||
_ => unreachable!("{:?}", content),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1348,14 +1374,14 @@ impl DiffCalculatorTrait for MovableListDiffCalculator {
|
||||||
let real_op = op.op();
|
let real_op = op.op();
|
||||||
match &real_op.content {
|
match &real_op.content {
|
||||||
crate::op::InnerContent::List(l) => match l {
|
crate::op::InnerContent::List(l) => match l {
|
||||||
crate::container::list::list_op::InnerListOp::Insert { slice, pos } => {
|
InnerListOp::Insert { slice, pos } => {
|
||||||
this.tracker.insert(
|
this.tracker.insert(
|
||||||
op.id_full(),
|
op.id_full(),
|
||||||
*pos,
|
*pos,
|
||||||
RichtextChunk::new_text(slice.0.clone()),
|
RichtextChunk::new_text(slice.0.clone()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
crate::container::list::list_op::InnerListOp::Delete(del) => {
|
InnerListOp::Delete(del) => {
|
||||||
this.tracker.delete(
|
this.tracker.delete(
|
||||||
op.id_start(),
|
op.id_start(),
|
||||||
del.id_start,
|
del.id_start,
|
||||||
|
|
Loading…
Reference in a new issue