@@ -242,6 +242,158 @@ func TestReviewShowsDiff(t *testing.T) {
242242 }
243243}
244244
245+ func TestMergeBasic (t * testing.T ) {
246+ for _ , backend := range backends {
247+ t .Run (string (backend ), func (t * testing.T ) {
248+ env := joinedEnv (t , backend )
249+ dbDir := forkCloneDir (t , env )
250+
251+ // Switch to PR mode and post.
252+ setMode (t , env , upstream , "pr" )
253+
254+ stdout , _ , err := runWL (t , env , "post" ,
255+ "--title" , "Merge test item" ,
256+ "--type" , "feature" ,
257+ "--no-push" ,
258+ )
259+ if err != nil {
260+ t .Fatalf ("wl post failed: %v" , err )
261+ }
262+ wantedID := extractWantedID (t , stdout )
263+ branch := "wl/" + forkOrg + "/" + wantedID
264+
265+ // Item should NOT be on main yet.
266+ raw := doltSQL (t , dbDir , "SELECT COUNT(*) FROM wanted WHERE id='" + wantedID + "'" )
267+ rows := parseCSV (t , raw )
268+ if len (rows ) >= 2 && strings .TrimSpace (rows [1 ][0 ]) != "0" {
269+ t .Errorf ("item should not be on main before merge, got count: %s" , rows [1 ][0 ])
270+ }
271+
272+ // Merge.
273+ stdout , stderr , err := runWL (t , env , "merge" , branch , "--no-push" )
274+ if err != nil {
275+ t .Fatalf ("wl merge failed: %v\n stdout: %s\n stderr: %s" , err , stdout , stderr )
276+ }
277+ if ! strings .Contains (stdout , "Merged" ) {
278+ t .Errorf ("expected 'Merged' message, got: %s" , stdout )
279+ }
280+ if ! strings .Contains (stdout , "deleted" ) {
281+ t .Errorf ("expected branch deletion message, got: %s" , stdout )
282+ }
283+
284+ // Item should now be on main.
285+ raw = doltSQL (t , dbDir , "SELECT id, title FROM wanted WHERE id='" + wantedID + "'" )
286+ rows = parseCSV (t , raw )
287+ if len (rows ) < 2 {
288+ t .Fatalf ("wanted item %s not found on main after merge" , wantedID )
289+ }
290+ if rows [1 ][1 ] != "Merge test item" {
291+ t .Errorf ("title = %q, want %q" , rows [1 ][1 ], "Merge test item" )
292+ }
293+
294+ // Branch should be gone.
295+ raw = doltSQL (t , dbDir , "SELECT COUNT(*) FROM dolt_branches WHERE name='" + branch + "'" )
296+ rows = parseCSV (t , raw )
297+ if len (rows ) >= 2 && strings .TrimSpace (rows [1 ][0 ]) != "0" {
298+ t .Errorf ("branch %s should be deleted after merge" , branch )
299+ }
300+ })
301+ }
302+ }
303+
304+ func TestMergeKeepBranch (t * testing.T ) {
305+ for _ , backend := range backends {
306+ t .Run (string (backend ), func (t * testing.T ) {
307+ env := joinedEnv (t , backend )
308+ dbDir := forkCloneDir (t , env )
309+
310+ setMode (t , env , upstream , "pr" )
311+
312+ stdout , _ , err := runWL (t , env , "post" ,
313+ "--title" , "Keep branch test" ,
314+ "--type" , "bug" ,
315+ "--no-push" ,
316+ )
317+ if err != nil {
318+ t .Fatalf ("wl post failed: %v" , err )
319+ }
320+ wantedID := extractWantedID (t , stdout )
321+ branch := "wl/" + forkOrg + "/" + wantedID
322+
323+ // Merge with --keep-branch.
324+ stdout , stderr , err := runWL (t , env , "merge" , branch , "--keep-branch" , "--no-push" )
325+ if err != nil {
326+ t .Fatalf ("wl merge failed: %v\n stdout: %s\n stderr: %s" , err , stdout , stderr )
327+ }
328+
329+ // Branch should still exist.
330+ raw := doltSQL (t , dbDir , "SELECT COUNT(*) FROM dolt_branches WHERE name='" + branch + "'" )
331+ rows := parseCSV (t , raw )
332+ if len (rows ) < 2 || strings .TrimSpace (rows [1 ][0 ]) != "1" {
333+ t .Errorf ("branch %s should still exist with --keep-branch" , branch )
334+ }
335+ })
336+ }
337+ }
338+
339+ func TestMergeNonExistentBranch (t * testing.T ) {
340+ for _ , backend := range backends {
341+ t .Run (string (backend ), func (t * testing.T ) {
342+ env := joinedEnv (t , backend )
343+
344+ _ , _ , err := runWL (t , env , "merge" , "wl/fake/w-nonexistent" , "--no-push" )
345+ if err == nil {
346+ t .Fatal ("merge of non-existent branch should fail" )
347+ }
348+ })
349+ }
350+ }
351+
352+ func TestMergeFullLifecycle (t * testing.T ) {
353+ for _ , backend := range backends {
354+ t .Run (string (backend ), func (t * testing.T ) {
355+ env := joinedEnv (t , backend )
356+ dbDir := forkCloneDir (t , env )
357+
358+ // PR mode: post → review --stat → merge → verify on main.
359+ setMode (t , env , upstream , "pr" )
360+
361+ stdout , _ , err := runWL (t , env , "post" ,
362+ "--title" , "Full lifecycle PR" ,
363+ "--type" , "feature" ,
364+ "--no-push" ,
365+ )
366+ if err != nil {
367+ t .Fatalf ("wl post failed: %v" , err )
368+ }
369+ wantedID := extractWantedID (t , stdout )
370+ branch := "wl/" + forkOrg + "/" + wantedID
371+
372+ // Review should show diff.
373+ stdout , stderr , err := runWL (t , env , "review" , branch , "--stat" )
374+ if err != nil {
375+ t .Fatalf ("wl review --stat failed: %v\n stdout: %s\n stderr: %s" , err , stdout , stderr )
376+ }
377+ if ! strings .Contains (stdout , "wanted" ) {
378+ t .Errorf ("review stat should mention 'wanted', got: %s" , stdout )
379+ }
380+
381+ // Merge.
382+ stdout , stderr , err = runWL (t , env , "merge" , branch , "--no-push" )
383+ if err != nil {
384+ t .Fatalf ("wl merge failed: %v\n stdout: %s\n stderr: %s" , err , stdout , stderr )
385+ }
386+
387+ // Verify on main.
388+ raw := doltSQL (t , dbDir , "SELECT title FROM wanted WHERE id='" + wantedID + "'" )
389+ rows := parseCSV (t , raw )
390+ if len (rows ) < 2 || rows [1 ][0 ] != "Full lifecycle PR" {
391+ t .Errorf ("item not found on main after merge" )
392+ }
393+ })
394+ }
395+ }
396+
245397func TestConfigSetGetMode (t * testing.T ) {
246398 for _ , backend := range backends {
247399 t .Run (string (backend ), func (t * testing.T ) {
0 commit comments