github.com/Benchkram/bob@v0.0.0-20220321080157-7c8f3876e225/bobgit/commit_test.go (about)

     1  package bobgit
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  	"testing"
    10  
    11  	"github.com/Benchkram/bob/pkg/cmdutil"
    12  	"github.com/google/go-cmp/cmp"
    13  	"github.com/stretchr/testify/assert"
    14  )
    15  
    16  var commitTestDataPath = "testdata/commit"
    17  
    18  func TestCommit(t *testing.T) {
    19  
    20  	type input struct {
    21  		// environment holds a function creating
    22  		// the testing folder structure.
    23  		environment func(dir string)
    24  	}
    25  
    26  	type test struct {
    27  		// name of the test and also used
    28  		// for storing expected output
    29  		name  string
    30  		input input
    31  		// execdir determines the dir in which `bob git status` is executed
    32  		// relative to the repo root.
    33  		// reporoot is used when empty.
    34  		execdir string
    35  		// send commit message to test
    36  		message string
    37  		// output string from Commit function
    38  		output string
    39  
    40  		expectedErr error
    41  	}
    42  
    43  	tests := []test{
    44  		// nothing should be commited, prints a additional user message with untracked repository list
    45  		{
    46  			"commit_untracked",
    47  			input{
    48  				func(dir string) {
    49  					err := cmdutil.RunGit(dir, "init")
    50  					assert.Nil(t, err)
    51  
    52  					assert.Nil(t, os.MkdirAll(dir, 0775))
    53  					assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664))
    54  					assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664))
    55  					assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664))
    56  
    57  					repo := filepath.Join(dir, "repo")
    58  					assert.Nil(t, os.MkdirAll(repo, 0775))
    59  					assert.Nil(t, cmdutil.RunGit(repo, "init"))
    60  					assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("file"), 0664))
    61  				},
    62  			},
    63  			"",
    64  			"test commmits with untracked files",
    65  			UntrackedRepoMessage([]string{".", "repo"}),
    66  			nil,
    67  		},
    68  		// all files should be commited except files in `repo` sub-directory
    69  		{
    70  			"commit_tracked_bobroot",
    71  			input{
    72  				func(dir string) {
    73  					err := cmdutil.RunGit(dir, "init")
    74  					assert.Nil(t, err)
    75  
    76  					assert.Nil(t, os.MkdirAll(dir, 0775))
    77  					assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664))
    78  					assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664))
    79  					assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664))
    80  
    81  					repo := filepath.Join(dir, "repo")
    82  					assert.Nil(t, os.MkdirAll(repo, 0775))
    83  					assert.Nil(t, cmdutil.RunGit(repo, "init"))
    84  					assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("file"), 0664))
    85  
    86  					err = cmdutil.RunGit(dir, "add", ".")
    87  					assert.Nil(t, err)
    88  				},
    89  			},
    90  			"",
    91  			"test commmits with tracked files in bobroot",
    92  			"",
    93  			nil,
    94  		},
    95  		// all files should be commited even files in `repo` sub-directory
    96  		{
    97  			"commit_tracked_all",
    98  			input{
    99  				func(dir string) {
   100  					err := cmdutil.RunGit(dir, "init")
   101  					assert.Nil(t, err)
   102  
   103  					assert.Nil(t, os.MkdirAll(dir, 0775))
   104  					assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664))
   105  					assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664))
   106  					assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664))
   107  
   108  					repo := filepath.Join(dir, "repo")
   109  					assert.Nil(t, os.MkdirAll(repo, 0775))
   110  					assert.Nil(t, cmdutil.RunGit(repo, "init"))
   111  					assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("file"), 0664))
   112  					err = cmdutil.RunGit(repo, "add", ".")
   113  					assert.Nil(t, err)
   114  
   115  					err = cmdutil.RunGit(dir, "add", ".")
   116  					assert.Nil(t, err)
   117  				},
   118  			},
   119  			"",
   120  			"test commmits with tracked files",
   121  			"",
   122  			nil,
   123  		},
   124  		// only files in `repo` sub-directory should be commited
   125  		// files in bobroot should be unmodified
   126  		{
   127  			"commit_repo_subdirectory_files",
   128  			input{
   129  				func(dir string) {
   130  					err := cmdutil.RunGit(dir, "init")
   131  					assert.Nil(t, err)
   132  
   133  					assert.Nil(t, os.MkdirAll(dir, 0775))
   134  					assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664))
   135  					assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664))
   136  					assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664))
   137  
   138  					repo := filepath.Join(dir, "repo")
   139  					assert.Nil(t, os.MkdirAll(repo, 0775))
   140  					assert.Nil(t, cmdutil.RunGit(repo, "init"))
   141  					assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("file"), 0664))
   142  					err = cmdutil.RunGit(repo, "add", ".")
   143  					assert.Nil(t, err)
   144  
   145  					err = cmdutil.RunGit(dir, "add", ".")
   146  					assert.Nil(t, err)
   147  					err = cmdutil.RunGit(dir, "commit", "-m", "bobroot changes commited")
   148  					assert.Nil(t, err)
   149  				},
   150  			},
   151  			"",
   152  			"test commmits with tracked files in repo subdir",
   153  			"",
   154  			nil,
   155  		},
   156  		// execute git commit from repo sub repository
   157  		// should work as same as executing from bobroot
   158  		{
   159  			"exec_commit_from_subdrepository",
   160  			input{
   161  				func(dir string) {
   162  					err := cmdutil.RunGit(dir, "init")
   163  					assert.Nil(t, err)
   164  
   165  					assert.Nil(t, os.MkdirAll(dir, 0775))
   166  					assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664))
   167  					assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664))
   168  					assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664))
   169  
   170  					repo := filepath.Join(dir, "repo")
   171  					assert.Nil(t, os.MkdirAll(repo, 0775))
   172  					assert.Nil(t, cmdutil.RunGit(repo, "init"))
   173  					assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("file"), 0664))
   174  					err = cmdutil.RunGit(repo, "add", ".")
   175  					assert.Nil(t, err)
   176  
   177  					err = cmdutil.RunGit(dir, "add", ".")
   178  					assert.Nil(t, err)
   179  				},
   180  			},
   181  			"repo",
   182  			"test commmits from sub-repository",
   183  			"",
   184  			nil,
   185  		},
   186  		// exec commit from subdirectory
   187  		// should work as same as executing from bobroot
   188  		{
   189  			"exec_commit_from_subdirectory",
   190  			input{
   191  				func(dir string) {
   192  					err := cmdutil.RunGit(dir, "init")
   193  					assert.Nil(t, err)
   194  
   195  					assert.Nil(t, os.MkdirAll(dir, 0775))
   196  					assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664))
   197  					assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664))
   198  					assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664))
   199  
   200  					repo := filepath.Join(dir, "subdirectory", "repo")
   201  					assert.Nil(t, os.MkdirAll(repo, 0775))
   202  					assert.Nil(t, cmdutil.RunGit(repo, "init"))
   203  					assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("file"), 0664))
   204  					err = cmdutil.RunGit(repo, "add", ".")
   205  					assert.Nil(t, err)
   206  
   207  					err = cmdutil.RunGit(dir, "add", ".")
   208  					assert.Nil(t, err)
   209  				},
   210  			},
   211  			"subdirectory",
   212  			"test commmits from subdirectory",
   213  			"",
   214  			nil,
   215  		},
   216  		// exec commit without a message
   217  		// execution should return a ErrEmptyCommitMessage error
   218  		{
   219  			"exec_commit_without_message",
   220  			input{
   221  				func(dir string) {
   222  					err := cmdutil.RunGit(dir, "init")
   223  					assert.Nil(t, err)
   224  
   225  					assert.Nil(t, os.MkdirAll(dir, 0775))
   226  					assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664))
   227  					assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664))
   228  					assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664))
   229  				},
   230  			},
   231  			"",
   232  			"",
   233  			"",
   234  			ErrEmptyCommitMessage,
   235  		},
   236  		// exec commit without a nothing to update
   237  		// execution should return a User message about nothing to update
   238  		{
   239  			"exec_commit_after_commiting_updates",
   240  			input{
   241  				func(dir string) {
   242  					err := cmdutil.RunGit(dir, "init")
   243  					assert.Nil(t, err)
   244  
   245  					assert.Nil(t, os.MkdirAll(dir, 0775))
   246  					assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664))
   247  					assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664))
   248  					assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664))
   249  
   250  					repo := filepath.Join(dir, "repo")
   251  					assert.Nil(t, os.MkdirAll(repo, 0775))
   252  					assert.Nil(t, cmdutil.RunGit(repo, "init"))
   253  					assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("file"), 0664))
   254  
   255  					err = cmdutil.RunGit(repo, "add", ".")
   256  					assert.Nil(t, err)
   257  
   258  					err = cmdutil.RunGit(repo, "commit", "-m", "All changes commited")
   259  					assert.Nil(t, err)
   260  
   261  					err = cmdutil.RunGit(dir, "add", ".")
   262  					assert.Nil(t, err)
   263  
   264  					err = cmdutil.RunGit(dir, "commit", "-m", "All changes commited")
   265  					assert.Nil(t, err)
   266  				},
   267  			},
   268  			"",
   269  			"exec commit after commiting one time",
   270  			CleanWorkingDirMessage,
   271  			nil,
   272  		},
   273  
   274  		// exec commit without a tracking on subrepository
   275  		// execution should return a User message about untracked repository name
   276  		{
   277  			"exec_commit_without_tracking_one_repo",
   278  			input{
   279  				func(dir string) {
   280  					err := cmdutil.RunGit(dir, "init")
   281  					assert.Nil(t, err)
   282  
   283  					assert.Nil(t, os.MkdirAll(dir, 0775))
   284  					assert.Nil(t, os.WriteFile(filepath.Join(dir, ".bob.workspace"), []byte(""), 0664))
   285  					assert.Nil(t, os.WriteFile(filepath.Join(dir, "file"), []byte("file"), 0664))
   286  					assert.Nil(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("repo/"), 0664))
   287  
   288  					repo := filepath.Join(dir, "repo")
   289  					assert.Nil(t, os.MkdirAll(repo, 0775))
   290  					assert.Nil(t, cmdutil.RunGit(repo, "init"))
   291  					assert.Nil(t, os.WriteFile(filepath.Join(repo, "file"), []byte("file"), 0664))
   292  
   293  					err = cmdutil.RunGit(dir, "add", ".")
   294  					assert.Nil(t, err)
   295  
   296  					err = cmdutil.RunGit(dir, "commit", "-m", "All changes commited")
   297  					assert.Nil(t, err)
   298  				},
   299  			},
   300  			"",
   301  			"exec commit after commiting one time",
   302  			UntrackedRepoMessage([]string{"repo"}),
   303  			nil,
   304  		},
   305  	}
   306  
   307  	for _, test := range tests {
   308  		dir, err := ioutil.TempDir("", test.name+"-*")
   309  		assert.Nil(t, err)
   310  
   311  		// Don't cleanup in testdir mode
   312  		if !createTestDirs {
   313  			defer os.RemoveAll(dir)
   314  		}
   315  
   316  		if debug || createTestDirs {
   317  			println("Using test dir " + dir)
   318  		}
   319  
   320  		test.input.environment(dir)
   321  
   322  		if createTestDirs {
   323  			continue
   324  		}
   325  
   326  		execdir := filepath.Join(dir, test.execdir)
   327  		statusBeforeFile := test.name + "_before"
   328  		statusAfterFile := test.name + "_after"
   329  
   330  		statusBefore, err := getStatus(execdir)
   331  		assert.Nil(t, err)
   332  
   333  		s, err := executeCommit(execdir, test.message)
   334  		if test.expectedErr != nil {
   335  			if errors.Is(err, test.expectedErr) {
   336  				continue
   337  			}
   338  			assert.Fail(t, fmt.Sprintf("expected error [%s] got [%s]", test.expectedErr.Error(), err.Error()))
   339  		}
   340  
   341  		// ignore the error caused by test.message nill
   342  		if err != nil && !errors.Is(err, ErrEmptyCommitMessage) {
   343  			assert.Nil(t, err)
   344  		}
   345  
   346  		assert.Equal(t, s, test.output, test.name)
   347  
   348  		statusAfter, err := getStatus(execdir)
   349  		assert.Nil(t, err)
   350  
   351  		if update {
   352  			// tests expecting a error don't need to compare their before and after putputs
   353  			if test.expectedErr != nil {
   354  				continue
   355  			}
   356  
   357  			err = os.RemoveAll(filepath.Join(commitTestDataPath, statusBeforeFile))
   358  			assert.Nil(t, err)
   359  			err = os.RemoveAll(filepath.Join(commitTestDataPath, statusAfterFile))
   360  			assert.Nil(t, err)
   361  			err = os.MkdirAll(commitTestDataPath, 0775)
   362  			assert.Nil(t, err)
   363  			err = os.WriteFile(filepath.Join(commitTestDataPath, statusBeforeFile), []byte(statusBefore.String()), 0664)
   364  			assert.Nil(t, err)
   365  			err = os.WriteFile(filepath.Join(commitTestDataPath, statusAfterFile), []byte(statusAfter.String()), 0664)
   366  			assert.Nil(t, err)
   367  			continue
   368  		}
   369  
   370  		expectBefore, err := os.ReadFile(filepath.Join(commitTestDataPath, statusBeforeFile))
   371  		assert.Nil(t, err, test.name)
   372  
   373  		diff := cmp.Diff(statusBefore.String(), string(expectBefore))
   374  		assert.Equal(t, "", diff, statusBeforeFile)
   375  
   376  		expectAfter, err := os.ReadFile(filepath.Join(commitTestDataPath, statusAfterFile))
   377  		assert.Nil(t, err, test.name)
   378  
   379  		diff = cmp.Diff(statusAfter.String(), string(expectAfter))
   380  		assert.Equal(t, "", diff, statusAfterFile)
   381  	}
   382  
   383  	if createTestDirs || update {
   384  		t.FailNow()
   385  	}
   386  }
   387  
   388  // executeCommit changes the current working dir before
   389  // executing commit command.
   390  func executeCommit(dir string, message string) (_ string, err error) {
   391  	wd, err := os.Getwd()
   392  	if err != nil {
   393  		return "", err
   394  	}
   395  
   396  	err = os.Chdir(dir)
   397  	if err != nil {
   398  		return "", err
   399  	}
   400  	defer func() { _ = os.Chdir(wd) }()
   401  
   402  	return Commit(message)
   403  }