github.com/matthewdale/lab@v0.14.0/cmd/root_test.go (about)

     1  package cmd
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"log"
     8  	"math/rand"
     9  	"os"
    10  	"os/exec"
    11  	"path"
    12  	"path/filepath"
    13  	"strconv"
    14  	"strings"
    15  	"testing"
    16  	"time"
    17  
    18  	"github.com/spf13/viper"
    19  	"github.com/stretchr/testify/assert"
    20  	"github.com/stretchr/testify/require"
    21  	"github.com/zaquestion/lab/internal/git"
    22  	lab "github.com/zaquestion/lab/internal/gitlab"
    23  )
    24  
    25  func TestMain(m *testing.M) {
    26  	wd, err := git.WorkingDir()
    27  	if err != nil {
    28  		log.Fatal(err)
    29  	}
    30  	os.Chdir(wd)
    31  	err = exec.Command("go", "test", "-c", "-coverpkg", "./...", "-covermode", "count", "-o", "lab_bin").Run()
    32  	if err != nil {
    33  		log.Fatal(err)
    34  	}
    35  	rand.Seed(time.Now().UnixNano())
    36  
    37  	// Load config for non-testbinary based tests
    38  	os.Chdir(path.Join(wd, "testdata"))
    39  	viper.SetConfigName("lab")
    40  	viper.SetConfigType("hcl")
    41  	viper.AddConfigPath(".")
    42  	err = viper.ReadInConfig()
    43  	if err != nil {
    44  		log.Fatal(err)
    45  	}
    46  	c := viper.AllSettings()["core"]
    47  	config := c.([]map[string]interface{})[0]
    48  	lab.Init(
    49  		config["host"].(string),
    50  		config["user"].(string),
    51  		config["token"].(string))
    52  
    53  	code := m.Run()
    54  	os.Chdir(wd)
    55  	os.Remove("lab_bin")
    56  	testdirs, err := filepath.Glob("testdata-*")
    57  	if err != nil {
    58  		log.Fatal(err)
    59  	}
    60  	for _, dir := range testdirs {
    61  		err := os.RemoveAll(dir)
    62  		if err != nil {
    63  			log.Fatal(err)
    64  		}
    65  	}
    66  
    67  	os.Exit(code)
    68  }
    69  
    70  func copyTestRepo(t *testing.T) string {
    71  	dir := "../testdata-" + strconv.Itoa(int(rand.Uint64()))
    72  	t.Log(dir)
    73  	err := exec.Command("cp", "-r", "../testdata", dir).Run()
    74  	if err != nil {
    75  		t.Fatal(err)
    76  	}
    77  	wd, err := os.Getwd()
    78  	if err != nil {
    79  		t.Fatal(err)
    80  	}
    81  	dir = path.Join(wd, dir)
    82  	return dir
    83  }
    84  
    85  func TestRootCloneNoArg(t *testing.T) {
    86  	cmd := exec.Command("../lab_bin", "clone")
    87  	b, _ := cmd.CombinedOutput()
    88  	require.Contains(t, string(b), "You must specify a repository to clone.")
    89  }
    90  
    91  func TestRootGitCmd(t *testing.T) {
    92  	cmd := exec.Command("../lab_bin", "log", "-n", "1")
    93  	b, _ := cmd.CombinedOutput()
    94  	require.Contains(t, string(b), `commit 09b519cba018b707c98fc56e37df15806d89d866
    95  Author: Zaq? Wiedmann <zaquestion@gmail.com>
    96  Date:   Sun Apr 1 19:40:47 2018 -0700
    97  
    98      (ci) jobs with interleaved sleeps and prints`)
    99  }
   100  
   101  func TestRootNoArg(t *testing.T) {
   102  	cmd := exec.Command("../lab_bin")
   103  	b, _ := cmd.CombinedOutput()
   104  	assert.Contains(t, string(b), "usage: git [--version] [--help] [-C <path>]")
   105  	assert.Contains(t, string(b), `These GitLab commands are provided by lab:
   106  
   107    ci            Work with GitLab CI pipelines and jobs`)
   108  }
   109  
   110  func TestRootVersion(t *testing.T) {
   111  	old := os.Stdout // keep backup of the real stdout
   112  	r, w, _ := os.Pipe()
   113  	os.Stdout = w
   114  
   115  	RootCmd.Flag("version").Value.Set("true")
   116  	RootCmd.Run(RootCmd, nil)
   117  
   118  	outC := make(chan string)
   119  	// copy the output in a separate goroutine so printing can't block indefinitely
   120  	go func() {
   121  		var buf bytes.Buffer
   122  		io.Copy(&buf, r)
   123  		outC <- buf.String()
   124  	}()
   125  
   126  	// back to normal state
   127  	w.Close()
   128  	os.Stdout = old // restoring the real stdout
   129  	out := <-outC
   130  
   131  	assert.Contains(t, out, "git version")
   132  	assert.Contains(t, out, fmt.Sprintf("lab version %s", Version))
   133  }
   134  
   135  func TestGitHelp(t *testing.T) {
   136  	cmd := exec.Command("../lab_bin")
   137  	b, _ := cmd.CombinedOutput()
   138  	expected := string(b)
   139  	expected = expected[:strings.LastIndex(strings.TrimSpace(expected), "\n")]
   140  
   141  	tests := []struct {
   142  		desc string
   143  		Cmds []string
   144  	}{
   145  		{
   146  			desc: "help arg",
   147  			Cmds: []string{"help"},
   148  		},
   149  		{
   150  			desc: "no arg",
   151  			Cmds: []string{},
   152  		},
   153  	}
   154  
   155  	for _, test := range tests {
   156  		t.Run(test.desc, func(t *testing.T) {
   157  			cmd := exec.Command("../lab_bin")
   158  			if len(test.Cmds) >= 1 {
   159  				cmd = exec.Command("../lab_bin", test.Cmds...)
   160  			}
   161  			b, _ := cmd.CombinedOutput()
   162  			res := string(b)
   163  			res = res[:strings.LastIndex(strings.TrimSpace(res), "\n")]
   164  			t.Log(expected)
   165  			t.Log(res)
   166  			assert.Equal(t, expected, res)
   167  			assert.Contains(t, res, "usage: git [--version] [--help] [-C <path>]")
   168  			assert.Contains(t, res, `These GitLab commands are provided by lab:
   169  
   170    ci            Work with GitLab CI pipelines and jobs`)
   171  		})
   172  	}
   173  }
   174  
   175  func Test_parseArgsStr(t *testing.T) {
   176  	tests := []struct {
   177  		Name           string
   178  		Args           []string
   179  		ExpectedString string
   180  		ExpectedInt    int64
   181  		ExpectedErr    string
   182  	}{
   183  		{
   184  			Name:           "No Args",
   185  			Args:           nil,
   186  			ExpectedString: "",
   187  			ExpectedInt:    0,
   188  			ExpectedErr:    "",
   189  		},
   190  		{
   191  			Name:           "1 arg remote",
   192  			Args:           []string{"origin"},
   193  			ExpectedString: "origin",
   194  			ExpectedInt:    0,
   195  			ExpectedErr:    "",
   196  		},
   197  		{
   198  			Name:           "1 arg non remote",
   199  			Args:           []string{"foo"},
   200  			ExpectedString: "foo",
   201  			ExpectedInt:    0,
   202  			ExpectedErr:    "",
   203  		},
   204  		{
   205  			Name:           "1 arg page",
   206  			Args:           []string{"100"},
   207  			ExpectedString: "",
   208  			ExpectedInt:    100,
   209  			ExpectedErr:    "",
   210  		},
   211  		{
   212  			Name:           "1 arg invalid page",
   213  			Args:           []string{"asdf100"},
   214  			ExpectedString: "asdf100",
   215  			ExpectedInt:    0,
   216  			ExpectedErr:    "",
   217  		},
   218  		{
   219  			Name:           "2 arg str page",
   220  			Args:           []string{"origin", "100"},
   221  			ExpectedString: "origin",
   222  			ExpectedInt:    100,
   223  			ExpectedErr:    "",
   224  		},
   225  		{
   226  			Name:           "2 arg valid str valid page",
   227  			Args:           []string{"foo", "100"},
   228  			ExpectedString: "foo",
   229  			ExpectedInt:    100,
   230  			ExpectedErr:    "",
   231  		},
   232  		{
   233  			Name:           "2 arg valid str invalid page",
   234  			Args:           []string{"foo", "asdf100"},
   235  			ExpectedString: "foo",
   236  			ExpectedInt:    0,
   237  			ExpectedErr:    "strconv.ParseInt: parsing \"asdf100\": invalid syntax",
   238  		},
   239  	}
   240  	for _, test := range tests {
   241  		t.Run(test.Name, func(t *testing.T) {
   242  			test := test
   243  			t.Parallel()
   244  			s, i, err := parseArgsStr(test.Args)
   245  			if err != nil {
   246  				assert.EqualError(t, err, test.ExpectedErr)
   247  			}
   248  			assert.Equal(t, test.ExpectedString, s)
   249  			assert.Equal(t, test.ExpectedInt, i)
   250  		})
   251  	}
   252  }
   253  
   254  func Test_parseArgs(t *testing.T) {
   255  	tests := []struct {
   256  		Name           string
   257  		Args           []string
   258  		ExpectedString string
   259  		ExpectedInt    int64
   260  		ExpectedErr    string
   261  	}{
   262  		{
   263  			Name:           "No Args",
   264  			Args:           nil,
   265  			ExpectedString: "zaquestion/test",
   266  			ExpectedInt:    0,
   267  			ExpectedErr:    "",
   268  		},
   269  		{
   270  			Name:           "1 arg remote",
   271  			Args:           []string{"lab-testing"},
   272  			ExpectedString: "lab-testing/test",
   273  			ExpectedInt:    0,
   274  			ExpectedErr:    "",
   275  		},
   276  		{
   277  			Name:           "1 arg non remote",
   278  			Args:           []string{"foo"},
   279  			ExpectedString: "",
   280  			ExpectedInt:    0,
   281  			ExpectedErr:    "foo is not a valid remote or number",
   282  		},
   283  		{
   284  			Name:           "1 arg page",
   285  			Args:           []string{"100"},
   286  			ExpectedString: "zaquestion/test",
   287  			ExpectedInt:    100,
   288  			ExpectedErr:    "",
   289  		},
   290  		{
   291  			Name:           "1 arg invalid page",
   292  			Args:           []string{"asdf100"},
   293  			ExpectedString: "",
   294  			ExpectedInt:    0,
   295  			ExpectedErr:    "asdf100 is not a valid remote or number",
   296  		},
   297  		{
   298  			Name:           "2 arg remote page",
   299  			Args:           []string{"origin", "100"},
   300  			ExpectedString: "zaquestion/test",
   301  			ExpectedInt:    100,
   302  			ExpectedErr:    "",
   303  		},
   304  		{
   305  			Name:           "2 arg invalid remote valid page",
   306  			Args:           []string{"foo", "100"},
   307  			ExpectedString: "",
   308  			ExpectedInt:    0,
   309  			ExpectedErr:    "foo is not a valid remote",
   310  		},
   311  		{
   312  			Name:           "2 arg invalid remote invalid page",
   313  			Args:           []string{"foo", "asdf100"},
   314  			ExpectedString: "",
   315  			ExpectedInt:    0,
   316  			ExpectedErr:    "strconv.ParseInt: parsing \"asdf100\": invalid syntax",
   317  		},
   318  	}
   319  	for _, test := range tests {
   320  		t.Run(test.Name, func(t *testing.T) {
   321  			test := test
   322  			t.Parallel()
   323  			s, i, err := parseArgs(test.Args)
   324  			if err != nil {
   325  				assert.EqualError(t, err, test.ExpectedErr)
   326  			}
   327  			assert.Equal(t, test.ExpectedString, s)
   328  			assert.Equal(t, test.ExpectedInt, i)
   329  		})
   330  	}
   331  }