github.com/meatballhat/deppy@v0.0.0-20151116212532-116c2a9aa48d/save_test.go (about)

     1  package main
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"io/ioutil"
     7  	"os"
     8  	"os/exec"
     9  	"path/filepath"
    10  	"reflect"
    11  	"strings"
    12  	"testing"
    13  	"text/template"
    14  )
    15  
    16  // node represents a file tree or a VCS repo
    17  type node struct {
    18  	path    string      // file name or commit type
    19  	body    interface{} // file contents or commit tag
    20  	entries []*node     // nil if the entry is a file
    21  }
    22  
    23  var (
    24  	pkgtpl = template.Must(template.New("package").Parse(`package {{.Name}}
    25  
    26  import (
    27  {{range .Imports}}	{{printf "%q" .}}
    28  {{end}})
    29  `))
    30  )
    31  
    32  func pkg(name string, pkg ...string) string {
    33  	v := struct {
    34  		Name    string
    35  		Imports []string
    36  	}{name, pkg}
    37  	var buf bytes.Buffer
    38  	err := pkgtpl.Execute(&buf, v)
    39  	if err != nil {
    40  		panic(err)
    41  	}
    42  	return buf.String()
    43  }
    44  
    45  func decl(name string) string {
    46  	return "var " + name + " int\n"
    47  }
    48  
    49  func deppy(importpath string, keyval ...string) *Deps {
    50  	g := &Deps{
    51  		ImportPath: importpath,
    52  	}
    53  	for i := 0; i < len(keyval); i += 2 {
    54  		g.Deps = append(g.Deps, Dependency{
    55  			ImportPath: keyval[i],
    56  			Comment:    keyval[i+1],
    57  		})
    58  	}
    59  	return g
    60  }
    61  
    62  func TestSave(t *testing.T) {
    63  	var cases = []struct {
    64  		cwd      string
    65  		args     []string
    66  		flagR    bool
    67  		start    []*node
    68  		altstart []*node
    69  		want     []*node
    70  		wdep     Deps
    71  		werr     bool
    72  	}{
    73  		{
    74  			// dependency on parent directory in same repo
    75  			// see bug https://github.com/tools/godep/issues/70
    76  			cwd:  "P",
    77  			args: []string{"./..."},
    78  			start: []*node{
    79  				{
    80  					"P",
    81  					"",
    82  					[]*node{
    83  						{"main.go", pkg("P"), nil},
    84  						{"Q/main.go", pkg("Q", "P"), nil},
    85  						{"+git", "C1", nil},
    86  					},
    87  				},
    88  			},
    89  			want: []*node{
    90  				{"P/main.go", pkg("P"), nil},
    91  				{"P/Q/main.go", pkg("Q", "P"), nil},
    92  			},
    93  			wdep: Deps{
    94  				ImportPath: "P",
    95  				Deps:       []Dependency{},
    96  			},
    97  		},
    98  	}
    99  
   100  	wd, err := os.Getwd()
   101  	if err != nil {
   102  		t.Fatal(err)
   103  	}
   104  	const scratch = "goderptest"
   105  	defer os.RemoveAll(scratch)
   106  	for _, test := range cases {
   107  		err = os.RemoveAll(scratch)
   108  		if err != nil {
   109  			t.Fatal(err)
   110  		}
   111  		altsrc := filepath.Join(scratch, "r2", "src")
   112  		if test.altstart != nil {
   113  			makeTree(t, &node{altsrc, "", test.altstart}, "")
   114  		}
   115  		src := filepath.Join(scratch, "r1", "src")
   116  		makeTree(t, &node{src, "", test.start}, altsrc)
   117  
   118  		dir := filepath.Join(wd, src, test.cwd)
   119  		err = os.Chdir(dir)
   120  		if err != nil {
   121  			panic(err)
   122  		}
   123  		root1 := filepath.Join(wd, scratch, "r1")
   124  		root2 := filepath.Join(wd, scratch, "r2")
   125  		err = os.Setenv("GOPATH", root1+string(os.PathListSeparator)+root2)
   126  		if err != nil {
   127  			panic(err)
   128  		}
   129  		err = save(test.args)
   130  		if g := err != nil; g != test.werr {
   131  			if err != nil {
   132  				t.Log(err)
   133  			}
   134  			t.Errorf("save err = %v want %v", g, test.werr)
   135  		}
   136  		err = os.Chdir(wd)
   137  		if err != nil {
   138  			panic(err)
   139  		}
   140  
   141  		checkTree(t, &node{src, "", test.want})
   142  
   143  		f, err := os.Open(filepath.Join(dir, "Deps"))
   144  		if err != nil {
   145  			t.Error(err)
   146  		}
   147  		g := new(Deps)
   148  		err = json.NewDecoder(f).Decode(g)
   149  		if err != nil {
   150  			t.Error(err)
   151  		}
   152  		f.Close()
   153  
   154  		if g.ImportPath != test.wdep.ImportPath {
   155  			t.Errorf("ImportPath = %s want %s", g.ImportPath, test.wdep.ImportPath)
   156  		}
   157  		for i := range g.Deps {
   158  			g.Deps[i].Rev = ""
   159  		}
   160  		if !reflect.DeepEqual(g.Deps, test.wdep.Deps) {
   161  			t.Errorf("Deps = %v want %v", g.Deps, test.wdep.Deps)
   162  		}
   163  	}
   164  }
   165  
   166  func makeTree(t *testing.T, tree *node, altpath string) (gopath string) {
   167  	walkTree(tree, tree.path, func(path string, n *node) {
   168  		g, isDeps := n.body.(*Deps)
   169  		body, _ := n.body.(string)
   170  		switch {
   171  		case isDeps:
   172  			for i, dep := range g.Deps {
   173  				rel := filepath.FromSlash(dep.ImportPath)
   174  				dir := filepath.Join(tree.path, rel)
   175  				if _, err := os.Stat(dir); os.IsNotExist(err) {
   176  					dir = filepath.Join(altpath, rel)
   177  				}
   178  				tag := dep.Comment
   179  				rev := strings.TrimSpace(run(t, dir, "git", "rev-parse", tag))
   180  				g.Deps[i].Rev = rev
   181  			}
   182  			os.MkdirAll(filepath.Dir(path), 0770)
   183  			f, err := os.Create(path)
   184  			if err != nil {
   185  				t.Errorf("makeTree: %v", err)
   186  				return
   187  			}
   188  			defer f.Close()
   189  			err = json.NewEncoder(f).Encode(g)
   190  			if err != nil {
   191  				t.Errorf("makeTree: %v", err)
   192  			}
   193  		case n.path == "+git":
   194  			dir := filepath.Dir(path)
   195  			run(t, dir, "git", "init") // repo might already exist, but ok
   196  			run(t, dir, "git", "add", ".")
   197  			run(t, dir, "git", "commit", "-m", "goderp")
   198  			if body != "" {
   199  				run(t, dir, "git", "tag", body)
   200  			}
   201  		case n.entries == nil && strings.HasPrefix(body, "symlink:"):
   202  			target := strings.TrimPrefix(body, "symlink:")
   203  			os.Symlink(target, path)
   204  		case n.entries == nil && body == "(absent)":
   205  			panic("is this gonna be forever")
   206  		case n.entries == nil:
   207  			os.MkdirAll(filepath.Dir(path), 0770)
   208  			err := ioutil.WriteFile(path, []byte(body), 0660)
   209  			if err != nil {
   210  				t.Errorf("makeTree: %v", err)
   211  			}
   212  		default:
   213  			os.MkdirAll(path, 0770)
   214  		}
   215  	})
   216  	return gopath
   217  }
   218  
   219  func checkTree(t *testing.T, want *node) {
   220  	walkTree(want, want.path, func(path string, n *node) {
   221  		body := n.body.(string)
   222  		switch {
   223  		case n.path == "+git":
   224  			panic("is this real life")
   225  		case n.entries == nil && strings.HasPrefix(body, "symlink:"):
   226  			panic("why is this happening to me")
   227  		case n.entries == nil && body == "(absent)":
   228  			body, err := ioutil.ReadFile(path)
   229  			if !os.IsNotExist(err) {
   230  				t.Errorf("checkTree: %s = %s want absent", path, string(body))
   231  				return
   232  			}
   233  		case n.entries == nil:
   234  			gbody, err := ioutil.ReadFile(path)
   235  			if err != nil {
   236  				t.Errorf("checkTree: %v", err)
   237  				return
   238  			}
   239  			if got := string(gbody); got != body {
   240  				t.Errorf("%s = %s want %s", path, got, body)
   241  			}
   242  		default:
   243  			os.MkdirAll(path, 0770)
   244  		}
   245  	})
   246  }
   247  
   248  func walkTree(n *node, path string, f func(path string, n *node)) {
   249  	f(path, n)
   250  	for _, e := range n.entries {
   251  		walkTree(e, filepath.Join(path, filepath.FromSlash(e.path)), f)
   252  	}
   253  }
   254  
   255  func run(t *testing.T, dir, name string, args ...string) string {
   256  	cmd := exec.Command(name, args...)
   257  	cmd.Dir = dir
   258  	cmd.Stderr = os.Stderr
   259  	out, err := cmd.Output()
   260  	if err != nil {
   261  		panic(name + " " + strings.Join(args, " ") + ": " + err.Error())
   262  	}
   263  	return string(out)
   264  }