github.com/magodo/ged@v0.0.0-20230330082724-5cc965b061e6/main_test.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"regexp"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/require"
    11  )
    12  
    13  func TestParsePattern(t *testing.T) {
    14  	cases := []struct {
    15  		p      string
    16  		expect interface{} // error or Pattern
    17  	}{
    18  		{
    19  			p:      ``,
    20  			expect: fmt.Errorf("no pattern specified"),
    21  		},
    22  		{
    23  			p:      `pkg`,
    24  			expect: fmt.Errorf("invalid pattern specified"),
    25  		},
    26  		{
    27  			p: `pkg:ident`,
    28  			expect: Pattern{
    29  				pkg:   regexp.MustCompile(`^pkg$`),
    30  				ident: regexp.MustCompile(`^ident$`),
    31  			},
    32  		},
    33  		{
    34  			p: `pkg:ident:field`,
    35  			expect: Pattern{
    36  				pkg:   regexp.MustCompile(`^pkg$`),
    37  				ident: regexp.MustCompile(`^ident$`),
    38  				field: regexp.MustCompile(`^field$`),
    39  			},
    40  		},
    41  		{
    42  			p: `pkg:ident:method()`,
    43  			expect: Pattern{
    44  				pkg:    regexp.MustCompile(`^pkg$`),
    45  				ident:  regexp.MustCompile(`^ident$`),
    46  				method: regexp.MustCompile(`^method$`),
    47  			},
    48  		},
    49  	}
    50  
    51  	for idx, c := range cases {
    52  		out, err := parsePattern(c.p)
    53  		switch c := c.expect.(type) {
    54  		case error:
    55  			if err == nil {
    56  				require.Fail(t, "expect error", idx)
    57  			}
    58  			if !strings.Contains(err.Error(), c.Error()) {
    59  				require.Contains(t, err.Error(), c.Error(), idx)
    60  			}
    61  		case Pattern:
    62  			if (out.pkg == nil) != (c.pkg == nil) {
    63  				require.Fail(t, fmt.Sprintf("package pattern exists=%t", out.pkg == nil), idx)
    64  			}
    65  			if c.pkg != nil {
    66  				require.Equal(t, c.pkg.String(), out.pkg.String(), idx)
    67  			}
    68  			if (out.ident == nil) != (c.ident == nil) {
    69  				require.Fail(t, fmt.Sprintf("ident pattern exists=%t", out.ident == nil), idx)
    70  			}
    71  			if c.ident != nil {
    72  				require.Equal(t, c.ident.String(), out.ident.String(), idx)
    73  			}
    74  			if (out.field == nil) != (c.field == nil) {
    75  				require.Fail(t, fmt.Sprintf("field pattern exists=%t", out.field == nil), idx)
    76  			}
    77  			if c.field != nil {
    78  				require.Equal(t, c.field.String(), out.field.String(), idx)
    79  			}
    80  			if (out.method == nil) != (c.method == nil) {
    81  				require.Fail(t, fmt.Sprintf("method pattern exists=%t", out.method == nil), idx)
    82  			}
    83  			if c.method != nil {
    84  				require.Equal(t, c.method.String(), out.method.String(), idx)
    85  			}
    86  		}
    87  	}
    88  }
    89  
    90  func TestFindDepInPackages(t *testing.T) {
    91  	root, _ := os.Getwd()
    92  	cases := []struct {
    93  		name   string
    94  		pwd    string
    95  		p      string
    96  		gopkgs []string
    97  		expect string
    98  	}{
    99  		{
   100  			name:   "Find package type",
   101  			pwd:    "./testdata/usepkg1/pkgtype",
   102  			p:      "uut/pkg1:T1",
   103  			gopkgs: []string{"."},
   104  			expect: fmt.Sprintf(`uut/pkg1 T1:
   105  	%s/testdata/usepkg1/pkgtype/pkgtype.go:8:11
   106  `, root),
   107  		},
   108  		{
   109  			name:   "Find package func",
   110  			pwd:    "./testdata/usepkg1/pkgfunc",
   111  			p:      "uut/pkg1:F1",
   112  			gopkgs: []string{"."},
   113  			expect: fmt.Sprintf(`uut/pkg1 F1:
   114  	%s/testdata/usepkg1/pkgfunc/pkgfunc.go:8:7
   115  `, root),
   116  		},
   117  		{
   118  			name:   "Find regular struct field",
   119  			pwd:    "./testdata/usepkg1/typefield",
   120  			p:      "uut/pkg1:T1:T1F1",
   121  			gopkgs: []string{"."},
   122  			expect: fmt.Sprintf(`uut/pkg1 T1.T1F1:
   123  	%s/testdata/usepkg1/typefield/typefield.go:10:6
   124  `, root),
   125  		},
   126  		{
   127  			name:   "Find struct embedded field",
   128  			pwd:    "./testdata/usepkg1/typefield",
   129  			p:      "uut/pkg1:T1:T2",
   130  			gopkgs: []string{"."},
   131  			expect: fmt.Sprintf(`uut/pkg1 T1.T2:
   132  	%s/testdata/usepkg1/typefield/typefield.go:12:6
   133  `, root),
   134  		},
   135  		{
   136  			name:   "Find struct field that is a field of an embedded field",
   137  			pwd:    "./testdata/usepkg1/typefield",
   138  			p:      "uut/pkg1:T1:T2F1",
   139  			gopkgs: []string{"."},
   140  			expect: fmt.Sprintf(`uut/pkg1 T1.T2F1:
   141  	%s/testdata/usepkg1/typefield/typefield.go:11:6
   142  `, root),
   143  		},
   144  		{
   145  			name:   "Find field of an embedded struct that is not explicitly referenced should return nothing",
   146  			pwd:    "./testdata/usepkg1/typefield",
   147  			p:      "uut/pkg1:T2:T2F1",
   148  			gopkgs: []string{"."},
   149  			expect: "",
   150  		},
   151  		{
   152  			name:   "Find method on a type, for both the type or a pointer to the type",
   153  			pwd:    "./testdata/usepkg1/typemethod",
   154  			p:      "uut/pkg1:T1:F1()",
   155  			gopkgs: []string{"."},
   156  			expect: fmt.Sprintf(`uut/pkg1 T1.F1():
   157  	%s/testdata/usepkg1/typemethod/typemethod.go:9:2
   158  	%s/testdata/usepkg1/typemethod/typemethod.go:13:2
   159  `, root, root),
   160  		},
   161  		{
   162  			name:   "Find method on the pointer to a type, for both the type or a pointer to the type",
   163  			pwd:    "./testdata/usepkg1/typemethod",
   164  			p:      "uut/pkg1:T1:F2()",
   165  			gopkgs: []string{"."},
   166  			expect: fmt.Sprintf(`uut/pkg1 T1.F2():
   167  	%s/testdata/usepkg1/typemethod/typemethod.go:10:2
   168  	%s/testdata/usepkg1/typemethod/typemethod.go:14:2
   169  `, root, root),
   170  		},
   171  		{
   172  			name:   "Find a method across packages",
   173  			pwd:    "./testdata/crosspkgs",
   174  			p:      "uut/pkg.*:T1:F1()",
   175  			gopkgs: []string{"."},
   176  			expect: fmt.Sprintf(`uut/pkg1 T1.F1():
   177  	%s/testdata/crosspkgs/crosspkgs.go:11:2
   178  uut/pkg2 T1.F1():
   179  	%s/testdata/crosspkgs/crosspkgs.go:12:2
   180  `, root, root),
   181  		},
   182  		{
   183  			name:   "Find method patterns (F.*) across packages",
   184  			pwd:    "./testdata/crosspkgs",
   185  			p:      "uut/pkg.*:T1:F.*()",
   186  			gopkgs: []string{"."},
   187  			expect: fmt.Sprintf(`uut/pkg1 T1.F1():
   188  	%s/testdata/crosspkgs/crosspkgs.go:11:2
   189  uut/pkg2 T1.F1():
   190  	%s/testdata/crosspkgs/crosspkgs.go:12:2
   191  uut/pkg2 T1.F2():
   192  	%s/testdata/crosspkgs/crosspkgs.go:13:2
   193  `, root, root, root),
   194  		},
   195  	}
   196  
   197  	for _, c := range cases {
   198  		os.Chdir(c.pwd)
   199  		pattern, err := parsePattern(c.p)
   200  		require.NoError(t, err, c.name)
   201  		matches, err := pattern.FindDepInPackages(c.gopkgs)
   202  		require.NoError(t, err, c.name)
   203  		require.Equal(t, c.expect, matches.String(), c.name)
   204  		os.Chdir(root)
   205  	}
   206  }