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) } }
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) } }