refactor: use testify assert (#59)

This commit is contained in:
Robert Kaussow 2024-03-11 09:23:17 +01:00 committed by GitHub
parent 2a7e9279ef
commit 35a26ac068
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 328 additions and 161 deletions

View File

@ -5,7 +5,7 @@ import (
"os"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/assert"
"github.com/urfave/cli/v2"
)
@ -81,10 +81,10 @@ func TestToMarkdownFull(t *testing.T) {
for _, tt := range tests {
want := testFileContent(t, tt.want)
t.Run(tt.name, func(t *testing.T) {
if got, _ := ToMarkdown(tt.app); got != want {
t.Errorf("got = %v, want %v", got, want)
}
got, _ := ToMarkdown(tt.app)
assert.Equal(t, want, got)
})
}
}
@ -141,10 +141,9 @@ func TestToData(t *testing.T) {
for _, tt := range tests {
got := GetTemplateData(tt.app)
t.Run(tt.name, func(t *testing.T) {
if diff := cmp.Diff(tt.want, got); diff != "" {
t.Errorf("data mismatch (-want +got):\n%s", diff)
}
assert.Equal(t, tt.want, got)
})
}
}

View File

@ -1,6 +1,8 @@
package file
import "os"
import (
"os"
)
// The MSDN docs appear to say that a normal path that is 248 bytes long will work;
// empirically the path must be less then 248 bytes long.
@ -30,6 +32,9 @@ func ReadStringOrFile(input string) (string, bool, error) {
return string(result), true, nil
}
// DeleteDir deletes the directory at the given path.
// It returns nil if the deletion succeeds, or the deletion error otherwise.
// If the directory does not exist, DeleteDir returns nil.
func DeleteDir(path string) error {
if _, err := os.Stat(path); os.IsNotExist(err) {
return nil

6
go.mod
View File

@ -5,9 +5,9 @@ go 1.22
require (
github.com/Masterminds/semver/v3 v3.2.1
github.com/Masterminds/sprig/v3 v3.2.3
github.com/google/go-cmp v0.6.0
github.com/joho/godotenv v1.5.1
github.com/rs/zerolog v1.32.0
github.com/stretchr/testify v1.7.0
github.com/urfave/cli/v2 v2.27.1
golang.org/x/net v0.22.0
)
@ -15,6 +15,7 @@ require (
require (
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/google/uuid v1.1.1 // indirect
github.com/huandu/xstrings v1.3.3 // indirect
github.com/imdario/mergo v0.3.11 // indirect
@ -22,11 +23,12 @@ require (
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/reflectwalk v1.0.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/stretchr/testify v1.7.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/sys v0.18.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

3
go.sum
View File

@ -12,8 +12,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
@ -89,6 +87,7 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=

View File

@ -233,6 +233,10 @@ func prevFromContext(c *cli.Context) Commit {
}
}
// splitMessage splits a commit message into a title and description.
// It splits the message on the first newline character, with the first
// line as the title, and the rest as the description. If there is no newline,
// the entire message is returned as the title, and the description is empty.
func splitMessage(message string) (string, string) {
//nolint:gomnd
switch parts := strings.SplitN(message, "\n", 2); len(parts) {

View File

@ -4,15 +4,18 @@ import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/urfave/cli/v2"
)
func Test_currFromContext(t *testing.T) {
tests := []struct {
name string
envs map[string]string
want map[string]string
}{
{
name: "empty commit message",
envs: map[string]string{
"CI_COMMIT_MESSAGE": "",
},
@ -23,6 +26,7 @@ func Test_currFromContext(t *testing.T) {
},
},
{
name: "commit message with title and desc",
envs: map[string]string{
"CI_COMMIT_MESSAGE": "test_title\ntest_desc",
},
@ -33,6 +37,7 @@ func Test_currFromContext(t *testing.T) {
},
},
{
name: "commit message with title, desc and additional",
envs: map[string]string{
"CI_COMMIT_MESSAGE": "test_title\ntest_desc\nadditional",
},
@ -63,16 +68,55 @@ func Test_currFromContext(t *testing.T) {
_ = got.App.Run([]string{"dummy"})
if got.Metadata.Curr.Message != tt.want["message"] {
t.Errorf("got = %q, want = %q", got.Metadata.Curr.Message, tt.want["message"])
}
if got.Metadata.Curr.Title != tt.want["title"] {
t.Errorf("got = %q, want = %q", got.Metadata.Curr.Title, tt.want["title"])
}
if got.Metadata.Curr.Description != tt.want["desc"] {
t.Errorf("got = %q, want = %q", got.Metadata.Curr.Description, tt.want["desc"])
}
assert.Equal(t, got.Metadata.Curr.Message, tt.want["message"])
assert.Equal(t, got.Metadata.Curr.Title, tt.want["title"])
assert.Equal(t, got.Metadata.Curr.Description, tt.want["desc"])
}
}
func TestSplitMessage(t *testing.T) {
testCases := []struct {
name string
message string
wantTitle string
wantDescription string
}{
{
name: "empty message",
message: "",
wantTitle: "",
wantDescription: "",
},
{
name: "only title",
message: "Title",
wantTitle: "Title",
wantDescription: "",
},
{
name: "title and description",
message: "Title\nDescription",
wantTitle: "Title",
wantDescription: "Description",
},
{
name: "title and description with blank line",
message: "Title\n\nDescription with blank line",
wantTitle: "Title",
wantDescription: "\nDescription with blank line",
},
{
name: "title and description with multiple blank lines",
message: "Title\n\n\nMultiple blank lines\nDescription",
wantTitle: "Title",
wantDescription: "\n\nMultiple blank lines\nDescription",
},
}
for _, tc := range testCases {
gotTitle, gotDescription := splitMessage(tc.message)
assert.Equal(t, tc.wantTitle, gotTitle)
assert.Equal(t, tc.wantDescription, gotDescription)
}
}

View File

@ -1,55 +1,48 @@
package tag
import (
"reflect"
"testing"
"github.com/stretchr/testify/assert"
)
func Test_stripTagPrefix(t *testing.T) {
tests := []struct {
Before string
After string
before string
after string
}{
{"refs/tags/1.0.0", "1.0.0"},
{"refs/tags/v1.0.0", "1.0.0"},
{"v1.0.0", "1.0.0"},
{before: "refs/tags/1.0.0", after: "1.0.0"},
{before: "refs/tags/v1.0.0", after: "1.0.0"},
{before: "v1.0.0", after: "1.0.0"},
}
for _, test := range tests {
got, want := stripTagPrefix(test.Before), test.After
if got != want {
t.Errorf("Got tag %s, want %s", got, want)
}
for _, tt := range tests {
got, want := stripTagPrefix(tt.before), tt.after
assert.Equal(t, got, want)
}
}
func TestSemverTagsStrict(t *testing.T) {
tests := []struct {
Before string
After []string
before string
after []string
}{
{"", []string{"latest"}},
{"refs/heads/main", []string{"latest"}},
{"refs/tags/0.9.0", []string{"0.9", "0.9.0"}},
{"refs/tags/1.0.0", []string{"1", "1.0", "1.0.0"}},
{"refs/tags/v1.0.0", []string{"1", "1.0", "1.0.0"}},
{"refs/tags/v1.0.0+1", []string{"1", "1.0", "1.0.0"}},
{"refs/tags/v1.0.0-alpha.1", []string{"1.0.0-alpha.1"}},
{"refs/tags/v1.0.0-alpha", []string{"1.0.0-alpha"}},
{before: "", after: []string{"latest"}},
{before: "refs/heads/main", after: []string{"latest"}},
{before: "refs/tags/0.9.0", after: []string{"0.9", "0.9.0"}},
{before: "refs/tags/1.0.0", after: []string{"1", "1.0", "1.0.0"}},
{before: "refs/tags/v1.0.0", after: []string{"1", "1.0", "1.0.0"}},
{before: "refs/tags/v1.0.0+1", after: []string{"1", "1.0", "1.0.0"}},
{before: "refs/tags/v1.0.0-alpha.1", after: []string{"1.0.0-alpha.1"}},
{before: "refs/tags/v1.0.0-alpha", after: []string{"1.0.0-alpha"}},
}
for _, test := range tests {
tags, err := SemverTags(test.Before, true)
if err != nil {
t.Error(err)
for _, tt := range tests {
tags, err := SemverTags(tt.before, true)
assert.NoError(t, err)
continue
}
got, want := tags, test.After
if !reflect.DeepEqual(got, want) {
t.Errorf("Got tag %v, want %v", got, want)
}
got, want := tags, tt.after
assert.Equal(t, got, want)
}
}
@ -70,19 +63,12 @@ func TestSemverTags(t *testing.T) {
{"refs/tags/22.04.0", []string{"22", "22.4", "22.4.0"}},
{"refs/tags/22.04", []string{"22", "22.4", "22.4.0"}},
}
for _, tt := range tests {
tags, err := SemverTags(tt.Before, false)
assert.NoError(t, err)
for _, test := range tests {
tags, err := SemverTags(test.Before, false)
if err != nil {
t.Error(err)
continue
}
got, want := tags, test.After
if !reflect.DeepEqual(got, want) {
t.Errorf("Got tag %v, want %v", got, want)
}
got, want := tags, tt.After
assert.Equal(t, got, want)
}
}
@ -94,27 +80,25 @@ func TestSemverTagsSrtictError(t *testing.T) {
"refs/tags/22.04",
}
for _, test := range tests {
_, err := SemverTags(test, true)
if err == nil {
t.Errorf("Expect tag error for %s", test)
}
for _, tt := range tests {
_, err := SemverTags(tt, true)
assert.Error(t, err, "Expect tag error for %s", tt)
}
}
func TestSemverTagSuffix(t *testing.T) {
tests := []struct {
Before string
Suffix string
After []string
before string
suffix string
after []string
}{
// without suffix
{
After: []string{"latest"},
after: []string{"latest"},
},
{
Before: "refs/tags/v1.0.0",
After: []string{
before: "refs/tags/v1.0.0",
after: []string{
"1",
"1.0",
"1.0.0",
@ -122,26 +106,26 @@ func TestSemverTagSuffix(t *testing.T) {
},
// with suffix
{
Suffix: "linux-amd64",
After: []string{"linux-amd64"},
suffix: "linux-amd64",
after: []string{"linux-amd64"},
},
{
Before: "refs/tags/v1.0.0",
Suffix: "linux-amd64",
After: []string{
before: "refs/tags/v1.0.0",
suffix: "linux-amd64",
after: []string{
"1-linux-amd64",
"1.0-linux-amd64",
"1.0.0-linux-amd64",
},
},
{
Suffix: "nanoserver",
After: []string{"nanoserver"},
suffix: "nanoserver",
after: []string{"nanoserver"},
},
{
Before: "refs/tags/v1.9.2",
Suffix: "nanoserver",
After: []string{
before: "refs/tags/v1.9.2",
suffix: "nanoserver",
after: []string{
"1-nanoserver",
"1.9-nanoserver",
"1.9.2-nanoserver",
@ -149,18 +133,12 @@ func TestSemverTagSuffix(t *testing.T) {
},
}
for _, test := range tests {
tag, err := SemverTagSuffix(test.Before, test.Suffix, true)
if err != nil {
t.Error(err)
for _, tt := range tests {
tag, err := SemverTagSuffix(tt.before, tt.suffix, true)
assert.NoError(t, err)
continue
}
got, want := tag, test.After
if !reflect.DeepEqual(got, want) {
t.Errorf("Got tag %v, want %v", got, want)
}
got, want := tag, tt.after
assert.Equal(t, got, want)
}
}
@ -182,52 +160,7 @@ func Test_stripHeadPrefix(t *testing.T) {
}
for _, tt := range tests {
if got := stripHeadPrefix(tt.args.ref); got != tt.want {
t.Errorf("stripHeadPrefix() = %v, want %v", got, tt.want)
}
}
}
func TestIsTaggable(t *testing.T) {
type args struct {
ref string
defaultBranch string
}
tests := []struct {
name string
args args
want bool
}{
{
name: "latest tag for default branch",
args: args{
ref: "refs/heads/main",
defaultBranch: "main",
},
want: true,
},
{
name: "build from tags",
args: args{
ref: "refs/tags/v1.0.0",
defaultBranch: "main",
},
want: true,
},
{
name: "skip build for not default branch",
args: args{
ref: "refs/heads/develop",
defaultBranch: "main",
},
want: false,
},
}
for _, tt := range tests {
if got := IsTaggable(tt.args.ref, tt.args.defaultBranch); got != tt.want {
t.Errorf("%q. IsTaggable() = %v, want %v", tt.name, got, tt.want)
}
got := stripHeadPrefix(tt.args.ref)
assert.Equal(t, got, tt.want)
}
}

View File

@ -2,10 +2,14 @@ package tag
import "strings"
// stripHeadPrefix removes the "refs/heads/" prefix from the given ref string.
// It is used to clean up Git ref names.
func stripHeadPrefix(ref string) string {
return strings.TrimPrefix(ref, "refs/heads/")
}
// stripTagPrefix removes the "refs/tags/" prefix and any "v" prefix
// from the given ref string. It is used to clean up Git tag ref names.
func stripTagPrefix(ref string) string {
ref = strings.TrimPrefix(ref, "refs/tags/")
ref = strings.TrimPrefix(ref, "v")

50
tag/util_test.go Normal file
View File

@ -0,0 +1,50 @@
package tag
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestIsTaggable(t *testing.T) {
type args struct {
ref string
defaultBranch string
}
tests := []struct {
name string
args args
want bool
}{
{
name: "latest tag for default branch",
args: args{
ref: "refs/heads/main",
defaultBranch: "main",
},
want: true,
},
{
name: "build from tags",
args: args{
ref: "refs/tags/v1.0.0",
defaultBranch: "main",
},
want: true,
},
{
name: "skip build for not default branch",
args: args{
ref: "refs/heads/develop",
defaultBranch: "main",
},
want: false,
},
}
for _, tt := range tests {
got := IsTaggable(tt.args.ref, tt.args.defaultBranch)
assert.Equal(t, got, tt.want, "%q. IsTaggable() = %v, want %v", tt.name, got, tt.want)
}
}

View File

@ -9,6 +9,8 @@ import (
"github.com/Masterminds/sprig/v3"
)
// LoadFuncMap merges the sprig template functions with any custom functions
// provided, giving priority to the custom functions in case of collisions.
func LoadFuncMap() template.FuncMap {
sprigFuncs := sprig.GenericFuncMap()
customFuncs := template.FuncMap{
@ -26,6 +28,8 @@ func LoadFuncMap() template.FuncMap {
return sprigFuncs
}
// ToSentence capitalizes the first letter of the input string,
// adds a period at the end if needed, and returns the resulting sentence.
func ToSentence(s string) string {
if s == "" {
return ""
@ -41,6 +45,8 @@ func ToSentence(s string) string {
return fmt.Sprintf("%s%s%s", string(unicode.ToUpper(r)), s[n:], closer)
}
// getLastRune returns the last n runes in the string s.
// It decodes s from the end, counting n runes.
func getLastRune(s string, c int) string {
j := len(s)
for i := 0; i < c && j > 0; i++ {

View File

@ -0,0 +1,68 @@
package template
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestToSentence(t *testing.T) {
tests := []struct {
name string
input string
want string
}{
{
name: "empty string",
input: "",
want: "",
},
{
name: "sentence without end period",
input: "this is a sentence",
want: "This is a sentence.",
},
{
name: "sentence with end period",
input: "this is a sentence.",
want: "This is a sentence.",
},
{
name: "single word",
input: "word",
want: "Word.",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := ToSentence(tt.input)
assert.Equal(t, got, tt.want)
})
}
}
func TestLoadFuncMap(t *testing.T) {
tests := []struct {
name string
want []string
wantDiff int
}{
{
name: "valid",
want: []string{
"ToSentence",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := LoadFuncMap()
_, ok := got["ToSentence"]
assert.True(t, ok, "LoadFuncMap() missing ToSentence func")
})
}
}

View File

@ -78,7 +78,9 @@ func RenderTrim(ctx context.Context, client http.Client, template string, playlo
return strings.Trim(out, " \n"), err
}
// AddPrefix is a helper function to ensure a string has a defined prefix.
// AddPrefix prepends the prefix string to the input string if the input
// string does not already have the prefix. It trims any leading or trailing
// space from the input before checking for the prefix.
func AddPrefix(prefix, input string) string {
if strings.TrimSpace(input) == "" {
return input

52
template/template_test.go Normal file
View File

@ -0,0 +1,52 @@
package template
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestAddPrefix(t *testing.T) {
type args struct {
prefix string
input string
}
tests := []struct {
name string
args args
want string
}{
{
name: "empty input",
args: args{
prefix: "pre",
input: "",
},
want: "",
},
{
name: "input already has prefix",
args: args{
prefix: "pre",
input: "pre-existing",
},
want: "pre-existing",
},
{
name: "add prefix",
args: args{
prefix: "pre",
input: "-existing",
},
want: "pre-existing",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := AddPrefix(tt.args.prefix, tt.args.input)
assert.Equal(t, tt.want, got)
})
}
}

View File

@ -1,28 +1,27 @@
package types
import (
"reflect"
"testing"
"github.com/stretchr/testify/assert"
)
func TestSplitWithEscaping(t *testing.T) {
tests := []struct {
Input string
Output []string
input string
output []string
}{
{"", []string{}},
{"a,b", []string{"a", "b"}},
{",,,", []string{"", "", "", ""}},
{",a\\,", []string{"", "a,"}},
{"a,b\\,c\\\\d,e", []string{"a", "b,c\\\\d", "e"}},
{input: "", output: []string{}},
{input: "a,b", output: []string{"a", "b"}},
{input: ",,,", output: []string{"", "", "", ""}},
{input: ",a\\,", output: []string{"", "a,"}},
{input: "a,b\\,c\\\\d,e", output: []string{"a", "b,c\\\\d", "e"}},
}
for _, test := range tests {
strings := splitWithEscaping(test.Input, ",", "\\")
got, want := strings, test.Output
for _, tt := range tests {
strings := splitWithEscaping(tt.input, ",", "\\")
got, want := strings, tt.output
if !reflect.DeepEqual(got, want) {
t.Errorf("Got tag %v, want %v", got, want)
}
assert.Equal(t, got, want)
}
}