Example #1
0
func TestComplete(t *testing.T) {
	scope := ast.NewScope()
	scope.Packages["pkg1"] = &ast.Package{
		Name: "pkg1",
		Classes: []*ast.Class{
			{
				Name: "A",
				Relations: []*ast.Relation{
					{Target: "io.Reader", RelType: ast.Implementation},
					{Target: "io.Writer", RelType: ast.Implementation},
					{Target: "io.Closer", RelType: ast.Implementation},
					{Target: "io.ReadWriter", RelType: ast.Implementation},
					{Target: "io.ReadCloser", RelType: ast.Implementation},
					{Target: "io.WriteCloser", RelType: ast.Implementation},
					{Target: "io.ReadWriteCloser", RelType: ast.Implementation},
				},
			},
			{
				Name: "XError",
				Relations: []*ast.Relation{
					{Target: "error", RelType: ast.Implementation},
					{Target: "fmt.Stringer", RelType: ast.Implementation},
					{Target: "os.PathError", RelType: ast.Association},
				},
				Methods: []*ast.Method{
					{Name: "Error"},
				},
			},
		},
	}
	err := annotator.Complete(scope)
	if err != nil {
		t.Fatal(err)
	}
	if len(scope.Packages) != 5 {
		for _, pkg := range scope.Packages {
			t.Logf("%+v", pkg)
		}
		t.Fatalf("pkg1, io, fmt, os, \"\" should be completed: %#v", scope.Packages)
	}
	if pkg, ok := scope.Packages["io"]; !ok || len(pkg.Interfaces) != 7 {
		t.Fatalf("io interfaces should be completed", pkg)
	}
	if pkg, ok := scope.Packages["fmt"]; !ok || len(pkg.Interfaces) != 1 || pkg.Interfaces[0].Name != "Stringer" {
		t.Fatalf("fmt.Stringer interface should be completed", pkg)
	}
	if pkg, ok := scope.Packages[""]; !ok || len(pkg.Interfaces) != 1 || pkg.Interfaces[0].Name != "error" {
		t.Fatalf(".error interface should be completed", pkg)
	}
	if pkg, ok := scope.Packages["os"]; !ok || len(pkg.Classes) != 1 || pkg.Classes[0].Name != "PathError" {
		t.Fatalf("os.PathError class should be completed", pkg)
	}
	pkg, ok := scope.Packages["pkg1"]
	if !ok || len(pkg.Classes) != 2 || pkg.Classes[1].Name != "XError" {
		t.Fatalf("pkg1.A and pkg1.XError class should be completed", pkg)
	}
	if cl := pkg.Classes[1]; len(cl.Methods) != 1 || cl.Methods[0].Name != "Error" {
		t.Fatalf("pkg1.XError methods should be completed", cl)
	}
}
Example #2
0
func TestCut(t *testing.T) {
	scope := ast.NewScope()
	pkg := &ast.Package{
		Name: "pkg1",
		Classes: []*ast.Class{
			{
				Name: "A",
				Relations: []*ast.Relation{
					{Target: "io.Reader", RelType: ast.Implementation},
					{Target: "io.Writer", RelType: ast.Implementation},
					{Target: "io.Closer", RelType: ast.Implementation},
					{Target: "io.ReadWriter", RelType: ast.Implementation},
					{Target: "io.ReadCloser", RelType: ast.Implementation},
					{Target: "io.WriteCloser", RelType: ast.Implementation},
					{Target: "io.ReadWriteCloser", RelType: ast.Implementation},
					{Target: "fmt.Stringer", RelType: ast.Implementation},
					{Target: "pkg1.XError", RelType: ast.Composition},
					{Target: "error", RelType: ast.Implementation},
				},
			},
			{
				Name: "XError",
				Relations: []*ast.Relation{
					{Target: "error", RelType: ast.Implementation},
				},
			},
		},
	}
	scope.Packages["pkg1"] = pkg
	scope.Packages["io"] = &ast.Package{
		Name:    "io",
		Classes: []*ast.Class{},
		Interfaces: []*ast.Interface{
			{Name: "Reader", Relations: []*ast.Relation{}},
			{Name: "Writer", Relations: []*ast.Relation{}},
			{Name: "Closer", Relations: []*ast.Relation{}},
			{Name: "ReadWriter", Relations: []*ast.Relation{
				{Target: "io.Reader", RelType: ast.Extension},
				{Target: "io.Writer", RelType: ast.Extension},
			}},
			{Name: "ReadCloser", Relations: []*ast.Relation{
				{Target: "io.Reader", RelType: ast.Extension},
				{Target: "io.Closer", RelType: ast.Extension},
			}},
			{Name: "WriteCloser", Relations: []*ast.Relation{
				{Target: "io.Writer", RelType: ast.Extension},
				{Target: "io.Closer", RelType: ast.Extension},
			}},
			{Name: "ReadWriteCloser", Relations: []*ast.Relation{
				{Target: "io.ReadWriter", RelType: ast.Extension},
				{Target: "io.WriteCloser", RelType: ast.Extension},
				{Target: "io.ReadCloser", RelType: ast.Extension},
			}},
		},
	}
	scope.Packages["fmt"] = &ast.Package{
		Name:    "fmt",
		Classes: []*ast.Class{},
		Interfaces: []*ast.Interface{
			{Name: "Stringer", Relations: []*ast.Relation{}},
		},
	}
	scope.Packages[""] = &ast.Package{
		Name:    "",
		Classes: []*ast.Class{},
		Interfaces: []*ast.Interface{
			{Name: "error", Relations: []*ast.Relation{}},
		},
	}
	err := annotator.Cut(scope)
	if err != nil {
		t.Fatal(err)
	}
	if len(pkg.Classes[0].Relations) != 3 {
		for _, rel := range pkg.Classes[0].Relations {
			t.Logf("%+v", rel)
		}
		t.Fatalf("io.ReadWriteCloser, fmt.Stringer and XError should be preserved: %#v", pkg.Classes[0].Relations)
	}
	if pkg.Classes[0].Relations[0].Target != "io.ReadWriteCloser" {
		t.Fatalf("other io.* should be omitted: %#v", pkg.Classes[0].Relations[0])
	}
	if pkg.Classes[0].Relations[1].Target != "fmt.Stringer" {
		t.Fatalf("fmt.Stringer should be preserved: %#v", pkg.Classes[0].Relations[1])
	}
	if pkg.Classes[0].Relations[2].Target != "pkg1.XError" {
		t.Fatalf("XError should be preserved: %#v", pkg.Classes[0].Relations[2])
	}
	if len(pkg.Classes[1].Relations) != 1 {
		t.Fatalf(".error should be preserved: %#v", pkg.Classes[1].Relations)
	}
}