unidiff-comments/changeset_reader_test.go
Norwin Roosen 71ca77c7f9
restructure package
so parser-only usage has no dependencies
2020-12-19 09:50:07 +01:00

200 lines
4.1 KiB
Go

package unidiff
import (
"bytes"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"testing"
"gitea.com/noerw/unidiff-comments/types"
"gitea.com/noerw/unidiff-comments/writer"
)
type diffTest struct {
name string
in []byte
out []byte
err []byte
}
func TestReadChangeset(t *testing.T) {
for _, testCase := range getParseTests("_test") {
expected := string(testCase.out)
changeset, err := ReadChangeset(bytes.NewBuffer(testCase.in))
if err != nil {
if err.Error() != strings.TrimSpace(string(testCase.err)) {
t.Logf("while testing on `%s`\n", testCase.name)
t.Fatal(err)
} else {
continue
}
}
buf := &bytes.Buffer{}
err = writer.WriteChangeset(changeset, buf)
if err != nil {
panic(err)
}
actual := buf.String()
if actual != expected {
t.Logf("while testing on `%s`\n", testCase.name)
t.Logf("expected:\n%#v", expected)
t.Logf("actual:\n%#v", actual)
t.Logf("diff:\n%v", makeDiff(actual, expected))
t.FailNow()
}
}
}
func TestNewCommentForLine(t *testing.T) {
tests := []struct {
file string
expected types.CommentAnchor
}{
{"_test/new_comment_to_add.diff",
types.CommentAnchor{
Line: 3, LineType: types.SegmentTypeAdded, Path: "/tmp/b"}},
{"_test/new_comment_to_del.diff",
types.CommentAnchor{
Line: 3,
LineType: types.SegmentTypeRemoved,
Path: "/tmp/a",
}},
{"_test/new_comment_to_ctx_with_add.diff",
types.CommentAnchor{
Line: 3,
LineType: types.SegmentTypeContext,
Path: "/tmp/a",
}},
{"_test/new_comment_to_ctx_with_add_del.diff",
types.CommentAnchor{
Line: 5,
LineType: types.SegmentTypeContext,
Path: "/tmp/a",
}},
}
for _, test := range tests {
changesetText, err := ioutil.ReadFile(test.file)
if err != nil {
t.Fatal(err)
}
changeset, err := ReadChangeset(bytes.NewBuffer(changesetText))
if err != nil {
t.Fatal(err)
}
if len(changeset.Diffs) != 1 {
t.Fatal("unexpected number of changeset")
t.FailNow()
}
comment := changeset.Diffs[0].LineComments[0]
if comment.Anchor.Line != test.expected.Line {
t.Fatal("comment binded to incorrect line")
t.FailNow()
}
if comment.Anchor.LineType != test.expected.LineType {
t.Fatal("unexpected line type")
t.FailNow()
}
if comment.Anchor.Path != test.expected.Path {
t.Fatal("unexpected path", comment.Anchor.Path)
t.FailNow()
}
}
}
func TestDoNotAddNestedCommentsToLineComments(t *testing.T) {
changesetText, err := ioutil.ReadFile("_test/with_one_nested_comment.diff")
if err != nil {
t.Fatal(err)
}
changeset, err := ReadChangeset(bytes.NewBuffer(changesetText))
if err != nil {
t.Fatal(err)
}
if len(changeset.Diffs[0].LineComments) != 1 {
t.Fatal("expected only one line comment")
}
}
func getParseTests(dir string) []*diffTest {
diffTests := make(map[string]*diffTest)
diffTestsList := make([]*diffTest, 0)
reChangesetTest := regexp.MustCompile(`/([^/]+)\.(in|out|err)\.diff$`)
filepath.Walk(dir, func(path string, f os.FileInfo, err error) error {
if !reChangesetTest.MatchString(path) {
return nil
}
matches := reChangesetTest.FindStringSubmatch(path)
caseName := matches[1]
if _, exist := diffTests[caseName]; !exist {
diffTests[caseName] = &diffTest{}
}
diffTests[caseName].name = caseName
var target *[]byte
switch matches[2] {
case "in":
target = &diffTests[caseName].in
case "out":
target = &diffTests[caseName].out
case "err":
target = &diffTests[caseName].err
}
*target, _ = ioutil.ReadFile(path)
diffTestsList = append(diffTestsList, diffTests[caseName])
return nil
})
for _, val := range diffTests {
if val.out == nil {
val.out = val.in
}
}
return diffTestsList
}
func makeDiff(actual, expected string) string {
a, _ := ioutil.TempFile(os.TempDir(), "actual")
defer func() {
os.Remove(a.Name())
}()
b, _ := ioutil.TempFile(os.TempDir(), "expected")
defer func() {
os.Remove(b.Name())
}()
a.WriteString(actual)
b.WriteString(expected)
cmd := exec.Command("diff", "-u", b.Name(), a.Name())
buf := bytes.NewBuffer([]byte{})
cmd.Stdout = buf
cmd.Run()
return buf.String()
}