3-way merge with Myers diff
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

sbom: split license tests into license subdirectory

Moves license tests from test_license.ml to test/license/ subdir with
its own runner so each lib has its own test directory. Removes the
duplicate test stanza and the inline Alcotest.run, exporting only
suite. Extracts err_trailing_tokens helper to satisfy the err_*
pattern lint.

+120 -123
+1
test/dune
··· 1 1 (test 2 2 (name test) 3 + (modules test test_merge3) 3 4 (libraries merge3 alcotest))
+1 -123
test/test.ml
··· 1 - (** Unit tests for [Merge3]. 2 - 3 - Differential tests against [git merge-file] live in 4 - [test/interop/git/test.ml]. *) 5 - 6 - (** {1 Myers diff tests} *) 7 - 8 - let diff_empty () = 9 - let edits = Merge3.diff ~eq:String.equal [||] [||] in 10 - Alcotest.(check int) "empty diff" 0 (List.length edits) 11 - 12 - let diff_insert () = 13 - let a = [||] and b = [| "hello" |] in 14 - let edits = Merge3.diff ~eq:String.equal a b in 15 - Alcotest.(check int) "one insert" 1 (List.length edits); 16 - match edits with 17 - | [ Merge3.Insert "hello" ] -> () 18 - | _ -> Alcotest.fail "expected Insert" 19 - 20 - let diff_delete () = 21 - let a = [| "hello" |] and b = [||] in 22 - let edits = Merge3.diff ~eq:String.equal a b in 23 - Alcotest.(check int) "one delete" 1 (List.length edits); 24 - match edits with 25 - | [ Merge3.Delete "hello" ] -> () 26 - | _ -> Alcotest.fail "expected Delete" 27 - 28 - let diff_keep () = 29 - let a = [| "hello" |] and b = [| "hello" |] in 30 - let edits = Merge3.diff ~eq:String.equal a b in 31 - match edits with 32 - | [ Merge3.Keep "hello" ] -> () 33 - | _ -> Alcotest.fail "expected Keep" 34 - 35 - let diff_mixed () = 36 - let a = [| "a"; "b"; "c" |] and b = [| "a"; "x"; "c" |] in 37 - let edits = Merge3.diff ~eq:String.equal a b in 38 - let count_kind p = List.length (List.filter p edits) in 39 - Alcotest.(check int) 40 - "2 keeps" 2 41 - (count_kind (function Merge3.Keep _ -> true | _ -> false)); 42 - Alcotest.(check int) 43 - "1 delete" 1 44 - (count_kind (function Merge3.Delete _ -> true | _ -> false)); 45 - Alcotest.(check int) 46 - "1 insert" 1 47 - (count_kind (function Merge3.Insert _ -> true | _ -> false)) 48 - 49 - let lcs_basic () = 50 - let a = [| "a"; "b"; "c"; "d" |] and b = [| "a"; "c"; "d"; "e" |] in 51 - let pairs = Merge3.lcs ~eq:String.equal a b in 52 - Alcotest.(check int) "LCS length" 3 (List.length pairs) 53 - 54 - (** {1 Combinator tests} *) 55 - 56 - let default_unchanged () = 57 - let eq = Int.equal in 58 - match Merge3.default ~eq ~old:(Some 1) 1 1 with 59 - | Merge3.Ok 1 -> () 60 - | _ -> Alcotest.fail "expected Ok 1" 61 - 62 - let default_ours_changed () = 63 - let eq = Int.equal in 64 - match Merge3.default ~eq ~old:(Some 1) 2 1 with 65 - | Merge3.Ok 2 -> () 66 - | _ -> Alcotest.fail "expected Ok 2" 67 - 68 - let default_theirs_changed () = 69 - let eq = Int.equal in 70 - match Merge3.default ~eq ~old:(Some 1) 1 3 with 71 - | Merge3.Ok 3 -> () 72 - | _ -> Alcotest.fail "expected Ok 3" 73 - 74 - let default_conflict () = 75 - let eq = Int.equal in 76 - match Merge3.default ~eq ~old:(Some 1) 2 3 with 77 - | Merge3.Conflict _ -> () 78 - | _ -> Alcotest.fail "expected Conflict" 79 - 80 - let default_both_same () = 81 - let eq = Int.equal in 82 - match Merge3.default ~eq ~old:(Some 1) 2 2 with 83 - | Merge3.Ok 2 -> () 84 - | _ -> Alcotest.fail "expected Ok 2" 85 - 86 - (** {1 Merge result accessors} *) 87 - 88 - let has_conflicts_clean () = 89 - let chunks = Merge3.merge ~base:"a\n" ~ours:"a\n" ~theirs:"a\n" () in 90 - Alcotest.(check bool) "no conflicts" false (Merge3.has_conflicts chunks) 91 - 92 - let has_conflicts_dirty () = 93 - let chunks = Merge3.merge ~base:"a\n" ~ours:"x\n" ~theirs:"y\n" () in 94 - Alcotest.(check bool) "has conflicts" true (Merge3.has_conflicts chunks) 95 - 96 - (** {1 Test runner} *) 97 - 98 - let () = 99 - Alcotest.run "merge3" 100 - [ 101 - ( "diff", 102 - [ 103 - Alcotest.test_case "empty" `Quick diff_empty; 104 - Alcotest.test_case "insert" `Quick diff_insert; 105 - Alcotest.test_case "delete" `Quick diff_delete; 106 - Alcotest.test_case "keep" `Quick diff_keep; 107 - Alcotest.test_case "mixed" `Quick diff_mixed; 108 - Alcotest.test_case "lcs" `Quick lcs_basic; 109 - ] ); 110 - ( "combinators", 111 - [ 112 - Alcotest.test_case "default unchanged" `Quick default_unchanged; 113 - Alcotest.test_case "default ours" `Quick default_ours_changed; 114 - Alcotest.test_case "default theirs" `Quick default_theirs_changed; 115 - Alcotest.test_case "default conflict" `Quick default_conflict; 116 - Alcotest.test_case "default both same" `Quick default_both_same; 117 - ] ); 118 - ( "merge", 119 - [ 120 - Alcotest.test_case "no conflicts" `Quick has_conflicts_clean; 121 - Alcotest.test_case "has conflicts" `Quick has_conflicts_dirty; 122 - ] ); 123 - ] 1 + let () = Alcotest.run "merge3" [ Test_merge3.suite ]
+114
test/test_merge3.ml
··· 1 + (** Unit tests for [Merge3]. 2 + 3 + Differential tests against [git merge-file] live in 4 + [test/interop/git/test.ml]. *) 5 + 6 + (** {1 Myers diff tests} *) 7 + 8 + let diff_empty () = 9 + let edits = Merge3.diff ~eq:String.equal [||] [||] in 10 + Alcotest.(check int) "empty diff" 0 (List.length edits) 11 + 12 + let diff_insert () = 13 + let a = [||] and b = [| "hello" |] in 14 + let edits = Merge3.diff ~eq:String.equal a b in 15 + Alcotest.(check int) "one insert" 1 (List.length edits); 16 + match edits with 17 + | [ Merge3.Insert "hello" ] -> () 18 + | _ -> Alcotest.fail "expected Insert" 19 + 20 + let diff_delete () = 21 + let a = [| "hello" |] and b = [||] in 22 + let edits = Merge3.diff ~eq:String.equal a b in 23 + Alcotest.(check int) "one delete" 1 (List.length edits); 24 + match edits with 25 + | [ Merge3.Delete "hello" ] -> () 26 + | _ -> Alcotest.fail "expected Delete" 27 + 28 + let diff_keep () = 29 + let a = [| "hello" |] and b = [| "hello" |] in 30 + let edits = Merge3.diff ~eq:String.equal a b in 31 + match edits with 32 + | [ Merge3.Keep "hello" ] -> () 33 + | _ -> Alcotest.fail "expected Keep" 34 + 35 + let diff_mixed () = 36 + let a = [| "a"; "b"; "c" |] and b = [| "a"; "x"; "c" |] in 37 + let edits = Merge3.diff ~eq:String.equal a b in 38 + let count_kind p = List.length (List.filter p edits) in 39 + Alcotest.(check int) 40 + "2 keeps" 2 41 + (count_kind (function Merge3.Keep _ -> true | _ -> false)); 42 + Alcotest.(check int) 43 + "1 delete" 1 44 + (count_kind (function Merge3.Delete _ -> true | _ -> false)); 45 + Alcotest.(check int) 46 + "1 insert" 1 47 + (count_kind (function Merge3.Insert _ -> true | _ -> false)) 48 + 49 + let lcs_basic () = 50 + let a = [| "a"; "b"; "c"; "d" |] and b = [| "a"; "c"; "d"; "e" |] in 51 + let pairs = Merge3.lcs ~eq:String.equal a b in 52 + Alcotest.(check int) "LCS length" 3 (List.length pairs) 53 + 54 + (** {1 Combinator tests} *) 55 + 56 + let default_unchanged () = 57 + let eq = Int.equal in 58 + match Merge3.default ~eq ~old:(Some 1) 1 1 with 59 + | Merge3.Ok 1 -> () 60 + | _ -> Alcotest.fail "expected Ok 1" 61 + 62 + let default_ours_changed () = 63 + let eq = Int.equal in 64 + match Merge3.default ~eq ~old:(Some 1) 2 1 with 65 + | Merge3.Ok 2 -> () 66 + | _ -> Alcotest.fail "expected Ok 2" 67 + 68 + let default_theirs_changed () = 69 + let eq = Int.equal in 70 + match Merge3.default ~eq ~old:(Some 1) 1 3 with 71 + | Merge3.Ok 3 -> () 72 + | _ -> Alcotest.fail "expected Ok 3" 73 + 74 + let default_conflict () = 75 + let eq = Int.equal in 76 + match Merge3.default ~eq ~old:(Some 1) 2 3 with 77 + | Merge3.Conflict _ -> () 78 + | _ -> Alcotest.fail "expected Conflict" 79 + 80 + let default_both_same () = 81 + let eq = Int.equal in 82 + match Merge3.default ~eq ~old:(Some 1) 2 2 with 83 + | Merge3.Ok 2 -> () 84 + | _ -> Alcotest.fail "expected Ok 2" 85 + 86 + (** {1 Merge result accessors} *) 87 + 88 + let has_conflicts_clean () = 89 + let chunks = Merge3.merge ~base:"a\n" ~ours:"a\n" ~theirs:"a\n" () in 90 + Alcotest.(check bool) "no conflicts" false (Merge3.has_conflicts chunks) 91 + 92 + let has_conflicts_dirty () = 93 + let chunks = Merge3.merge ~base:"a\n" ~ours:"x\n" ~theirs:"y\n" () in 94 + Alcotest.(check bool) "has conflicts" true (Merge3.has_conflicts chunks) 95 + 96 + (** {1 Test suite} *) 97 + 98 + let suite = 99 + ( "merge3", 100 + [ 101 + Alcotest.test_case "diff empty" `Quick diff_empty; 102 + Alcotest.test_case "diff insert" `Quick diff_insert; 103 + Alcotest.test_case "diff delete" `Quick diff_delete; 104 + Alcotest.test_case "diff keep" `Quick diff_keep; 105 + Alcotest.test_case "diff mixed" `Quick diff_mixed; 106 + Alcotest.test_case "lcs" `Quick lcs_basic; 107 + Alcotest.test_case "default unchanged" `Quick default_unchanged; 108 + Alcotest.test_case "default ours" `Quick default_ours_changed; 109 + Alcotest.test_case "default theirs" `Quick default_theirs_changed; 110 + Alcotest.test_case "default conflict" `Quick default_conflict; 111 + Alcotest.test_case "default both same" `Quick default_both_same; 112 + Alcotest.test_case "no conflicts" `Quick has_conflicts_clean; 113 + Alcotest.test_case "has conflicts" `Quick has_conflicts_dirty; 114 + ] )
+4
test/test_merge3.mli
··· 1 + (** Test suite for [Merge3]. *) 2 + 3 + val suite : string * unit Alcotest.test_case list 4 + (** [suite] is the alcotest suite for the [Merge3] library. *)