package main import ( "bytes" "log" "strings" "testing" "github.com/Masterminds/semver/v3" "github.com/go-git/go-billy/v5/osfs" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/storage/filesystem" "github.com/spf13/viper" ) var ( tags = []string{"0.1.1", "1.2.3", "3.1.1", "0.3.0", "4.1.1", "0.8.1", "1.1.1-PR.44.4"} ) func newRepo(tempDir string) *git.Repository { fs := osfs.New(tempDir) strg := filesystem.NewStorage(fs, nil) r, err := git.Init(strg, fs) if err != nil { log.Fatal(err) } return r } func makeCommit(wt *git.Worktree) (plumbing.Hash, error) { file, err := wt.Filesystem.Create("thisismyfile") if err != nil { return plumbing.Hash{}, err } file.Write([]byte("this is my content")) wt.Add("thisismyfile") hash, err := wt.Commit("this is a commit", &git.CommitOptions{}) if err != nil { return plumbing.Hash{}, err } return hash, nil } func TestCmd(t *testing.T) { tests := []struct { name string input string prior string output string isError error }{ { name: "patch bump", input: "patch", prior: "1.1.1", output: "1.1.2", isError: nil, }, { name: "minor bump", input: "minor", prior: "1.1.0", output: "1.2.0", isError: nil, }, { name: "major bump", input: "major", prior: "1.2.1", output: "2.0.0", isError: nil, }, { name: "major bump new prerelease", input: "major --prerelease --key-args PR_NUM=11", prior: "1.2.1", output: "2.0.0-PR.11.0", isError: nil, }, { name: "major bump existing prerelease bump", input: "major --prerelease --key-args PR_NUM=11", prior: "2.0.0-PR.11.0", output: "2.0.0-PR.11.1", isError: nil, }, { name: "minor bump new prerelease", input: "minor --prerelease --key-args PR_NUM=11", prior: "1.2.1", output: "1.3.0-PR.11.0", isError: nil, }, { name: "minor bump existing prerelease bump", input: "minor --prerelease --key-args PR_NUM=11", prior: "1.3.0-PR.11.0", output: "1.3.0-PR.11.1", isError: nil, }, { name: "patch bump new prerelease", input: "patch --prerelease --key-args PR_NUM=11", prior: "1.2.1", output: "1.2.2-PR.11.0", isError: nil, }, { name: "patch bump existing prerelease bump", input: "patch --prerelease --key-args PR_NUM=11", prior: "1.2.2-PR.11.0", output: "1.2.2-PR.11.1", isError: nil, }, { name: "patch bump different fmt", input: "patch --prerelease --prerelease-fmt NOTME.$BumpInt", prior: "1.2.3", output: "1.2.4-NOTME.0", isError: nil, }, { name: "patch bump existing different fmt", input: "patch --prerelease --prerelease-fmt NOTME.$BumpInt", prior: "1.2.4-NOTME.0", output: "1.2.4-NOTME.1", isError: nil, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { logOut := &bytes.Buffer{} repoDir := t.TempDir() testRepo := newRepo(repoDir) viper.Set("repo-dir", repoDir) wt, _ := testRepo.Worktree() hash, err := makeCommit(wt) if err != nil { t.Fatal(err) } _, err = testRepo.CreateTag(test.prior, hash, nil) if err != nil { t.Fatal(err) } rootCmd.SetArgs(strings.Split(test.input, " ")) rootCmd.SetOut(logOut) rootCmd.SetErr(logOut) result := rootCmd.Execute() if result != test.isError { t.Fatalf("didn't expect %s", result) } out := logOut.String() t.Logf("stuff %s", out) if out != test.output { t.Fatalf("expected %s found %s", test.output, out) } }) } } func TestLatestTags(t *testing.T) { semverTags := []*semver.Version{} for _, v := range tags { version, err := semver.NewVersion(v) if err != nil { log.Fatal(err) } semverTags = append(semverTags, version) } tests := []struct { name string inputs []*semver.Version // * for nil cases output *semver.Version }{ { name: "returns the last item in slice", inputs: semverTags, output: semver.New(1, 1, 1, "PR.44.4", ""), }, { name: "returns nil if no tags are present", inputs: []*semver.Version{}, output: &semver.Version{}, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { result := latestTag(test.inputs) if !test.output.Equal(result) { t.Fatalf("Expect %s found %s", test.output.String(), result.String()) } }) } } func TestFindingTags(t *testing.T) { tmpDir := t.TempDir() r := newRepo(tmpDir) wt, err := r.Worktree() if err != nil { t.Fatal(err) } hash, err := makeCommit(wt) if err != nil { t.Fatal(err) } results, err := findTags(r) if err != nil { t.Fatal(err) } if len(results) != 0 { t.Fatalf("Expected no tags, found %d", len(results)) } // at least a single tag is found _, err = r.CreateTag("0.0.1", hash, nil) if err != nil { t.Fatal(err) } results1, err := findTags(r) if err != nil { t.Fatal(err) } if len(results1) != 1 { t.Fatalf("Expected no tags, found %d", len(results1)) } // a random tag _, _ = r.CreateTag("this-is-not-me", hash, nil) results2, err := findTags(r) if err != nil { t.Fatal(err) } if len(results2) != 1 { t.Fatalf("Expected no tags, found %d", len(results2)) } // all semver tags for _, tag := range tags { _, _ = r.CreateTag(tag, hash, nil) } results3, err := findTags(r) if err != nil { t.Fatal(err) } if len(results3) != 8 { t.Fatalf("found %d", len(results3)) } } func TestIncPreRelease(t *testing.T) { tests := []struct { name string prf preReleaseVersion startVersion string expectedResult string hasError bool }{ { name: "test keyarg", prf: preReleaseVersion{ Fmt: []string{"PR", "$KeyArg PR_NUM"}, KeyArgs: map[string]string{"PR_NUM": "11"}, versionPart: "patch", }, startVersion: "1.0.1-PR.jjj.1", expectedResult: "1.0.1-PR.11", hasError: false, }, { name: "test bumpint", prf: preReleaseVersion{ Fmt: []string{"PR", "$KeyArg PR_NUM", "$BumpInt"}, KeyArgs: map[string]string{"PR_NUM": "11"}, versionPart: "patch", }, startVersion: "1.0.1-PR.jjj.1", expectedResult: "1.0.1-PR.11.2", hasError: false, }, { name: "test bumpint with parse err", prf: preReleaseVersion{ Fmt: []string{"PR", "$KeyArg PR_NUM", "$BumpInt"}, KeyArgs: map[string]string{"PR_NUM": "11"}, versionPart: "patch", }, startVersion: "1.0.1-PR.jjj.j", expectedResult: "1.0.1-PR.11.2", hasError: true, }, { name: "test fmt arg change", prf: preReleaseVersion{ Fmt: []string{"PR", "$KeyArg PR_NUM", "$BumpInt"}, KeyArgs: map[string]string{"PR_NUM": "11"}, versionPart: "patch", }, startVersion: "1.0.1-stuff.jjj.j", expectedResult: "1.0.1-PR.11.2", hasError: true, }, { name: "test creating a new pre-release", prf: preReleaseVersion{ Fmt: []string{"PR", "$KeyArg PR_NUM", "$BumpInt"}, KeyArgs: map[string]string{"PR_NUM": "11"}, versionPart: "patch", }, startVersion: "1.0.1", expectedResult: "1.0.2-PR.11.0", hasError: false, }, { name: "test creating a new major prerelease", prf: preReleaseVersion{ Fmt: []string{"PR", "$KeyArg PR_NUM", "$BumpInt"}, KeyArgs: map[string]string{"PR_NUM": "11"}, versionPart: "major", }, startVersion: "1.8.1", expectedResult: "2.0.0-PR.11.0", hasError: false, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { // start version sv, err := semver.NewVersion(test.startVersion) if err != nil { log.Fatal(err) } test.prf.v = sv nv, err := test.prf.incPreRelease() if !test.hasError && err != nil { t.Fatal(err) } if test.hasError && err == nil { t.Fatalf("found %s expected %s", nv, test.expectedResult) } // its an error and we expect it if test.hasError && err != nil { return } // its not right if nv.String() != test.expectedResult { t.Fatalf("found %s expected %s", nv, test.expectedResult) } }) } }