github.com/x-motemen/ghq@v1.6.1/cmd_list_test.go (about) 1 package main 2 3 import ( 4 "flag" 5 "os" 6 "path/filepath" 7 "runtime" 8 "sort" 9 "strings" 10 "sync" 11 "testing" 12 13 "github.com/urfave/cli/v2" 14 ) 15 16 func flagSet(name string, flags []cli.Flag) *flag.FlagSet { 17 set := flag.NewFlagSet(name, flag.ContinueOnError) 18 19 for _, f := range flags { 20 f.Apply(set) 21 } 22 return set 23 } 24 25 func TestCommandList(t *testing.T) { 26 _, _, err := capture(func() { 27 app := cli.NewApp() 28 flagSet := flagSet("list", commandList.Flags) 29 c := cli.NewContext(app, flagSet, nil) 30 31 doList(c) 32 }) 33 34 if err != nil { 35 t.Errorf("error should be nil, but: %v", err) 36 } 37 } 38 39 func TestCommandListUnique(t *testing.T) { 40 _, _, err := capture(func() { 41 app := cli.NewApp() 42 flagSet := flagSet("list", commandList.Flags) 43 flagSet.Parse([]string{"--unique"}) 44 c := cli.NewContext(app, flagSet, nil) 45 46 doList(c) 47 }) 48 49 if err != nil { 50 t.Errorf("error should be nil, but: %v", err) 51 } 52 } 53 54 func TestCommandListUnknown(t *testing.T) { 55 _, _, err := capture(func() { 56 app := cli.NewApp() 57 flagSet := flagSet("list", commandList.Flags) 58 flagSet.Parse([]string{"--unknown-flag"}) 59 c := cli.NewContext(app, flagSet, nil) 60 61 doList(c) 62 }) 63 64 if err != nil { 65 t.Errorf("error should be nil, but: %v", err) 66 } 67 } 68 69 func sortLines(s string) string { 70 ss := strings.Split(strings.TrimSpace(s), "\n") 71 sort.Strings(ss) 72 return strings.Join(ss, "\n") 73 } 74 75 func equalPathLines(lhs, rhs string) bool { 76 return sortLines(lhs) == sortLines(rhs) 77 } 78 79 func TestDoList_query(t *testing.T) { 80 gitRepos := []string{ 81 "github.com/motemen/ghq", 82 "github.com/motemen/gobump", 83 "github.com/motemen/gore", 84 "github.com/Songmu/gobump", 85 "github.com/test/Awesome", 86 "golang.org/x/crypt", 87 "golang.org/x/image", 88 } 89 svnRepos := []string{ 90 "github.com/msh5/svntest", 91 } 92 testCases := []struct { 93 name string 94 args []string 95 expect string 96 }{{ 97 name: "repo match", 98 args: []string{"ghq"}, 99 expect: "github.com/motemen/ghq\n", 100 }, { 101 name: "unique", 102 args: []string{"--unique", "ghq"}, 103 expect: "ghq\n", 104 }, { 105 name: "host only doesn't match", 106 args: []string{"github.com"}, 107 expect: "", 108 }, { 109 name: "host and slash match", 110 args: []string{"golang.org/"}, 111 expect: "golang.org/x/crypt\ngolang.org/x/image\n", 112 }, { 113 name: "host and user", 114 args: []string{"github.com/Songmu"}, 115 expect: "github.com/Songmu/gobump\n", 116 }, { 117 name: "with scheme", 118 args: []string{"https://github.com/motemen/ghq"}, 119 expect: "github.com/motemen/ghq\n", 120 }, { 121 name: "exact", 122 args: []string{"-exact", "gobump"}, 123 expect: "github.com/Songmu/gobump\ngithub.com/motemen/gobump\n", 124 }, { 125 name: "query", 126 args: []string{"men/go"}, 127 expect: "github.com/motemen/gobump\ngithub.com/motemen/gore\n", 128 }, { 129 name: "exact query", 130 args: []string{"-exact", "men/go"}, 131 expect: "", 132 }, { 133 name: "vcs", 134 args: []string{"--vcs", "svn"}, 135 expect: "github.com/msh5/svntest\n", 136 }, { 137 name: "smartcasing fuzzy", 138 args: []string{"awesome"}, 139 expect: "github.com/test/Awesome\n", 140 }, { 141 name: "smartcasing exact", 142 args: []string{"Awesome"}, 143 expect: "github.com/test/Awesome\n", 144 }, { 145 name: "smartcasing exact fail", 146 args: []string{"aWesome"}, 147 expect: "", 148 }} 149 150 withFakeGitBackend(t, func(t *testing.T, tmproot string, _ *_cloneArgs, _ *_updateArgs) { 151 for _, r := range gitRepos { 152 os.MkdirAll(filepath.Join(tmproot, r, ".git"), 0755) 153 } 154 for _, r := range svnRepos { 155 os.MkdirAll(filepath.Join(tmproot, r, ".svn"), 0755) 156 } 157 for _, tc := range testCases { 158 t.Run(tc.name, func(t *testing.T) { 159 args := append([]string{"ghq", "list"}, tc.args...) 160 out, _, _ := capture(func() { 161 newApp().Run(args) 162 }) 163 if !equalPathLines(out, tc.expect) { 164 t.Errorf("got:\n%s\nexpect:\n%s", out, tc.expect) 165 } 166 if strings.Contains(tc.name, "unique") { 167 return 168 } 169 argsFull := append([]string{"ghq", "list", "--full-path"}, tc.args...) 170 fullExpect := tc.expect 171 if fullExpect != "" { 172 if runtime.GOOS == "windows" { 173 fullExpect = strings.ReplaceAll(fullExpect, `/`, `\`) 174 } 175 fullExpect = tmproot + string(filepath.Separator) + strings.TrimSpace(fullExpect) 176 fullExpect = strings.ReplaceAll(fullExpect, "\n", "\n"+tmproot+string(filepath.Separator)) 177 fullExpect += "\n" 178 } 179 out, _, _ = capture(func() { 180 newApp().Run(argsFull) 181 }) 182 if !equalPathLines(out, fullExpect) { 183 t.Errorf("got:\n%s\nexpect:\n%s", out, fullExpect) 184 } 185 }) 186 } 187 }) 188 } 189 190 func TestDoList_unique(t *testing.T) { 191 defer func(orig []string) { _localRepositoryRoots = orig }(_localRepositoryRoots) 192 193 tmp1 := newTempDir(t) 194 tmp2 := newTempDir(t) 195 196 _localRepositoryRoots = nil 197 localRepoOnce = &sync.Once{} 198 rootPaths := []string{tmp1, tmp2} 199 setEnv(t, envGhqRoot, strings.Join(rootPaths, string(os.PathListSeparator))) 200 for _, rootPath := range rootPaths { 201 os.MkdirAll(filepath.Join(rootPath, "github.com/motemen/ghq/.git"), 0755) 202 } 203 out, _, _ := capture(func() { 204 newApp().Run([]string{"ghq", "list", "--unique"}) 205 }) 206 if out != "ghq\n" { 207 t.Errorf("got: %s, expect: ghq\n", out) 208 } 209 } 210 211 func TestDoList_unknownRoot(t *testing.T) { 212 defer func(orig []string) { _localRepositoryRoots = orig }(_localRepositoryRoots) 213 setEnv(t, envGhqRoot, "/path/to/unknown-ghq") 214 _localRepositoryRoots = nil 215 localRepoOnce = &sync.Once{} 216 217 err := newApp().Run([]string{"ghq", "list"}) 218 if err != nil { 219 t.Errorf("error should be nil, but: %v", err) 220 } 221 } 222 223 func TestDoList_notPermittedRoot(t *testing.T) { 224 if runtime.GOOS == "windows" { 225 t.SkipNow() 226 } 227 defer func(orig []string) { _localRepositoryRoots = orig }(_localRepositoryRoots) 228 tmpdir := newTempDir(t) 229 defer os.Chmod(tmpdir, 0755) 230 setEnv(t, envGhqRoot, tmpdir) 231 232 _localRepositoryRoots = nil 233 localRepoOnce = &sync.Once{} 234 os.Chmod(tmpdir, 0000) 235 236 err := newApp().Run([]string{"ghq", "list"}) 237 if err != nil { 238 t.Errorf("error should be nil, but: %+v", err) 239 } 240 } 241 242 func TestDoList_withSystemHiddenDir(t *testing.T) { 243 if runtime.GOOS == "windows" { 244 t.SkipNow() 245 } 246 defer func(orig []string) { _localRepositoryRoots = orig }(_localRepositoryRoots) 247 tmpdir := newTempDir(t) 248 systemHidden := filepath.Join(tmpdir, ".system") 249 os.MkdirAll(systemHidden, 0000) 250 defer os.Chmod(systemHidden, 0755) 251 setEnv(t, envGhqRoot, tmpdir) 252 253 _localRepositoryRoots = nil 254 localRepoOnce = &sync.Once{} 255 256 err := newApp().Run([]string{"ghq", "list"}) 257 if err != nil { 258 t.Errorf("error should be nil, but: %v", err) 259 } 260 }