github.com/developest/gtm-enhanced@v1.0.4-0.20220111132249-cc80a3372c3f/scm/git_test.go (about)

     1  // Copyright 2016 Michael Schenk. All rights reserved.
     2  // Use of this source code is governed by a MIT-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package scm
     6  
     7  import (
     8  	"io/ioutil"
     9  	"os"
    10  	"path"
    11  	"path/filepath"
    12  	"regexp"
    13  	"strings"
    14  	"testing"
    15  
    16  	"github.com/DEVELOPEST/gtm-core/util"
    17  )
    18  
    19  func TestWorkdir(t *testing.T) {
    20  	repo := util.NewTestRepo(t, false)
    21  	defer repo.Remove()
    22  
    23  	repo.AddSubmodule("http://example.org/submodule", "submodule")
    24  
    25  	gotPath, err := Workdir(repo.Path())
    26  	if err != nil {
    27  		t.Errorf("Workdir error, %s", err)
    28  	}
    29  	if repo.Workdir() != gotPath {
    30  		t.Errorf("Workdir want %s, got %s", repo.Workdir(), gotPath)
    31  	}
    32  
    33  	sdir := filepath.Join(repo.Workdir(), "submodule")
    34  	gotPath, err = Workdir(sdir)
    35  	if err != nil {
    36  		t.Errorf("Workdir want error nil got %s", err)
    37  	}
    38  	if sdir != gotPath {
    39  		t.Errorf("Workdir want %s for submodule, got %s", sdir, gotPath)
    40  	}
    41  }
    42  
    43  func TestGitRepoPath(t *testing.T) {
    44  	repo := util.NewTestRepo(t, false)
    45  	defer repo.Remove()
    46  
    47  	repo.AddSubmodule("http://example.org/submodule", "submodule")
    48  
    49  	gotPath, err := GitRepoPath(repo.Path())
    50  	if err != nil {
    51  		t.Errorf("GitRepoPath error, %s", err)
    52  	}
    53  	if repo.Path() != gotPath {
    54  		t.Errorf("GitRepoPath want %s, got %s", repo.Path(), gotPath)
    55  	}
    56  
    57  	saveDir, err := os.Getwd()
    58  	util.CheckFatal(t, err)
    59  	_ = os.Chdir(saveDir)
    60  
    61  	_ = os.Chdir(repo.Path())
    62  	gotPath, err = GitRepoPath()
    63  	if err != nil {
    64  		t.Errorf("GitRepoPath error, %s", err)
    65  	}
    66  	if repo.Path() != gotPath {
    67  		t.Errorf("GitRepoPath want %s, got %s", repo.Path(), gotPath)
    68  	}
    69  
    70  	subGitdir := filepath.Join(repo.Workdir(), ".git", "modules", "submodule")
    71  	gotPath, err = GitRepoPath(filepath.Join(repo.Workdir(), "submodule"))
    72  	if err != nil {
    73  		t.Errorf("GitRepoPath want error nil got %s", err)
    74  	}
    75  	if subGitdir != gotPath {
    76  		t.Errorf("GitRepoPath want %s for submodule, got %s", subGitdir, gotPath)
    77  	}
    78  }
    79  
    80  func TestCommitIDs(t *testing.T) {
    81  	repo := util.NewTestRepo(t, false)
    82  	defer repo.Remove()
    83  	repo.Seed()
    84  
    85  	workdir := repo.Workdir()
    86  
    87  	commits, err := CommitIDs(CommitLimiter{Max: 2}, workdir)
    88  	if err != nil {
    89  		t.Errorf("CommitIDs error, %s", err)
    90  	}
    91  	if len(commits) != 1 {
    92  		t.Errorf("CommitIDs want 1 commit, got %d", len(commits))
    93  	}
    94  
    95  	saveDir, err := os.Getwd()
    96  	util.CheckFatal(t, err)
    97  	defer os.Chdir(saveDir)
    98  
    99  	err = os.Chdir(workdir)
   100  	util.CheckFatal(t, err)
   101  
   102  	commits, err = CommitIDs(CommitLimiter{Max: 2})
   103  	if err != nil {
   104  		t.Errorf("CommitIDs error, %s", err)
   105  	}
   106  	if len(commits) != 1 {
   107  		t.Errorf("CommitIDs want 1 commit, got %d", len(commits))
   108  	}
   109  }
   110  
   111  func TestHeadCommit(t *testing.T) {
   112  	repo := util.NewTestRepo(t, false)
   113  	defer repo.Remove()
   114  	repo.Seed()
   115  
   116  	workdir := repo.Workdir()
   117  
   118  	commit, err := HeadCommit(workdir)
   119  	if err != nil {
   120  		t.Errorf("HeadCommit error, %s", err)
   121  	}
   122  	email := "random@hacker.com"
   123  	if commit.Email != email {
   124  		t.Errorf("HeadCommit want email \"%s\", got \"%s\"", email, commit.Email)
   125  	}
   126  
   127  	saveDir, err := os.Getwd()
   128  	util.CheckFatal(t, err)
   129  	defer os.Chdir(saveDir)
   130  
   131  	err = os.Chdir(workdir)
   132  	util.CheckFatal(t, err)
   133  
   134  	commit, err = HeadCommit()
   135  	if err != nil {
   136  		t.Errorf("HeadCommit error, %s", err)
   137  	}
   138  	if commit.Email != email {
   139  		t.Errorf("HeadCommit want message \"%s\", got \"%s\"", email, commit.Email)
   140  	}
   141  }
   142  
   143  func TestNote(t *testing.T) {
   144  	repo := util.NewTestRepo(t, false)
   145  	defer repo.Remove()
   146  	repo.Seed()
   147  
   148  	workdir := repo.Workdir()
   149  
   150  	noteTxt := "This is a note"
   151  	err := CreateNote(noteTxt, "gtm-data", workdir)
   152  	if err != nil {
   153  		t.Errorf("CreateNote error, %s", err)
   154  	}
   155  
   156  	commit, err := HeadCommit(workdir)
   157  	if err != nil {
   158  		t.Errorf("HeadCommit error, %s", err)
   159  	}
   160  
   161  	note, err := ReadNote(commit.ID, "gtm-data", true, workdir)
   162  	if err != nil {
   163  		t.Errorf("ReadNote error, %s", err)
   164  	}
   165  
   166  	if note.Note != noteTxt {
   167  		t.Errorf("ReadNote want message \"%s\", got \"%s\"", noteTxt, note.Note)
   168  	}
   169  
   170  	saveDir, err := os.Getwd()
   171  	util.CheckFatal(t, err)
   172  	defer os.Chdir(saveDir)
   173  
   174  	err = os.Chdir(workdir)
   175  	util.CheckFatal(t, err)
   176  
   177  	err = CreateNote(noteTxt, "gtm-data")
   178  	// Expect error, note should already exist
   179  	if err == nil {
   180  		t.Errorf("CreateNote expected error but got nil")
   181  	}
   182  
   183  	commit, err = HeadCommit()
   184  	if err != nil {
   185  		t.Errorf("HeadCommit error, %s", err)
   186  	}
   187  
   188  	note, err = ReadNote(commit.ID, "gtm-data", true)
   189  	if err != nil {
   190  		t.Errorf("ReadNote error, %s", err)
   191  	}
   192  
   193  	if note.Note != noteTxt {
   194  		t.Errorf("ReadNote want message \"%s\", got \"%s\"", noteTxt, note.Note)
   195  	}
   196  
   197  }
   198  
   199  func TestStatus(t *testing.T) {
   200  	repo := util.NewTestRepo(t, false)
   201  	defer repo.Remove()
   202  	repo.Seed()
   203  
   204  	repo.SaveFile("README", "", "Updated readme file")
   205  	repo.Stage("README")
   206  
   207  	workdir := repo.Workdir()
   208  
   209  	status, err := NewStatus(workdir)
   210  	if err != nil {
   211  		t.Errorf("NewStatus error, %s", err)
   212  	}
   213  	if status.IsModified("README", false) {
   214  		t.Error("status.IsModified want \"false\" got \"true\"")
   215  	}
   216  	if !status.IsModified("README", true) {
   217  		t.Error("status.IsModified want \"true\" got \"false\"")
   218  	}
   219  	if !status.IsTracked("README") {
   220  		t.Error("status.IsTracked want \"true\" got \"false\"")
   221  	}
   222  	if !status.HasStaged() {
   223  		t.Error("status.HasStaged() want \"true\" got \"false\"")
   224  	}
   225  	if len(status.Files) != 1 {
   226  		t.Errorf("len(status.Files) want \"1\" got \"%d\"", len(status.Files))
   227  	}
   228  }
   229  
   230  func TestIgnoreSet_GitignoreDoesNotExists(t *testing.T) {
   231  	repo := util.NewTestRepo(t, false)
   232  	defer repo.Remove()
   233  
   234  	workdir := repo.Workdir()
   235  	gitignorePath := filepath.Join(workdir, ".gitignore")
   236  
   237  	err := IgnoreSet("/.gtm/", workdir)
   238  	if err != nil {
   239  		t.Errorf("IgnoreSet error: %s", err)
   240  	}
   241  
   242  	data, err := ioutil.ReadFile(gitignorePath)
   243  	if err != nil {
   244  		t.Errorf("read .gitignore error: %s", err)
   245  	}
   246  
   247  	if string(data) != "/.gtm/\n" {
   248  		t.Errorf(
   249  			".gitignore want contents \"/.gtm/\n\", got \"%s\"",
   250  			string(data),
   251  		)
   252  	}
   253  }
   254  
   255  func TestIgnoreSet_GitignoreIsEmpty(t *testing.T) {
   256  	repo := util.NewTestRepo(t, false)
   257  	defer repo.Remove()
   258  
   259  	workdir := repo.Workdir()
   260  	gitignorePath := filepath.Join(workdir, ".gitignore")
   261  
   262  	_, err := os.Create(gitignorePath)
   263  	if err != nil {
   264  		t.Errorf("can't create .gitignore: %s", err)
   265  	}
   266  
   267  	err = IgnoreSet("/.gtm/", workdir)
   268  	if err != nil {
   269  		t.Errorf("IgnoreSet error: %s", err)
   270  	}
   271  
   272  	data, err := ioutil.ReadFile(gitignorePath)
   273  	if err != nil {
   274  		t.Errorf("read .gitignore error: %s", err)
   275  	}
   276  
   277  	if string(data) != "/.gtm/\n" {
   278  		t.Errorf(
   279  			".gitignore want contents \"/.gtm/\n\", got \"%s\"",
   280  			string(data),
   281  		)
   282  	}
   283  }
   284  
   285  func TestIgnoreSet_GitignoreContainsSomeData(t *testing.T) {
   286  	repo := util.NewTestRepo(t, false)
   287  	defer repo.Remove()
   288  
   289  	workdir := repo.Workdir()
   290  	gitignorePath := filepath.Join(workdir, ".gitignore")
   291  
   292  	err := ioutil.WriteFile(gitignorePath, []byte("blah\n"), 0644)
   293  	if err != nil {
   294  		t.Errorf("can't create .gitignore: %s", err)
   295  	}
   296  
   297  	err = IgnoreSet("/.gtm/", workdir)
   298  	if err != nil {
   299  		t.Errorf("IgnoreSet error: %s", err)
   300  	}
   301  
   302  	data, err := ioutil.ReadFile(gitignorePath)
   303  	if err != nil {
   304  		t.Errorf("read .gitignore error: %s", err)
   305  	}
   306  
   307  	if string(data) != "blah\n/.gtm/\n" {
   308  		t.Errorf(
   309  			".gitignore want contents \"blah\n/.gtm/\n\", got \"%s\"",
   310  			string(data),
   311  		)
   312  	}
   313  }
   314  
   315  func TestIgnoreSet_GitignoreAlreadyContainsGivenData(t *testing.T) {
   316  	repo := util.NewTestRepo(t, false)
   317  	defer repo.Remove()
   318  
   319  	workdir := repo.Workdir()
   320  	gitignorePath := filepath.Join(workdir, ".gitignore")
   321  
   322  	err := ioutil.WriteFile(gitignorePath, []byte("/.gtm/\n"), 0644)
   323  	if err != nil {
   324  		t.Errorf("can't create .gitignore: %s", err)
   325  	}
   326  
   327  	err = IgnoreSet("/.gtm/", workdir)
   328  	if err != nil {
   329  		t.Errorf("IgnoreSet error: %s", err)
   330  	}
   331  
   332  	data, err := ioutil.ReadFile(gitignorePath)
   333  	if err != nil {
   334  		t.Errorf("read .gitignore error: %s", err)
   335  	}
   336  
   337  	if string(data) != "/.gtm/\n" {
   338  		t.Errorf(
   339  			".gitignore want contents \"/.gtm/\n\", got \"%s\"",
   340  			string(data),
   341  		)
   342  	}
   343  }
   344  
   345  func TestIgnoreSet_GitignoreError(t *testing.T) {
   346  	repo := util.NewTestRepo(t, false)
   347  	defer repo.Remove()
   348  
   349  	workdir := repo.Workdir()
   350  	gitignorePath := filepath.Join(workdir, ".gitignore")
   351  
   352  	// create directory with name .gitignore for io read error
   353  	err := os.Mkdir(gitignorePath, 0644)
   354  	if err != nil {
   355  		t.Errorf("can't create directory %s: %s", gitignorePath, err)
   356  	}
   357  
   358  	err = IgnoreSet("/.gtm/", workdir)
   359  	if err == nil {
   360  		t.Errorf("IgnoreSet must return error, .gitignore is error")
   361  	}
   362  
   363  	if !strings.Contains(err.Error(), "can't read") {
   364  		t.Errorf(
   365  			"IgnoreSet error must contain \"can't read\", got \"%s\"",
   366  			err,
   367  		)
   368  	}
   369  }
   370  
   371  func TestSetGitHooks(t *testing.T) {
   372  	repo := util.NewTestRepo(t, false)
   373  	defer repo.Remove()
   374  
   375  	gitRepoPath := repo.Path()
   376  
   377  	hooks := map[string]GitHook{
   378  		"post-commit": {
   379  			Exe:     "gtm",
   380  			Command: "gtm commit --yes",
   381  			RE:      regexp.MustCompile(`(?s)[/,:,a-z,A-Z,0-9,$,-,_,=, ]*gtm\s+commit\s+--yes\.*`)},
   382  	}
   383  
   384  	// test when hook exists
   385  	err := ioutil.WriteFile(path.Join(gitRepoPath, "hooks", "post-commit"), []byte{}, 0755)
   386  	if err != nil {
   387  		t.Fatalf("SetHooks(hooks) expect error nil, got %s", err)
   388  	}
   389  
   390  	err = SetHooks(hooks, gitRepoPath)
   391  	if err != nil {
   392  		t.Fatalf("SetHooks(hooks) expect error nil, got %s", err)
   393  	}
   394  	b, err := ioutil.ReadFile(path.Join(gitRepoPath, "hooks", "post-commit"))
   395  	if err != nil {
   396  		t.Fatalf("SetHooks(hooks) expect error nil, got %s", err)
   397  	}
   398  	output := string(b)
   399  	if !strings.Contains(output, hooks["post-commit"].Command) {
   400  		t.Errorf("SetHooks(hooks) expected post-commit to contain %s, got %s", hooks["post-commit"].Command, output)
   401  	}
   402  
   403  	// test if hook doesn't exist
   404  	err = os.Remove(path.Join(gitRepoPath, "hooks", "post-commit"))
   405  	if err != nil {
   406  		t.Fatalf("SetHooks(hooks) expect error nil, got %s", err)
   407  	}
   408  
   409  	err = SetHooks(hooks, gitRepoPath)
   410  	if err != nil {
   411  		t.Errorf("SetHooks(hooks) expect error nil, got %s", err)
   412  	}
   413  	b, err = ioutil.ReadFile(path.Join(gitRepoPath, "hooks", "post-commit"))
   414  	if err != nil {
   415  		t.Fatalf("SetHooks(hooks) expect error nil, got %s", err)
   416  	}
   417  	output = string(b)
   418  	if !strings.Contains(output, hooks["post-commit"].Command) {
   419  		t.Errorf("SetHooks(hooks) expected post-commit to contain %s, got %s", hooks["post-commit"].Command, output)
   420  	}
   421  
   422  	// test if hooks folder doesn't exist
   423  	err = os.RemoveAll(path.Join(gitRepoPath, "hooks"))
   424  	if err != nil {
   425  		t.Fatalf("SetHooks(hooks) expect error nil, got %s", err)
   426  	}
   427  
   428  	err = SetHooks(hooks, gitRepoPath)
   429  	if err != nil {
   430  		t.Errorf("SetHooks(hooks) expect error nil, got %s", err)
   431  	}
   432  	b, err = ioutil.ReadFile(path.Join(gitRepoPath, "hooks", "post-commit"))
   433  	if err != nil {
   434  		t.Fatalf("SetHooks(hooks) expect error nil, got %s", err)
   435  	}
   436  	output = string(b)
   437  	if !strings.Contains(output, hooks["post-commit"].Command) {
   438  		t.Errorf("SetHooks(hooks) expected post-commit to contain %s, got %s", hooks["post-commit"].Command, output)
   439  	}
   440  
   441  }
   442  
   443  func TestPushFetchRemote(t *testing.T) {
   444  	remoteRepo := util.NewTestRepo(t, true)
   445  	defer remoteRepo.Remove()
   446  
   447  	localRepo := remoteRepo.Clone()
   448  	defer localRepo.Remove()
   449  	localRepo.Seed()
   450  
   451  	noteTxt := "This is a note"
   452  	err := CreateNote(noteTxt, "gtm-data", localRepo.Workdir())
   453  	if err != nil {
   454  		t.Errorf("CreateNote error, %s", err)
   455  	}
   456  
   457  	localRepo.Push("origin", "refs/heads/master", "refs/notes/gtm-data")
   458  
   459  	// clone remote again in another directory
   460  	localRepo2 := remoteRepo.Clone()
   461  	defer localRepo2.Remove()
   462  	localRepo2.Fetch("origin", "refs/notes/gtm-data:refs/notes/gtm-data")
   463  
   464  	commit, err := HeadCommit(localRepo2.Workdir())
   465  	if err != nil {
   466  		t.Errorf("HeadCommit error, %s", err)
   467  	}
   468  
   469  	note, err := ReadNote(commit.ID, "gtm-data", true, localRepo2.Workdir())
   470  	if err != nil {
   471  		t.Errorf("ReadNote error, %s", err)
   472  	}
   473  
   474  	if note.Note != noteTxt {
   475  		t.Errorf("ReadNote want message \"%s\", got \"%s\"", noteTxt, note.Note)
   476  	}
   477  }