github.com/kazu/ghq@v0.8.1-0.20180818162325-dedd532b4440/commands_test.go (about)

     1  package main
     2  
     3  import (
     4  	"flag"
     5  	"io/ioutil"
     6  	"net/url"
     7  	"os"
     8  	"path/filepath"
     9  
    10  	"github.com/urfave/cli"
    11  )
    12  
    13  import (
    14  	. "github.com/onsi/gomega"
    15  	"testing"
    16  )
    17  
    18  func flagSet(name string, flags []cli.Flag) *flag.FlagSet {
    19  	set := flag.NewFlagSet(name, flag.ContinueOnError)
    20  
    21  	for _, f := range flags {
    22  		f.Apply(set)
    23  	}
    24  	return set
    25  }
    26  
    27  func captureReader(block func()) (*os.File, *os.File, error) {
    28  	rOut, wOut, err := os.Pipe()
    29  	if err != nil {
    30  		return nil, nil, err
    31  	}
    32  
    33  	rErr, wErr, err := os.Pipe()
    34  	if err != nil {
    35  		return nil, nil, err
    36  	}
    37  
    38  	defer wOut.Close()
    39  	defer wErr.Close()
    40  
    41  	var stdout, stderr *os.File
    42  	os.Stdout, stdout = wOut, os.Stdout
    43  	os.Stderr, stderr = wErr, os.Stderr
    44  
    45  	defer func() {
    46  		os.Stdout = stdout
    47  		os.Stderr = stderr
    48  	}()
    49  
    50  	block()
    51  
    52  	wOut.Close()
    53  	wErr.Close()
    54  
    55  	return rOut, rErr, nil
    56  }
    57  
    58  func capture(block func()) (string, string, error) {
    59  	rOut, rErr, err := captureReader(block)
    60  	if err != nil {
    61  		return "", "", err
    62  	}
    63  
    64  	bufOut, err := ioutil.ReadAll(rOut)
    65  	if err != nil {
    66  		return "", "", err
    67  	}
    68  
    69  	bufErr, err := ioutil.ReadAll(rErr)
    70  	if err != nil {
    71  		return "", "", err
    72  	}
    73  
    74  	return string(bufOut), string(bufErr), nil
    75  }
    76  
    77  type _cloneArgs struct {
    78  	remote  *url.URL
    79  	local   string
    80  	shallow bool
    81  }
    82  
    83  type _updateArgs struct {
    84  	local string
    85  }
    86  
    87  func withFakeGitBackend(t *testing.T, block func(string, *_cloneArgs, *_updateArgs)) {
    88  	tmpRoot, err := ioutil.TempDir("", "ghq")
    89  	if err != nil {
    90  		t.Fatalf("Could not create tempdir: %s", err)
    91  	}
    92  	defer os.RemoveAll(tmpRoot)
    93  
    94  	// Resolve /var/folders/.../T/... to /private/var/... in OSX
    95  	tmpRoot = func() string {
    96  		wd, err := os.Getwd()
    97  		if err != nil {
    98  			t.Fatalf("os.Getwd(): %s", err)
    99  		}
   100  
   101  		defer func() {
   102  			err := os.Chdir(wd)
   103  			if err != nil {
   104  				t.Fatalf("os.Chdir(): %s", err)
   105  			}
   106  		}()
   107  
   108  		err = os.Chdir(tmpRoot)
   109  		if err != nil {
   110  			t.Fatalf("os.Chdir(): %s", err)
   111  		}
   112  
   113  		tmpRoot, err := os.Getwd()
   114  		if err != nil {
   115  			t.Fatalf("os.Getwd(): %s", err)
   116  		}
   117  
   118  		return tmpRoot
   119  	}()
   120  
   121  	_localRepositoryRoots = []string{tmpRoot}
   122  	defer func() { _localRepositoryRoots = []string{} }()
   123  
   124  	var cloneArgs _cloneArgs
   125  	var updateArgs _updateArgs
   126  
   127  	var originalGitBackend = GitBackend
   128  	GitBackend = &VCSBackend{
   129  		Clone: func(remote *url.URL, local string, shallow bool) error {
   130  			cloneArgs = _cloneArgs{
   131  				remote:  remote,
   132  				local:   filepath.FromSlash(local),
   133  				shallow: shallow,
   134  			}
   135  			return nil
   136  		},
   137  		Update: func(local string) error {
   138  			updateArgs = _updateArgs{
   139  				local: local,
   140  			}
   141  			return nil
   142  		},
   143  	}
   144  	defer func() { GitBackend = originalGitBackend }()
   145  
   146  	block(tmpRoot, &cloneArgs, &updateArgs)
   147  }
   148  
   149  func TestCommandGet(t *testing.T) {
   150  	RegisterTestingT(t)
   151  
   152  	app := newApp()
   153  
   154  	withFakeGitBackend(t, func(tmpRoot string, cloneArgs *_cloneArgs, updateArgs *_updateArgs) {
   155  		localDir := filepath.Join(tmpRoot, "github.com", "motemen", "ghq-test-repo")
   156  
   157  		app.Run([]string{"", "get", "motemen/ghq-test-repo"})
   158  
   159  		Expect(cloneArgs.remote.String()).To(Equal("https://github.com/motemen/ghq-test-repo"))
   160  		Expect(filepath.ToSlash(cloneArgs.local)).To(Equal(filepath.ToSlash(localDir)))
   161  		Expect(cloneArgs.shallow).To(Equal(false))
   162  	})
   163  
   164  	withFakeGitBackend(t, func(tmpRoot string, cloneArgs *_cloneArgs, updateArgs *_updateArgs) {
   165  		localDir := filepath.Join(tmpRoot, "github.com", "motemen", "ghq-test-repo")
   166  
   167  		app.Run([]string{"", "get", "-p", "motemen/ghq-test-repo"})
   168  
   169  		Expect(cloneArgs.remote.String()).To(Equal("ssh://git@github.com/motemen/ghq-test-repo"))
   170  		Expect(filepath.ToSlash(cloneArgs.local)).To(Equal(filepath.ToSlash(localDir)))
   171  	})
   172  
   173  	withFakeGitBackend(t, func(tmpRoot string, cloneArgs *_cloneArgs, updateArgs *_updateArgs) {
   174  		localDir := filepath.Join(tmpRoot, "github.com", "motemen", "ghq-test-repo")
   175  		// mark as "already cloned", the condition may change later
   176  		os.MkdirAll(filepath.Join(localDir, ".git"), 0755)
   177  
   178  		app.Run([]string{"", "get", "-u", "motemen/ghq-test-repo"})
   179  
   180  		Expect(updateArgs.local).To(Equal(localDir))
   181  	})
   182  
   183  	withFakeGitBackend(t, func(tmpRoot string, cloneArgs *_cloneArgs, updateArgs *_updateArgs) {
   184  		localDir := filepath.Join(tmpRoot, "github.com", "motemen", "ghq-test-repo")
   185  		app.Run([]string{"", "get", "-p", "motemen/ghq-test-repo"})
   186  
   187  		Expect(cloneArgs.remote.String()).To(Equal("ssh://git@github.com/motemen/ghq-test-repo"))
   188  		Expect(filepath.ToSlash(cloneArgs.local)).To(Equal(filepath.ToSlash(localDir)))
   189  		Expect(cloneArgs.shallow).To(Equal(false))
   190  	})
   191  
   192  	withFakeGitBackend(t, func(tmpRoot string, cloneArgs *_cloneArgs, updateArgs *_updateArgs) {
   193  		localDir := filepath.Join(tmpRoot, "github.com", "motemen", "ghq-test-repo")
   194  
   195  		app.Run([]string{"", "get", "-shallow", "motemen/ghq-test-repo"})
   196  
   197  		Expect(cloneArgs.remote.String()).To(Equal("https://github.com/motemen/ghq-test-repo"))
   198  		Expect(filepath.ToSlash(cloneArgs.local)).To(Equal(filepath.ToSlash(localDir)))
   199  		Expect(cloneArgs.shallow).To(Equal(true))
   200  	})
   201  
   202  	withFakeGitBackend(t, func(tmpRoot string, cloneArgs *_cloneArgs, updateArgs *_updateArgs) {
   203  		localDir := filepath.Join(tmpRoot, "github.com", "motemen")
   204  		os.MkdirAll(localDir, 0755)
   205  		wd, _ := os.Getwd()
   206  		defer os.Chdir(wd)
   207  		os.Chdir(localDir)
   208  
   209  		app.Run([]string{"", "get", "-u", "." + string(filepath.Separator) + "ghq-test-repo"})
   210  
   211  		Expect(cloneArgs.remote.String()).To(Equal("https://github.com/motemen/ghq-test-repo"))
   212  		Expect(cloneArgs.local).To(Equal(filepath.Join(localDir, "ghq-test-repo")))
   213  	})
   214  
   215  	withFakeGitBackend(t, func(tmpRoot string, cloneArgs *_cloneArgs, updateArgs *_updateArgs) {
   216  		localDir := filepath.Join(tmpRoot, "github.com", "motemen", "ghq-test-repo")
   217  		os.MkdirAll(localDir, 0755)
   218  		wd, _ := os.Getwd()
   219  		defer os.Chdir(wd)
   220  		os.Chdir(localDir)
   221  
   222  		app.Run([]string{"", "get", "-u", ".." + string(filepath.Separator) + "ghq-another-test-repo"})
   223  
   224  		Expect(cloneArgs.remote.String()).To(Equal("https://github.com/motemen/ghq-another-test-repo"))
   225  		Expect(cloneArgs.local).To(Equal(filepath.Join(tmpRoot, "github.com", "motemen", "ghq-another-test-repo")))
   226  	})
   227  }
   228  
   229  func TestCommandList(t *testing.T) {
   230  	RegisterTestingT(t)
   231  
   232  	_, _, err := capture(func() {
   233  		app := cli.NewApp()
   234  		flagSet := flagSet("list", commandList.Flags)
   235  		c := cli.NewContext(app, flagSet, nil)
   236  
   237  		doList(c)
   238  	})
   239  
   240  	Expect(err).To(BeNil())
   241  }
   242  
   243  func TestCommandListUnique(t *testing.T) {
   244  	RegisterTestingT(t)
   245  
   246  	_, _, err := capture(func() {
   247  		app := cli.NewApp()
   248  		flagSet := flagSet("list", commandList.Flags)
   249  		flagSet.Parse([]string{"--unique"})
   250  		c := cli.NewContext(app, flagSet, nil)
   251  
   252  		doList(c)
   253  	})
   254  
   255  	Expect(err).To(BeNil())
   256  }
   257  
   258  func TestCommandListUnknown(t *testing.T) {
   259  	RegisterTestingT(t)
   260  
   261  	_, _, err := capture(func() {
   262  		app := cli.NewApp()
   263  		flagSet := flagSet("list", commandList.Flags)
   264  		flagSet.Parse([]string{"--unknown-flag"})
   265  		c := cli.NewContext(app, flagSet, nil)
   266  
   267  		doList(c)
   268  	})
   269  
   270  	Expect(err).To(BeNil())
   271  }