github.com/q2/git-lfs@v0.5.1-0.20150410234700-03a0d4cec40e/commands/commands_test.go (about)

     1  package commands
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/bmizerany/assert"
     6  	"io"
     7  	"io/ioutil"
     8  	"os"
     9  	"os/exec"
    10  	"path/filepath"
    11  	"strings"
    12  	"testing"
    13  )
    14  
    15  var (
    16  	Root         string
    17  	Bin          string
    18  	TempDir      string
    19  	GitEnv       []string
    20  	JoinedGitEnv string
    21  	configKeys   = []string{"Endpoint", "LocalWorkingDir", "LocalGitDir", "LocalMediaDir", "TempDir"}
    22  )
    23  
    24  func NewRepository(t *testing.T, name string) *Repository {
    25  	path := filepath.Join(TempDir, name)
    26  	r := &Repository{
    27  		T:        t,
    28  		Name:     name,
    29  		Path:     path,
    30  		Paths:    []string{path},
    31  		Commands: make([]*TestCommand, 0),
    32  	}
    33  	r.clone()
    34  	r.Path = expand(path)
    35  	return r
    36  }
    37  
    38  func AssertIncludeString(t *testing.T, expected string, actual []string) {
    39  	found := false
    40  	for _, line := range actual {
    41  		if line == expected {
    42  			found = true
    43  		}
    44  	}
    45  	assert.Tf(t, found, "%s not included.", expected)
    46  }
    47  
    48  func GlobalGitConfig(t *testing.T) []string {
    49  	o := cmd(t, "git", "config", "-l", "--global")
    50  	return strings.Split(o, "\n")
    51  }
    52  
    53  func SetConfigOutput(c *TestCommand, keys map[string]string) {
    54  	pieces := make([]string, 0, len(keys))
    55  
    56  	for _, key := range configKeys {
    57  		if v, ok := keys[key]; ok {
    58  			pieces = append(pieces, key+"="+v)
    59  		}
    60  	}
    61  
    62  	c.Output = strings.Join(pieces, "\n")
    63  
    64  	if len(JoinedGitEnv) > 0 {
    65  		c.Output += "\n" + JoinedGitEnv
    66  	}
    67  }
    68  
    69  type Repository struct {
    70  	T                *testing.T
    71  	Name             string
    72  	Path             string
    73  	Paths            []string
    74  	Commands         []*TestCommand
    75  	expandedTempPath bool
    76  }
    77  
    78  func (r *Repository) AddPath(paths ...string) {
    79  	r.Paths = append(r.Paths, filepath.Join(paths...))
    80  }
    81  
    82  func (r *Repository) Command(args ...string) *TestCommand {
    83  	cmd := &TestCommand{
    84  		T:               r.T,
    85  		Args:            args,
    86  		BeforeCallbacks: make([]func(), 0),
    87  		AfterCallbacks:  make([]func(), 0),
    88  		Env:             make([]string, 0),
    89  	}
    90  	r.Commands = append(r.Commands, cmd)
    91  	return cmd
    92  }
    93  
    94  func (r *Repository) ReadFile(paths ...string) string {
    95  	args := make([]string, 1, len(paths)+1)
    96  	args[0] = r.Path
    97  	args = append(args, paths...)
    98  	by, err := ioutil.ReadFile(filepath.Join(args...))
    99  	assert.Equal(r.T, nil, err)
   100  	return string(by)
   101  }
   102  
   103  func (r *Repository) WriteFile(filename, output string) {
   104  	r.e(ioutil.WriteFile(filename, []byte(output), 0755))
   105  }
   106  
   107  func (r *Repository) MediaCmd(args ...string) string {
   108  	return r.cmd(Bin, args...)
   109  }
   110  
   111  func (r *Repository) GitCmd(args ...string) string {
   112  	return r.cmd("git", args...)
   113  }
   114  
   115  func (r *Repository) Test() {
   116  	for _, path := range r.Paths {
   117  		r.test(path)
   118  	}
   119  }
   120  
   121  func (r *Repository) test(path string) {
   122  	fmt.Println("Command tests for\n", path)
   123  	for _, cmd := range r.Commands {
   124  		r.clone()
   125  		cmd.Run(path)
   126  	}
   127  }
   128  
   129  func (r *Repository) clone() {
   130  	clone(r.T, r.Name, r.Path)
   131  }
   132  
   133  func (r *Repository) e(err error) {
   134  	e(r.T, err)
   135  }
   136  
   137  func (r *Repository) cmd(name string, args ...string) string {
   138  	return cmd(r.T, name, args...)
   139  }
   140  
   141  type TestCommand struct {
   142  	T               *testing.T
   143  	Args            []string
   144  	Env             []string
   145  	Input           io.Reader
   146  	Output          string
   147  	BeforeCallbacks []func()
   148  	AfterCallbacks  []func()
   149  }
   150  
   151  func (c *TestCommand) Run(path string) {
   152  	fmt.Println("$ git lfs", strings.Join(c.Args, " "))
   153  
   154  	for _, cb := range c.BeforeCallbacks {
   155  		cb()
   156  	}
   157  
   158  	c.e(os.Chdir(path))
   159  
   160  	cmd := exec.Command(Bin, c.Args...)
   161  	cmd.Stdin = c.Input
   162  	if c.Env != nil && len(c.Env) > 0 {
   163  		cmd.Env = append(os.Environ(), c.Env...)
   164  	}
   165  	outputBytes, err := cmd.CombinedOutput()
   166  	c.e(err)
   167  
   168  	if len(c.Output) > 0 {
   169  		assert.Equal(c.T, c.Output+"\n", string(outputBytes))
   170  	}
   171  
   172  	for _, cb := range c.AfterCallbacks {
   173  		cb()
   174  	}
   175  }
   176  
   177  func (c *TestCommand) Before(f func()) {
   178  	c.BeforeCallbacks = append(c.BeforeCallbacks, f)
   179  }
   180  
   181  func (c *TestCommand) After(f func()) {
   182  	c.AfterCallbacks = append(c.AfterCallbacks, f)
   183  }
   184  
   185  func (c *TestCommand) e(err error) {
   186  	e(c.T, err)
   187  }
   188  
   189  func cmd(t *testing.T, name string, args ...string) string {
   190  	cmd := exec.Command(name, args...)
   191  	o, err := cmd.CombinedOutput()
   192  	if err != nil {
   193  		t.Fatalf(
   194  			"Error running command:\n$ %s\n\n%s",
   195  			strings.Join(cmd.Args, " "),
   196  			string(o),
   197  		)
   198  	}
   199  	return string(o)
   200  }
   201  
   202  func e(t *testing.T, err error) {
   203  	if err != nil {
   204  		t.Fatal(err.Error())
   205  	}
   206  }
   207  
   208  func expand(path string) string {
   209  	p, err := filepath.EvalSymlinks(path)
   210  	if err != nil {
   211  		panic(err)
   212  	}
   213  	return p
   214  }
   215  
   216  func clone(t *testing.T, name, path string) {
   217  	e(t, os.RemoveAll(path))
   218  
   219  	reposPath := filepath.Join(Root, "commands", "repos")
   220  	e(t, os.Chdir(reposPath))
   221  	cmd(t, "git", "clone", name, path)
   222  	e(t, os.Chdir(path))
   223  	cmd(t, "git", "remote", "remove", "origin")
   224  	cmd(t, "git", "remote", "add", "origin", "https://example.com/git/lfs")
   225  }
   226  
   227  func init() {
   228  	wd, err := os.Getwd()
   229  	if err != nil {
   230  		panic(err)
   231  	}
   232  
   233  	Root = filepath.Join(wd, "..")
   234  	Bin = filepath.Join(Root, "bin", "git-lfs")
   235  	TempDir = filepath.Join(os.TempDir(), "git-lfs-tests")
   236  
   237  	env := os.Environ()
   238  	GitEnv = make([]string, 0, len(env))
   239  	for _, e := range env {
   240  		if !strings.Contains(e, "GIT_") {
   241  			continue
   242  		}
   243  		GitEnv = append(GitEnv, e)
   244  	}
   245  	JoinedGitEnv = strings.Join(GitEnv, "\n")
   246  }