oh-my-posh/segment_git_test.go

627 lines
16 KiB
Go
Raw Normal View History

2019-03-13 04:14:30 -07:00
package main
import (
"testing"
"github.com/stretchr/testify/assert"
)
const (
changesColor = "#BD8BDE"
)
2019-03-13 04:14:30 -07:00
func TestEnabledGitNotFound(t *testing.T) {
env := new(MockedEnvironment)
env.On("hasCommand", "git").Return(false)
g := &git{
env: env,
}
assert.False(t, g.enabled())
}
func TestEnabledInWorkingDirectory(t *testing.T) {
env := new(MockedEnvironment)
env.On("hasCommand", "git").Return(true)
env.On("runCommand", "git", []string{"rev-parse", "--is-inside-work-tree"}).Return("true", nil)
2019-03-13 04:14:30 -07:00
g := &git{
env: env,
}
assert.True(t, g.enabled())
}
func TestGetGitOutputForCommand(t *testing.T) {
args := []string{"-c", "core.quotepath=false", "-c", "color.status=false"}
commandArgs := []string{"symbolic-ref", "--short", "HEAD"}
want := "je suis le output"
env := new(MockedEnvironment)
env.On("runCommand", "git", append(args, commandArgs...)).Return(want, nil)
2019-03-13 04:14:30 -07:00
g := &git{
env: env,
}
2020-10-07 04:32:42 -07:00
got := g.getGitCommandOutput(commandArgs...)
2019-03-13 04:14:30 -07:00
assert.Equal(t, want, got)
}
2020-10-07 04:32:42 -07:00
type detachedContext struct {
currentCommit string
rebase string
rebaseMerge bool
rebaseApply bool
origin string
onto string
step string
total string
branchName string
tagName string
2020-10-07 11:44:22 -07:00
cherryPick bool
cherryPickSHA string
2020-10-11 02:56:33 -07:00
merge bool
mergeHEAD string
2020-10-07 04:32:42 -07:00
}
2020-10-13 01:00:17 -07:00
func setupHEADContextEnv(context *detachedContext) *git {
2019-03-13 04:14:30 -07:00
env := new(MockedEnvironment)
2020-10-13 01:00:17 -07:00
env.On("hasFolder", "/.git/rebase-merge").Return(context.rebaseMerge)
env.On("hasFolder", "/.git/rebase-apply").Return(context.rebaseApply)
env.On("getFileContent", "/.git/rebase-merge/orig-head").Return(context.origin)
env.On("getFileContent", "/.git/rebase-merge/onto").Return(context.onto)
env.On("getFileContent", "/.git/rebase-merge/msgnum").Return(context.step)
env.On("getFileContent", "/.git/rebase-apply/next").Return(context.step)
env.On("getFileContent", "/.git/rebase-merge/end").Return(context.total)
env.On("getFileContent", "/.git/rebase-apply/last").Return(context.total)
env.On("getFileContent", "/.git/rebase-apply/head-name").Return(context.origin)
env.On("getFileContent", "/.git/CHERRY_PICK_HEAD").Return(context.cherryPickSHA)
env.On("getFileContent", "/.git/MERGE_HEAD").Return(context.mergeHEAD)
env.On("hasFiles", "/.git/CHERRY_PICK_HEAD").Return(context.cherryPick)
env.On("hasFiles", "/.git/MERGE_HEAD").Return(context.merge)
env.mockGitCommand(context.currentCommit, "rev-parse", "--short", "HEAD")
env.mockGitCommand(context.tagName, "describe", "--tags", "--exact-match")
env.mockGitCommand(context.origin, "name-rev", "--name-only", "--exclude=tags/*", context.origin)
env.mockGitCommand(context.onto, "name-rev", "--name-only", "--exclude=tags/*", context.onto)
env.mockGitCommand(context.cherryPickSHA, "name-rev", "--name-only", "--exclude=tags/*", context.cherryPickSHA)
env.mockGitCommand(context.mergeHEAD, "name-rev", "--name-only", "--exclude=tags/*", context.mergeHEAD)
2020-10-13 01:00:17 -07:00
g := &git{
env: env,
repo: &gitRepo{
root: "",
},
}
return g
2020-10-07 04:32:42 -07:00
}
func (m *MockedEnvironment) mockGitCommand(returnValue string, args ...string) {
args = append([]string{"-c", "core.quotepath=false", "-c", "color.status=false"}, args...)
m.On("runCommand", "git", args).Return(returnValue, nil)
}
2020-10-07 04:32:42 -07:00
func TestGetGitDetachedCommitHash(t *testing.T) {
2020-10-16 04:28:54 -07:00
want := "\uf417lalasha1"
2020-10-07 04:32:42 -07:00
context := &detachedContext{
2020-10-07 11:44:22 -07:00
currentCommit: "lalasha1",
2020-10-07 04:32:42 -07:00
}
2020-10-13 01:00:17 -07:00
g := setupHEADContextEnv(context)
got := g.getGitHEADContext("")
2019-03-13 04:14:30 -07:00
assert.Equal(t, want, got)
}
2020-10-07 11:44:22 -07:00
func TestGetGitHEADContextTagName(t *testing.T) {
2020-10-16 04:28:54 -07:00
want := "\uf412lalasha1"
2020-10-07 04:32:42 -07:00
context := &detachedContext{
currentCommit: "whatever",
2020-10-07 11:44:22 -07:00
tagName: "lalasha1",
2020-10-07 04:32:42 -07:00
}
2020-10-13 01:00:17 -07:00
g := setupHEADContextEnv(context)
got := g.getGitHEADContext("")
2020-10-07 04:32:42 -07:00
assert.Equal(t, want, got)
}
2020-10-07 11:44:22 -07:00
func TestGetGitHEADContextRebaseMerge(t *testing.T) {
2020-10-16 04:28:54 -07:00
want := "\ue728 \ue0a0cool-feature-bro onto \ue0a0main (2/3) at \uf417whatever"
2020-10-07 04:32:42 -07:00
context := &detachedContext{
currentCommit: "whatever",
rebase: "true",
rebaseMerge: true,
origin: "cool-feature-bro",
onto: "main",
step: "2",
total: "3",
}
2020-10-13 01:00:17 -07:00
g := setupHEADContextEnv(context)
got := g.getGitHEADContext("")
2020-10-07 04:32:42 -07:00
assert.Equal(t, want, got)
}
2020-10-07 11:44:22 -07:00
func TestGetGitHEADContextRebaseApply(t *testing.T) {
2020-10-16 04:28:54 -07:00
want := "\ue728 \ue0a0cool-feature-bro (2/3) at \uf417whatever"
2020-10-07 04:32:42 -07:00
context := &detachedContext{
currentCommit: "whatever",
rebase: "true",
rebaseApply: true,
origin: "cool-feature-bro",
step: "2",
total: "3",
}
2020-10-13 01:00:17 -07:00
g := setupHEADContextEnv(context)
got := g.getGitHEADContext("")
2020-10-07 04:32:42 -07:00
assert.Equal(t, want, got)
}
2020-10-07 11:44:22 -07:00
func TestGetGitHEADContextRebaseUnknown(t *testing.T) {
2020-10-16 04:28:54 -07:00
want := "\uf417whatever"
2020-10-07 04:32:42 -07:00
context := &detachedContext{
currentCommit: "whatever",
rebase: "true",
}
2020-10-13 01:00:17 -07:00
g := setupHEADContextEnv(context)
got := g.getGitHEADContext("")
2020-10-07 11:44:22 -07:00
assert.Equal(t, want, got)
}
func TestGetGitHEADContextCherryPickOnBranch(t *testing.T) {
2020-10-16 04:28:54 -07:00
want := "\ue29b pickme onto \ue0a0main"
2020-10-07 11:44:22 -07:00
context := &detachedContext{
currentCommit: "whatever",
branchName: "main",
cherryPick: true,
cherryPickSHA: "pickme",
}
2020-10-13 01:00:17 -07:00
g := setupHEADContextEnv(context)
got := g.getGitHEADContext("main")
2020-10-07 11:44:22 -07:00
assert.Equal(t, want, got)
}
func TestGetGitHEADContextCherryPickOnTag(t *testing.T) {
2020-10-16 04:28:54 -07:00
want := "\ue29b pickme onto \uf412v3.4.6"
2020-10-07 11:44:22 -07:00
context := &detachedContext{
currentCommit: "whatever",
tagName: "v3.4.6",
cherryPick: true,
cherryPickSHA: "pickme",
}
2020-10-13 01:00:17 -07:00
g := setupHEADContextEnv(context)
got := g.getGitHEADContext("")
2019-03-13 04:14:30 -07:00
assert.Equal(t, want, got)
}
2020-10-11 02:56:33 -07:00
func TestGetGitHEADContextMerge(t *testing.T) {
2020-10-16 04:28:54 -07:00
want := "\ue727 \ue0a0feat into \ue0a0main"
2020-10-11 02:56:33 -07:00
context := &detachedContext{
merge: true,
mergeHEAD: "feat",
}
2020-10-13 01:00:17 -07:00
g := setupHEADContextEnv(context)
2020-10-11 02:56:33 -07:00
got := g.getGitHEADContext("main")
assert.Equal(t, want, got)
}
func TestGetGitHEADContextMergeTag(t *testing.T) {
2020-10-16 04:28:54 -07:00
want := "\ue727 \ue0a0feat into \uf412v3.4.6"
2020-10-11 02:56:33 -07:00
context := &detachedContext{
tagName: "v3.4.6",
merge: true,
mergeHEAD: "feat",
}
2020-10-13 01:00:17 -07:00
g := setupHEADContextEnv(context)
2020-10-11 02:56:33 -07:00
got := g.getGitHEADContext("")
assert.Equal(t, want, got)
}
2019-03-13 04:14:30 -07:00
func TestGetStashContextZeroEntries(t *testing.T) {
2020-10-10 10:27:04 -07:00
want := ""
2019-03-13 04:14:30 -07:00
env := new(MockedEnvironment)
env.On("runCommand", "git", []string{"-c", "core.quotepath=false", "-c", "color.status=false", "rev-list", "--walk-reflogs", "--count", "refs/stash"}).Return("", nil)
2019-03-13 04:14:30 -07:00
g := &git{
env: env,
}
got := g.getStashContext()
assert.Equal(t, want, got)
}
func TestGetStashContextMultipleEntries(t *testing.T) {
2020-10-10 10:27:04 -07:00
want := "2"
2019-03-13 04:14:30 -07:00
env := new(MockedEnvironment)
env.On("runCommand", "git", []string{"-c", "core.quotepath=false", "-c", "color.status=false", "rev-list", "--walk-reflogs", "--count", "refs/stash"}).Return("2", nil)
2019-03-13 04:14:30 -07:00
g := &git{
env: env,
}
got := g.getStashContext()
assert.Equal(t, want, got)
}
func TestParseGitBranchInfoEqual(t *testing.T) {
g := git{}
branchInfo := "## master...origin/master"
2020-10-07 11:44:22 -07:00
got := g.parseGitStatusInfo(branchInfo)
2019-03-13 04:14:30 -07:00
assert.Equal(t, "master", got["local"])
assert.Equal(t, "origin/master", got["upstream"])
assert.Empty(t, got["ahead"])
assert.Empty(t, got["behind"])
}
func TestParseGitBranchInfoAhead(t *testing.T) {
g := git{}
branchInfo := "## master...origin/master [ahead 1]"
2020-10-07 11:44:22 -07:00
got := g.parseGitStatusInfo(branchInfo)
2019-03-13 04:14:30 -07:00
assert.Equal(t, "master", got["local"])
assert.Equal(t, "origin/master", got["upstream"])
assert.Equal(t, "1", got["ahead"])
assert.Empty(t, got["behind"])
}
func TestParseGitBranchInfoBehind(t *testing.T) {
g := git{}
branchInfo := "## master...origin/master [behind 1]"
2020-10-07 11:44:22 -07:00
got := g.parseGitStatusInfo(branchInfo)
2019-03-13 04:14:30 -07:00
assert.Equal(t, "master", got["local"])
assert.Equal(t, "origin/master", got["upstream"])
assert.Equal(t, "1", got["behind"])
assert.Empty(t, got["ahead"])
}
func TestParseGitBranchInfoBehindandAhead(t *testing.T) {
g := git{}
branchInfo := "## master...origin/master [ahead 1, behind 2]"
2020-10-07 11:44:22 -07:00
got := g.parseGitStatusInfo(branchInfo)
2019-03-13 04:14:30 -07:00
assert.Equal(t, "master", got["local"])
assert.Equal(t, "origin/master", got["upstream"])
assert.Equal(t, "2", got["behind"])
assert.Equal(t, "1", got["ahead"])
}
2020-10-10 10:16:58 -07:00
func TestParseGitBranchInfoNoRemote(t *testing.T) {
g := git{}
branchInfo := "## master"
got := g.parseGitStatusInfo(branchInfo)
assert.Equal(t, "master", got["local"])
assert.Empty(t, got["upstream"])
}
2020-10-11 04:32:21 -07:00
func TestParseGitBranchInfoRemoteGone(t *testing.T) {
g := git{}
branchInfo := "## test-branch...origin/test-branch [gone]"
got := g.parseGitStatusInfo(branchInfo)
assert.Equal(t, "test-branch", got["local"])
assert.Equal(t, "gone", got["upstream_status"])
}
2020-10-11 04:32:21 -07:00
func TestGitStatusUnmerged(t *testing.T) {
expected := "<#123456>working: x1</>"
2020-10-11 04:32:21 -07:00
status := &gitStatus{
unmerged: 1,
}
2020-10-18 03:30:27 -07:00
assert.Equal(t, expected, status.string("working:", "#123456"))
2020-10-11 04:32:21 -07:00
}
func TestGitStatusUnmergedModified(t *testing.T) {
expected := "<#123456>working: ~3 x1</>"
2020-10-11 04:32:21 -07:00
status := &gitStatus{
unmerged: 1,
modified: 3,
}
2020-10-18 03:30:27 -07:00
assert.Equal(t, expected, status.string("working:", "#123456"))
2020-10-11 04:32:21 -07:00
}
func TestGitStatusEmpty(t *testing.T) {
expected := ""
status := &gitStatus{}
2020-10-18 03:30:27 -07:00
assert.Equal(t, expected, status.string("working:", "#123456"))
2020-10-11 04:32:21 -07:00
}
func TestParseGitStatsWorking(t *testing.T) {
g := &git{}
output := []string{
"## amazing-feat",
" M change.go",
"DD change.go",
" ? change.go",
" ? change.go",
" A change.go",
" U change.go",
" R change.go",
" C change.go",
}
status := g.parseGitStats(output, true)
assert.Equal(t, 3, status.modified)
assert.Equal(t, 1, status.unmerged)
assert.Equal(t, 1, status.added)
assert.Equal(t, 1, status.deleted)
assert.Equal(t, 2, status.untracked)
2020-10-18 10:27:20 -07:00
assert.True(t, status.changed)
2020-10-11 04:32:21 -07:00
}
func TestParseGitStatsStaging(t *testing.T) {
g := &git{}
output := []string{
"## amazing-feat",
" M change.go",
"DD change.go",
" ? change.go",
"?? change.go",
" A change.go",
"DU change.go",
"MR change.go",
"AC change.go",
}
status := g.parseGitStats(output, false)
assert.Equal(t, 1, status.modified)
assert.Equal(t, 0, status.unmerged)
assert.Equal(t, 1, status.added)
assert.Equal(t, 2, status.deleted)
2020-10-18 23:54:15 -07:00
assert.Equal(t, 0, status.untracked)
2020-10-18 10:27:20 -07:00
assert.True(t, status.changed)
2020-10-11 04:32:21 -07:00
}
func TestParseGitStatsNoChanges(t *testing.T) {
g := &git{}
expected := &gitStatus{}
output := []string{
"## amazing-feat",
}
status := g.parseGitStats(output, false)
assert.Equal(t, expected, status)
2020-10-18 10:27:20 -07:00
assert.False(t, status.changed)
2020-10-11 04:32:21 -07:00
}
func TestParseGitStatsInvalidLine(t *testing.T) {
g := &git{}
expected := &gitStatus{}
output := []string{
"## amazing-feat",
"#",
}
status := g.parseGitStats(output, false)
assert.Equal(t, expected, status)
2020-10-18 10:27:20 -07:00
assert.False(t, status.changed)
2020-10-11 04:32:21 -07:00
}
func bootstrapUpstreamTest(upstream string) *git {
env := &MockedEnvironment{}
env.On("runCommand", "git", []string{"-c", "core.quotepath=false", "-c", "color.status=false", "remote", "get-url", "origin"}).Return(upstream, nil)
props := &properties{
values: map[Property]interface{}{
GithubIcon: "GH",
GitlabIcon: "GL",
BitbucketIcon: "BB",
GitIcon: "G",
},
}
g := &git{
env: env,
repo: &gitRepo{
upstream: "origin/main",
},
props: props,
}
return g
}
func TestGetUpstreamSymbolGitHub(t *testing.T) {
g := bootstrapUpstreamTest("github.com/test")
upstreamIcon := g.getUpstreamSymbol()
assert.Equal(t, "GH", upstreamIcon)
}
func TestGetUpstreamSymbolGitLab(t *testing.T) {
g := bootstrapUpstreamTest("gitlab.com/test")
upstreamIcon := g.getUpstreamSymbol()
assert.Equal(t, "GL", upstreamIcon)
}
func TestGetUpstreamSymbolBitBucket(t *testing.T) {
g := bootstrapUpstreamTest("bitbucket.org/test")
upstreamIcon := g.getUpstreamSymbol()
assert.Equal(t, "BB", upstreamIcon)
}
func TestGetUpstreamSymbolGit(t *testing.T) {
g := bootstrapUpstreamTest("gitstash.com/test")
upstreamIcon := g.getUpstreamSymbol()
assert.Equal(t, "G", upstreamIcon)
}
2020-10-18 10:27:20 -07:00
func TestGetStatusColorLocalChangesStaging(t *testing.T) {
expected := changesColor
2020-10-18 10:27:20 -07:00
repo := &gitRepo{
staging: &gitStatus{
changed: true,
},
}
g := &git{
repo: repo,
props: &properties{
values: map[Property]interface{}{
LocalChangesColor: expected,
},
},
}
assert.Equal(t, expected, g.getStatusColor("#fg1111"))
}
func TestGetStatusColorLocalChangesWorking(t *testing.T) {
expected := changesColor
2020-10-18 10:27:20 -07:00
repo := &gitRepo{
staging: &gitStatus{},
working: &gitStatus{
changed: true,
},
}
g := &git{
repo: repo,
props: &properties{
values: map[Property]interface{}{
LocalChangesColor: expected,
},
},
}
assert.Equal(t, expected, g.getStatusColor("#fg1111"))
}
func TestGetStatusColorAheadAndBehind(t *testing.T) {
expected := changesColor
2020-10-18 10:27:20 -07:00
repo := &gitRepo{
staging: &gitStatus{},
working: &gitStatus{},
ahead: 1,
behind: 3,
}
g := &git{
repo: repo,
props: &properties{
values: map[Property]interface{}{
AheadAndBehindColor: expected,
},
},
}
assert.Equal(t, expected, g.getStatusColor("#fg1111"))
}
func TestGetStatusColorAhead(t *testing.T) {
expected := changesColor
2020-10-18 10:27:20 -07:00
repo := &gitRepo{
staging: &gitStatus{},
working: &gitStatus{},
ahead: 1,
behind: 0,
}
g := &git{
repo: repo,
props: &properties{
values: map[Property]interface{}{
AheadColor: expected,
},
},
}
assert.Equal(t, expected, g.getStatusColor("#fg1111"))
}
func TestGetStatusColorBehind(t *testing.T) {
expected := changesColor
2020-10-18 10:27:20 -07:00
repo := &gitRepo{
staging: &gitStatus{},
working: &gitStatus{},
ahead: 0,
behind: 5,
}
g := &git{
repo: repo,
props: &properties{
values: map[Property]interface{}{
BehindColor: expected,
},
},
}
assert.Equal(t, expected, g.getStatusColor("#fg1111"))
}
func TestGetStatusColorDefault(t *testing.T) {
expected := changesColor
2020-10-18 10:27:20 -07:00
repo := &gitRepo{
staging: &gitStatus{},
working: &gitStatus{},
ahead: 0,
behind: 0,
}
g := &git{
repo: repo,
props: &properties{
values: map[Property]interface{}{
BehindColor: changesColor,
2020-10-18 10:27:20 -07:00
},
},
}
assert.Equal(t, expected, g.getStatusColor(expected))
}
func TestSetStatusColorBackground(t *testing.T) {
expected := changesColor
2020-10-18 10:27:20 -07:00
repo := &gitRepo{
staging: &gitStatus{
changed: true,
},
}
g := &git{
repo: repo,
props: &properties{
values: map[Property]interface{}{
LocalChangesColor: changesColor,
2020-10-18 10:27:20 -07:00
ColorBackground: false,
},
foreground: "#ffffff",
background: "#111111",
},
}
g.SetStatusColor()
assert.Equal(t, expected, g.props.foreground)
}
func TestSetStatusColorForeground(t *testing.T) {
expected := changesColor
2020-10-18 10:27:20 -07:00
repo := &gitRepo{
staging: &gitStatus{
changed: true,
},
}
g := &git{
repo: repo,
props: &properties{
values: map[Property]interface{}{
LocalChangesColor: changesColor,
2020-10-18 10:27:20 -07:00
ColorBackground: true,
},
foreground: "#ffffff",
background: "#111111",
},
}
g.SetStatusColor()
assert.Equal(t, expected, g.props.background)
}
func TestGetStatusDetailStringDefault(t *testing.T) {
expected := "<#111111>icon +1</>"
status := &gitStatus{
changed: true,
added: 1,
}
g := &git{
props: &properties{
foreground: "#111111",
},
}
assert.Equal(t, expected, g.getStatusDetailString(status, WorkingColor, LocalWorkingIcon, "icon"))
}
func TestGetStatusDetailStringNoStatus(t *testing.T) {
expected := "<#111111>icon</>"
status := &gitStatus{
changed: true,
added: 1,
}
g := &git{
props: &properties{
values: map[Property]interface{}{
DisplayStatusDetail: false,
},
foreground: "#111111",
},
}
assert.Equal(t, expected, g.getStatusDetailString(status, WorkingColor, LocalWorkingIcon, "icon"))
}
func TestGetStatusDetailStringNoStatusColorOverride(t *testing.T) {
expected := "<#123456>icon</>"
status := &gitStatus{
changed: true,
added: 1,
}
g := &git{
props: &properties{
values: map[Property]interface{}{
DisplayStatusDetail: false,
WorkingColor: "#123456",
},
foreground: "#111111",
},
}
assert.Equal(t, expected, g.getStatusDetailString(status, WorkingColor, LocalWorkingIcon, "icon"))
}