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 }