From f5283fb7474818280868b135557c87091243fd6a Mon Sep 17 00:00:00 2001 From: Joao Pedro Henrique Date: Tue, 24 Oct 2023 00:47:33 -0300 Subject: [PATCH] feat: Add case in which both parents add different nodes --- merge/src/lib.rs | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/merge/src/lib.rs b/merge/src/lib.rs index 41f5f4a..6bd1393 100644 --- a/merge/src/lib.rs +++ b/merge/src/lib.rs @@ -148,6 +148,17 @@ pub fn merge( }) } + cur_left = children_left_it.next(); + cur_right = children_right_it.next(); + } else if !has_matching_base_left + && !has_matching_base_right + && matching_left_right.is_none() + { + result_children.push(CSTNode::Conflict { + left: Box::new(Some(cur_left.unwrap().to_owned())), + right: Box::new(Some(cur_right.unwrap().to_owned())), + }); + cur_left = children_left_it.next(); cur_right = children_right_it.next(); } @@ -212,6 +223,28 @@ mod tests { assert_eq!(expected_merge, merged_tree_swap) } + fn assert_merge_output_is( + base: CSTNode, + parent_a: CSTNode, + parent_b: CSTNode, + expected_merge: CSTNode, + ) { + let matchings_base_parent_a = ordered_tree_matching(&base, &parent_a); + let matchings_base_parent_b = ordered_tree_matching(&base, &parent_b); + let matchings_parents = ordered_tree_matching(&parent_a, &parent_b); + + let merged_tree = merge( + &base, + &parent_a, + &parent_b, + &matchings_base_parent_a, + &matchings_base_parent_b, + &matchings_parents, + ); + + assert_eq!(expected_merge, merged_tree); + } + #[test] fn if_i_am_merging_three_unchanged_nodes_it_is_a_success() { let node = CSTNode::Terminal { @@ -612,4 +645,47 @@ mod tests { merged_tree_swap ); } + + #[test] + fn if_both_parents_add_different_nodes_then_we_have_a_conflict() { + let base = CSTNode::NonTerminal { + kind: "kind".into(), + children: vec![], + }; + + let left = CSTNode::NonTerminal { + kind: "kind".into(), + children: vec![CSTNode::Terminal { + kind: "kind_a".into(), + value: "value_a".into(), + }], + }; + + let right = CSTNode::NonTerminal { + kind: "kind".into(), + children: vec![CSTNode::Terminal { + kind: "kind_b".into(), + value: "value_b".into(), + }], + }; + + assert_merge_output_is( + base, + left, + right, + CSTNode::NonTerminal { + kind: "kind".into(), + children: vec![CSTNode::Conflict { + left: Box::new(Some(CSTNode::Terminal { + kind: "kind_a".into(), + value: "value_a".into(), + })), + right: Box::new(Some(CSTNode::Terminal { + kind: "kind_b".into(), + value: "value_b".into(), + })), + }], + }, + ) + } }