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  }