github.com/motemen/ghq@v1.0.3/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  		"golang.org/x/crypt",
    86  		"golang.org/x/image",
    87  	}
    88  	svnRepos := []string{
    89  		"github.com/msh5/svntest",
    90  	}
    91  	testCases := []struct {
    92  		name   string
    93  		args   []string
    94  		expect string
    95  	}{{
    96  		name:   "repo match",
    97  		args:   []string{"ghq"},
    98  		expect: "github.com/motemen/ghq\n",
    99  	}, {
   100  		name:   "unique",
   101  		args:   []string{"--unique", "ghq"},
   102  		expect: "ghq\n",
   103  	}, {
   104  		name:   "host only doesn't match",
   105  		args:   []string{"github.com"},
   106  		expect: "",
   107  	}, {
   108  		name:   "host and slash match",
   109  		args:   []string{"golang.org/"},
   110  		expect: "golang.org/x/crypt\ngolang.org/x/image\n",
   111  	}, {
   112  		name:   "host and user",
   113  		args:   []string{"github.com/Songmu"},
   114  		expect: "github.com/Songmu/gobump\n",
   115  	}, {
   116  		name:   "with scheme",
   117  		args:   []string{"https://github.com/motemen/ghq"},
   118  		expect: "github.com/motemen/ghq\n",
   119  	}, {
   120  		name:   "exact",
   121  		args:   []string{"-exact", "gobump"},
   122  		expect: "github.com/Songmu/gobump\ngithub.com/motemen/gobump\n",
   123  	}, {
   124  		name:   "query",
   125  		args:   []string{"men/go"},
   126  		expect: "github.com/motemen/gobump\ngithub.com/motemen/gore\n",
   127  	}, {
   128  		name:   "exact query",
   129  		args:   []string{"-exact", "men/go"},
   130  		expect: "",
   131  	}, {
   132  		name:   "vcs",
   133  		args:   []string{"--vcs", "svn"},
   134  		expect: "github.com/msh5/svntest\n",
   135  	}}
   136  
   137  	withFakeGitBackend(t, func(t *testing.T, tmproot string, _ *_cloneArgs, _ *_updateArgs) {
   138  		for _, r := range gitRepos {
   139  			os.MkdirAll(filepath.Join(tmproot, r, ".git"), 0755)
   140  		}
   141  		for _, r := range svnRepos {
   142  			os.MkdirAll(filepath.Join(tmproot, r, ".svn"), 0755)
   143  		}
   144  		for _, tc := range testCases {
   145  			t.Run(tc.name, func(t *testing.T) {
   146  				args := append([]string{"ghq", "list"}, tc.args...)
   147  				out, _, _ := capture(func() {
   148  					newApp().Run(args)
   149  				})
   150  				if !equalPathLines(out, tc.expect) {
   151  					t.Errorf("got:\n%s\nexpect:\n%s", out, tc.expect)
   152  				}
   153  				if strings.Contains(tc.name, "unique") {
   154  					return
   155  				}
   156  				argsFull := append([]string{"ghq", "list", "--full-path"}, tc.args...)
   157  				fullExpect := tc.expect
   158  				if fullExpect != "" {
   159  					if runtime.GOOS == "windows" {
   160  						fullExpect = strings.ReplaceAll(fullExpect, `/`, `\`)
   161  					}
   162  					fullExpect = tmproot + string(filepath.Separator) + strings.TrimSpace(fullExpect)
   163  					fullExpect = strings.ReplaceAll(fullExpect, "\n", "\n"+tmproot+string(filepath.Separator))
   164  					fullExpect += "\n"
   165  				}
   166  				out, _, _ = capture(func() {
   167  					newApp().Run(argsFull)
   168  				})
   169  				if !equalPathLines(out, fullExpect) {
   170  					t.Errorf("got:\n%s\nexpect:\n%s", out, fullExpect)
   171  				}
   172  			})
   173  		}
   174  	})
   175  }
   176  
   177  func TestDoList_unique(t *testing.T) {
   178  	defer func(orig []string) { _localRepositoryRoots = orig }(_localRepositoryRoots)
   179  	defer func(orig string) { os.Setenv(envGhqRoot, orig) }(os.Getenv(envGhqRoot))
   180  
   181  	tmp1 := newTempDir(t)
   182  	defer os.RemoveAll(tmp1)
   183  	tmp2 := newTempDir(t)
   184  	defer os.RemoveAll(tmp2)
   185  
   186  	_localRepositoryRoots = nil
   187  	localRepoOnce = &sync.Once{}
   188  	rootPaths := []string{tmp1, tmp2}
   189  	os.Setenv(envGhqRoot, strings.Join(rootPaths, string(os.PathListSeparator)))
   190  	for _, rootPath := range rootPaths {
   191  		os.MkdirAll(filepath.Join(rootPath, "github.com/motemen/ghq/.git"), 0755)
   192  	}
   193  	out, _, _ := capture(func() {
   194  		newApp().Run([]string{"ghq", "list", "--unique"})
   195  	})
   196  	if out != "ghq\n" {
   197  		t.Errorf("got: %s, expect: ghq\n", out)
   198  	}
   199  }
   200  
   201  func TestDoList_unknownRoot(t *testing.T) {
   202  	defer func(orig []string) { _localRepositoryRoots = orig }(_localRepositoryRoots)
   203  	defer tmpEnv(envGhqRoot, "/path/to/unknown-ghq")()
   204  	_localRepositoryRoots = nil
   205  	localRepoOnce = &sync.Once{}
   206  
   207  	err := newApp().Run([]string{"ghq", "list"})
   208  	if err != nil {
   209  		t.Errorf("error should be nil, but: %v", err)
   210  	}
   211  }
   212  
   213  func TestDoList_notPermittedRoot(t *testing.T) {
   214  	if runtime.GOOS == "windows" {
   215  		t.SkipNow()
   216  	}
   217  	defer func(orig []string) { _localRepositoryRoots = orig }(_localRepositoryRoots)
   218  	tmpdir := newTempDir(t)
   219  	defer func(dir string) {
   220  		os.Chmod(dir, 0755)
   221  		os.RemoveAll(dir)
   222  	}(tmpdir)
   223  	defer tmpEnv(envGhqRoot, tmpdir)()
   224  
   225  	_localRepositoryRoots = nil
   226  	localRepoOnce = &sync.Once{}
   227  	os.Chmod(tmpdir, 0000)
   228  
   229  	err := newApp().Run([]string{"ghq", "list"})
   230  	if err != nil {
   231  		t.Errorf("error should be nil, but: %+v", err)
   232  	}
   233  }
   234  
   235  func TestDoList_withSystemHiddenDir(t *testing.T) {
   236  	if runtime.GOOS == "windows" {
   237  		t.SkipNow()
   238  	}
   239  	defer func(orig []string) { _localRepositoryRoots = orig }(_localRepositoryRoots)
   240  	tmpdir := newTempDir(t)
   241  	systemHidden := filepath.Join(tmpdir, ".system")
   242  	os.MkdirAll(systemHidden, 0000)
   243  	defer func(dir string) {
   244  		os.Chmod(systemHidden, 0755)
   245  		os.RemoveAll(dir)
   246  	}(tmpdir)
   247  	defer tmpEnv(envGhqRoot, tmpdir)()
   248  
   249  	_localRepositoryRoots = nil
   250  	localRepoOnce = &sync.Once{}
   251  
   252  	err := newApp().Run([]string{"ghq", "list"})
   253  	if err != nil {
   254  		t.Errorf("error should be nil, but: %v", err)
   255  	}
   256  }