Skip to content
quarry Artifact [8637abb3ec]
Login

Artifact [8637abb3ec]

Artifact 8637abb3ece6485010138eea8e36cb36705b3ea279d97e5c7769de4440ec9301:


package diff

import (
	"strings"
	"testing"
)

// The ticket's own motivating case, from pikchr a7f1c35b: one line
// gains "(including" at its end. The reader must see THAT — a marked
// range on each side — not two fully-coloured lines to diff by eye.
func TestIntraLineMarks(t *testing.T) {
	u := `--- a/pikchr.y
+++ b/pikchr.y
@@ -5220,7 +5220,8 @@ static void x(void){
   int i;
-  /* Remove leading and trailing whitespace from each argument.
+  /* Remove leading and trailing whitespace from each argument (including
   more;
`
	files := Parse(u)
	if len(files) != 1 || files[0].Path != "pikchr.y" || files[0].Change != Change {
		t.Fatalf("files = %+v", files)
	}
	h := files[0].Hunks[0]
	if h.OldStart != 5220 || h.NewStart != 5220 || h.Header != "static void x(void){" {
		t.Fatalf("hunk = %+v", h)
	}
	// Numbers: context carries both, deletion old-only, addition new-only.
	if h.Lines[0].OldNum != 5220 || h.Lines[0].NewNum != 5220 ||
		h.Lines[1].OldNum != 5221 || h.Lines[1].NewNum != 0 ||
		h.Lines[2].NewNum != 5221 || h.Lines[2].OldNum != 0 ||
		h.Lines[3].OldNum != 5222 || h.Lines[3].NewNum != 5222 {
		t.Fatalf("numbering wrong: %+v", h.Lines)
	}

	Enrich(files)
	del, add := files[0].Hunks[0].Lines[1], files[0].Hunks[0].Lines[2]
	marked := func(l Line) string {
		var b strings.Builder
		for _, tok := range l.Tokens {
			if tok.Mark {
				b.WriteString(tok.Text)
			}
		}
		return b.String()
	}
	if got := marked(add); !strings.Contains(got, "(including") {
		t.Fatalf("addition marks = %q, want the added words", got)
	}
	if got := marked(add); strings.Contains(got, "Remove leading") {
		t.Fatalf("addition over-marked the unchanged text: %q", got)
	}
	if got := marked(del); strings.Contains(got, "Remove leading") {
		t.Fatalf("deletion over-marked: %q", got)
	}
	// Syntax classes arrived positionally (pikchr.y matches a lexer via
	// the .y suffix); reassembling all tokens must reproduce the text
	// exactly — the splice must never lose or duplicate a byte.
	var whole strings.Builder
	for _, tok := range add.Tokens {
		whole.WriteString(tok.Text)
	}
	if whole.String() != "  /* Remove leading and trailing whitespace from each argument (including" {
		t.Fatalf("splice corrupted the text: %q", whole.String())
	}
}

// A new file and a deleted file are CHANGE KINDS, not diffs against
// /dev/null; and total rewrites mark nothing — a fully-marked pair
// says less than plain colour.
func TestChangeKindsAndRewriteGuard(t *testing.T) {
	u := `--- /dev/null
+++ b/fresh.go
@@ -0,0 +1,1 @@
+package fresh
--- a/gone.go
+++ /dev/null
@@ -1,1 +0,0 @@
-package gone
`
	files := Parse(u)
	if len(files) != 2 || files[0].Change != Added || files[0].Path != "fresh.go" ||
		files[1].Change != Deleted || files[1].Path != "gone.go" {
		t.Fatalf("kinds = %+v", files)
	}

	da, db := wordDiff("completely different text here", "nothing shared at all now")
	if da != nil || db != nil {
		t.Fatalf("a rewrite was word-marked: %v %v", da, db)
	}
}